@uptrademedia/site-kit 1.1.6 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-LHMD7CAR.mjs → chunk-2STSAGNT.mjs} +28 -6
- package/dist/chunk-2STSAGNT.mjs.map +1 -0
- package/dist/{chunk-6ODMCZHH.js → chunk-C5TQLU5U.js} +166 -32
- package/dist/chunk-C5TQLU5U.js.map +1 -0
- package/dist/{chunk-IRNMIFOE.js → chunk-ICHCPLRB.js} +28 -6
- package/dist/chunk-ICHCPLRB.js.map +1 -0
- package/dist/{chunk-E6L6AY2Q.mjs → chunk-RLO3QJ65.mjs} +166 -32
- package/dist/chunk-RLO3QJ65.mjs.map +1 -0
- package/dist/cli/index.js +404 -782
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +398 -774
- package/dist/cli/index.mjs.map +1 -1
- package/dist/engage/index.d.mts +3 -1
- package/dist/engage/index.d.ts +3 -1
- package/dist/engage/index.js +4 -4
- package/dist/engage/index.mjs +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -3
- package/dist/index.mjs.map +1 -1
- package/dist/llms/index.d.mts +23 -274
- package/dist/llms/index.d.ts +23 -274
- package/dist/llms/index.js +14 -14
- package/dist/llms/index.js.map +1 -1
- package/dist/llms/index.mjs +4 -4
- package/dist/llms/index.mjs.map +1 -1
- package/dist/robots/index.d.mts +46 -0
- package/dist/robots/index.d.ts +46 -0
- package/dist/robots/index.js +34 -0
- package/dist/robots/index.js.map +1 -0
- package/dist/robots/index.mjs +32 -0
- package/dist/robots/index.mjs.map +1 -0
- package/dist/seo/index.d.mts +1 -1
- package/dist/seo/index.d.ts +1 -1
- package/dist/seo/index.js +0 -3
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +1 -1
- package/dist/sitemap/index.d.mts +6 -2
- package/dist/sitemap/index.d.ts +6 -2
- package/dist/sitemap/index.js +5 -8
- package/dist/sitemap/index.js.map +1 -1
- package/dist/sitemap/index.mjs +5 -5
- package/dist/sitemap/index.mjs.map +1 -1
- package/dist/types-Cl2SOKHd.d.mts +259 -0
- package/dist/types-Cl2SOKHd.d.ts +259 -0
- package/package.json +44 -39
- package/dist/chunk-6ODMCZHH.js.map +0 -1
- package/dist/chunk-E6L6AY2Q.mjs.map +0 -1
- package/dist/chunk-IRNMIFOE.js.map +0 -1
- package/dist/chunk-LHMD7CAR.mjs.map +0 -1
|
@@ -83,9 +83,21 @@ async function getOptimizedLLMsTxt(options) {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// src/llms/generateLLMsTxt.ts
|
|
86
|
+
function mergeLLMsData(portal, local) {
|
|
87
|
+
if (!local) return portal;
|
|
88
|
+
if (!portal) return local;
|
|
89
|
+
return {
|
|
90
|
+
business: portal.business ?? local.business,
|
|
91
|
+
contact: portal.contact ?? local.contact,
|
|
92
|
+
services: (portal.services?.length ? portal.services : local.services) ?? [],
|
|
93
|
+
faq: (portal.faq?.length ? portal.faq : local.faq) ?? [],
|
|
94
|
+
pages: (portal.pages?.length ? portal.pages : local.pages) ?? []
|
|
95
|
+
};
|
|
96
|
+
}
|
|
86
97
|
async function generateLLMsTxt(options) {
|
|
87
98
|
const {
|
|
88
99
|
projectId,
|
|
100
|
+
getLocalData,
|
|
89
101
|
includeBusinessInfo = true,
|
|
90
102
|
includeServices = true,
|
|
91
103
|
includeFAQ = true,
|
|
@@ -95,7 +107,16 @@ async function generateLLMsTxt(options) {
|
|
|
95
107
|
maxPages = 50,
|
|
96
108
|
customSections = []
|
|
97
109
|
} = options;
|
|
98
|
-
|
|
110
|
+
let data = await getLLMsData(projectId);
|
|
111
|
+
const useLocal = getLocalData && (!data || !data.services?.length);
|
|
112
|
+
if (useLocal && getLocalData) {
|
|
113
|
+
try {
|
|
114
|
+
const local = await getLocalData();
|
|
115
|
+
data = mergeLLMsData(data ?? null, local);
|
|
116
|
+
} catch (err) {
|
|
117
|
+
console.warn("[site-kit] getLocalData failed:", err);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
99
120
|
if (!data) {
|
|
100
121
|
return {
|
|
101
122
|
markdown: "# Website\n\n> Information not available.",
|
|
@@ -264,7 +285,8 @@ async function writeLLMsTxtToPublic(options = {}) {
|
|
|
264
285
|
full = false,
|
|
265
286
|
apiUrl,
|
|
266
287
|
apiKey,
|
|
267
|
-
fallbackToLocal = true
|
|
288
|
+
fallbackToLocal = true,
|
|
289
|
+
getLocalData
|
|
268
290
|
} = options;
|
|
269
291
|
const cwd = typeof process !== "undefined" ? process.cwd() : ".";
|
|
270
292
|
const outPath = join(cwd, outputDir);
|
|
@@ -278,7 +300,7 @@ async function writeLLMsTxtToPublic(options = {}) {
|
|
|
278
300
|
let optimized = !!markdown;
|
|
279
301
|
if (!markdown && fallbackToLocal) {
|
|
280
302
|
console.warn("[site-kit] Optimized llms.txt unavailable, using local generation");
|
|
281
|
-
const result = await generateLLMsTxt({});
|
|
303
|
+
const result = await generateLLMsTxt({ getLocalData });
|
|
282
304
|
markdown = result.markdown;
|
|
283
305
|
}
|
|
284
306
|
if (!markdown) {
|
|
@@ -290,7 +312,7 @@ async function writeLLMsTxtToPublic(options = {}) {
|
|
|
290
312
|
if (full) {
|
|
291
313
|
let fullMarkdown = await getOptimizedLLMsTxt({ ...apiOptions, full: true });
|
|
292
314
|
if (!fullMarkdown && fallbackToLocal) {
|
|
293
|
-
const result = await generateLLMsFullTxt({});
|
|
315
|
+
const result = await generateLLMsFullTxt({ getLocalData });
|
|
294
316
|
fullMarkdown = result.markdown;
|
|
295
317
|
}
|
|
296
318
|
if (fullMarkdown) {
|
|
@@ -302,5 +324,5 @@ async function writeLLMsTxtToPublic(options = {}) {
|
|
|
302
324
|
}
|
|
303
325
|
|
|
304
326
|
export { generateLLMsFullTxt, generateLLMsTxt, getBusinessInfo, getFAQItems, getLLMsData, getOptimizedLLMsTxt, getPageSummaries, getServices, writeLLMsTxtToPublic };
|
|
305
|
-
//# sourceMappingURL=chunk-
|
|
306
|
-
//# sourceMappingURL=chunk-
|
|
327
|
+
//# sourceMappingURL=chunk-2STSAGNT.mjs.map
|
|
328
|
+
//# sourceMappingURL=chunk-2STSAGNT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/llms/api.ts","../src/llms/generateLLMsTxt.ts","../src/llms/writeLLMsTxt.ts"],"names":[],"mappings":"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","file":"chunk-2STSAGNT.mjs","sourcesContent":["/**\n * @uptrade/site-kit/llms - API Functions\n * \n * Data fetching for LLM visibility content.\n * Pulls from Signal knowledge base and project data.\n */\n\n// @ts-expect-error - React 19 cache; @types/react may not include it yet\nimport { cache } from 'react'\nimport type { LLMsDataResponse, LLMBusinessInfo, LLMContactInfo, LLMService, LLMFAQItem, LLMPageSummary } from './types'\n\n// ============================================\n// API Config\n// ============================================\n\nfunction getApiConfig() {\n // Use site-kit globals if available, otherwise fall back to env vars\n const apiUrl = (typeof window !== 'undefined' && (window as any).__SITE_KIT_API_URL__) \n || process.env.NEXT_PUBLIC_UPTRADE_API_URL \n || 'https://api.uptrademedia.com'\n \n const apiKey = (typeof window !== 'undefined' && (window as any).__SITE_KIT_API_KEY__)\n || process.env.NEXT_PUBLIC_UPTRADE_API_KEY \n || ''\n \n return { apiUrl, apiKey }\n}\n\nasync function apiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('@uptrade/llms: No API key configured. Set NEXT_PUBLIC_UPTRADE_API_KEY.')\n return null\n }\n \n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n next: { revalidate: 3600 }, // Next.js fetch cache\n } as RequestInit)\n \n if (!response.ok) {\n console.error(`@uptrade/llms: API error: ${response.statusText}`)\n return null\n }\n \n return await response.json()\n } catch (error) {\n console.error('@uptrade/llms: Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Cached Data Fetchers\n// ============================================\n\n/**\n * Fetch all LLM visibility data for a project - cached per request\n * This is the main data source for llms.txt generation\n * \n * @param projectId - Optional project ID (API key identifies project if omitted)\n */\nexport const getLLMsData = cache(async (\n projectId?: string\n): Promise<LLMsDataResponse | null> => {\n return apiGet<LLMsDataResponse>(`/api/public/llms/data`)\n})\n\n/**\n * Fetch business info only - cached per request\n */\nexport const getBusinessInfo = cache(async (\n projectId?: string\n): Promise<LLMBusinessInfo | null> => {\n const result = await apiGet<{ business: LLMBusinessInfo }>(`/api/public/llms/business`)\n return result?.business || null\n})\n\n/**\n * Fetch services list - cached per request\n */\nexport const getServices = cache(async (\n projectId?: string\n): Promise<LLMService[]> => {\n const result = await apiGet<{ services: LLMService[] }>(`/api/public/llms/services`)\n return result?.services || []\n})\n\n/**\n * Fetch FAQ items - cached per request\n */\nexport const getFAQItems = cache(async (\n projectId?: string,\n limit?: number\n): Promise<LLMFAQItem[]> => {\n const endpoint = limit \n ? `/api/public/llms/faq?limit=${limit}`\n : '/api/public/llms/faq'\n const result = await apiGet<{ faq: LLMFAQItem[] }>(endpoint)\n return result?.faq || []\n})\n\n/**\n * Fetch page summaries for sitemap - cached per request\n */\nexport const getPageSummaries = cache(async (\n projectId?: string,\n limit?: number\n): Promise<LLMPageSummary[]> => {\n const endpoint = limit \n ? `/api/public/llms/pages?limit=${limit}`\n : '/api/public/llms/pages'\n const result = await apiGet<{ pages: LLMPageSummary[] }>(endpoint)\n return result?.pages || []\n})\n\n/**\n * Fetch AI-optimized llms.txt markdown from Portal API (build-time)\n * Used by writeLLMsTxtToPublic for static file generation\n */\nexport async function getOptimizedLLMsTxt(options?: {\n full?: boolean\n apiUrl?: string\n apiKey?: string\n}): Promise<string | null> {\n const apiUrl = options?.apiUrl\n || (typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_UPTRADE_API_URL)\n || 'https://api.uptrademedia.com'\n const apiKey = options?.apiKey\n || (typeof process !== 'undefined' && (process.env?.UPTRADE_API_KEY || process.env?.NEXT_PUBLIC_UPTRADE_API_KEY))\n || ''\n\n if (!apiKey) {\n console.error('@uptrade/llms: No API key configured for getOptimizedLLMsTxt')\n return null\n }\n\n const endpoint = options?.full ? '/api/public/llms/txt?full=true' : '/api/public/llms/txt'\n\n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'text/plain',\n 'x-api-key': apiKey,\n },\n })\n\n if (!response.ok) {\n console.error(`@uptrade/llms: Optimized txt API error: ${response.status} ${response.statusText}`)\n return null\n }\n\n return await response.text()\n } catch (error) {\n console.error('@uptrade/llms: Failed to fetch optimized llms.txt:', error)\n return null\n }\n}\n","/**\n * @uptrade/site-kit/llms - llms.txt Generator\n * \n * Generates llms.txt content following the llms.txt specification.\n * https://llmstxt.org/\n * \n * The llms.txt file provides a markdown-formatted overview of a website\n * specifically designed for LLM consumption. It helps AI systems understand\n * what a business does, what services it offers, and how to answer questions.\n */\n\nimport { getLLMsData } from './api'\nimport type { \n GenerateLLMSTxtOptions, \n LLMSTxtContent,\n LLMsDataResponse,\n LLMBusinessInfo,\n LLMContactInfo,\n LLMService,\n LLMFAQItem,\n LLMPageSummary\n} from './types'\n\n/**\n * Merge Portal data with local data. Portal fields take precedence; local fills gaps when Portal is empty.\n */\nfunction mergeLLMsData(\n portal: Partial<LLMsDataResponse> | null,\n local: LLMsDataResponse | null\n): LLMsDataResponse | null {\n if (!local) return portal as LLMsDataResponse | null\n if (!portal) return local\n return {\n business: portal.business ?? local.business,\n contact: portal.contact ?? local.contact,\n services: (portal.services?.length ? portal.services : local.services) ?? [],\n faq: (portal.faq?.length ? portal.faq : local.faq) ?? [],\n pages: (portal.pages?.length ? portal.pages : local.pages) ?? [],\n }\n}\n\n/**\n * Generate llms.txt content from Portal data\n * \n * @example\n * ```ts\n * // app/llms.txt/route.ts\n * import { generateLLMsTxt } from '@uptrade/site-kit/llms'\n * \n * export async function GET() {\n * const { markdown } = await generateLLMsTxt({\n * projectId: process.env.UPTRADE_PROJECT_ID!\n * })\n * \n * return new Response(markdown, {\n * headers: { 'Content-Type': 'text/plain; charset=utf-8' }\n * })\n * }\n * ```\n */\nexport async function generateLLMsTxt(\n options: GenerateLLMSTxtOptions\n): Promise<LLMSTxtContent> {\n const {\n projectId,\n getLocalData,\n includeBusinessInfo = true,\n includeServices = true,\n includeFAQ = true,\n includePages = true,\n includeContact = true,\n maxFAQItems = 20,\n maxPages = 50,\n customSections = [],\n } = options\n\n // Fetch from Portal first\n let data = await getLLMsData(projectId)\n\n // Use local data when Portal returns null or empty services\n const useLocal = getLocalData && (!data || !data.services?.length)\n if (useLocal && getLocalData) {\n try {\n const local = await getLocalData()\n data = mergeLLMsData(data ?? null, local)\n } catch (err) {\n console.warn('[site-kit] getLocalData failed:', err)\n }\n }\n \n if (!data) {\n // Return minimal content if no data\n return {\n markdown: '# Website\\n\\n> Information not available.',\n metadata: {\n generated_at: new Date().toISOString(),\n project_id: projectId || '',\n sections: [],\n }\n }\n }\n\n const sections: string[] = []\n const sectionNames: string[] = []\n\n // ========================================\n // Header Section (H1 + blockquote summary)\n // ========================================\n if (includeBusinessInfo && data.business) {\n const header = generateHeaderSection(data.business)\n sections.push(header)\n sectionNames.push('header')\n }\n\n // ========================================\n // About Section\n // ========================================\n if (includeBusinessInfo && data.business?.description) {\n const about = generateAboutSection(data.business)\n sections.push(about)\n sectionNames.push('about')\n }\n\n // ========================================\n // Services Section\n // ========================================\n if (includeServices && data.services?.length > 0) {\n const services = generateServicesSection(data.services)\n sections.push(services)\n sectionNames.push('services')\n }\n\n // ========================================\n // Contact Section\n // ========================================\n if (includeContact && data.contact) {\n const contact = generateContactSection(data.contact)\n sections.push(contact)\n sectionNames.push('contact')\n }\n\n // ========================================\n // FAQ Section\n // ========================================\n if (includeFAQ && data.faq?.length > 0) {\n const faq = generateFAQSection(data.faq.slice(0, maxFAQItems))\n sections.push(faq)\n sectionNames.push('faq')\n }\n\n // ========================================\n // Pages Section (sitemap-like index)\n // ========================================\n if (includePages && data.pages?.length > 0) {\n const pages = generatePagesSection(data.pages.slice(0, maxPages), data.business?.website || '')\n sections.push(pages)\n sectionNames.push('pages')\n }\n\n // ========================================\n // Custom Sections\n // ========================================\n for (const custom of customSections) {\n sections.push(`## ${custom.title}\\n\\n${custom.content}`)\n sectionNames.push(custom.title.toLowerCase().replace(/\\s+/g, '-'))\n }\n\n return {\n markdown: sections.join('\\n\\n---\\n\\n'),\n metadata: {\n generated_at: new Date().toISOString(),\n project_id: projectId || '',\n sections: sectionNames,\n }\n }\n}\n\n/**\n * Generate llms-full.txt with comprehensive knowledge dump\n * Use this for AI systems that can handle larger context\n */\nexport async function generateLLMsFullTxt(\n options: GenerateLLMSTxtOptions\n): Promise<LLMSTxtContent> {\n return generateLLMsTxt({\n ...options,\n includeBusinessInfo: true,\n includeServices: true,\n includeFAQ: true,\n includePages: true,\n includeContact: true,\n maxFAQItems: 100,\n maxPages: 200,\n })\n}\n\n// ============================================\n// Section Generators\n// ============================================\n\nfunction generateHeaderSection(business: LLMBusinessInfo): string {\n const lines: string[] = []\n \n // H1 with business name\n lines.push(`# ${business.name}`)\n lines.push('')\n \n // Blockquote summary (per llms.txt spec)\n const summary = business.tagline || business.description.split('.')[0]\n lines.push(`> ${summary}`)\n \n if (business.industry) {\n lines.push('')\n lines.push(`**Industry:** ${business.industry}`)\n }\n \n if (business.service_area) {\n lines.push(`**Service Area:** ${business.service_area}`)\n }\n \n if (business.website) {\n lines.push(`**Website:** ${business.website}`)\n }\n\n return lines.join('\\n')\n}\n\nfunction generateAboutSection(business: LLMBusinessInfo): string {\n const lines: string[] = []\n \n lines.push('## About')\n lines.push('')\n lines.push(business.description)\n \n if (business.founded) {\n lines.push('')\n lines.push(`Established: ${business.founded}`)\n }\n\n return lines.join('\\n')\n}\n\nfunction generateServicesSection(services: LLMService[]): string {\n const lines: string[] = []\n \n lines.push('## Services')\n lines.push('')\n \n for (const service of services) {\n if (service.url) {\n lines.push(`- **[${service.name}](${service.url})**: ${service.description}`)\n } else {\n lines.push(`- **${service.name}**: ${service.description}`)\n }\n }\n\n return lines.join('\\n')\n}\n\nfunction generateContactSection(contact: LLMContactInfo): string {\n const lines: string[] = []\n \n lines.push('## Contact Information')\n lines.push('')\n \n if (contact.phone) {\n lines.push(`- **Phone:** ${contact.phone}`)\n }\n if (contact.email) {\n lines.push(`- **Email:** ${contact.email}`)\n }\n if (contact.address || contact.city) {\n const addressParts = [\n contact.address,\n contact.city,\n contact.state,\n contact.postal_code,\n contact.country\n ].filter(Boolean)\n lines.push(`- **Address:** ${addressParts.join(', ')}`)\n }\n if (contact.hours) {\n lines.push(`- **Hours:** ${contact.hours}`)\n }\n\n return lines.join('\\n')\n}\n\nfunction generateFAQSection(faq: LLMFAQItem[]): string {\n const lines: string[] = []\n \n lines.push('## Frequently Asked Questions')\n lines.push('')\n \n for (const item of faq) {\n lines.push(`### ${item.question}`)\n lines.push('')\n lines.push(item.answer)\n lines.push('')\n }\n\n return lines.join('\\n').trim()\n}\n\nfunction generatePagesSection(pages: LLMPageSummary[], baseUrl: string): string {\n const lines: string[] = []\n \n lines.push('## Site Pages')\n lines.push('')\n \n for (const page of pages) {\n const url = page.path.startsWith('http') ? page.path : `${baseUrl}${page.path}`\n if (page.description) {\n lines.push(`- [${page.title}](${url}): ${page.description}`)\n } else {\n lines.push(`- [${page.title}](${url})`)\n }\n }\n\n return lines.join('\\n')\n}\n\nexport default generateLLMsTxt\n","/**\n * @uptrade/site-kit/llms - Build-Time Write\n *\n * Fetches AI-optimized llms.txt from Portal API and writes to public/llms.txt\n * at build time. Integrates with sitemap flow when optimizedLLMsTxt is enabled.\n */\n\nimport { writeFileSync, mkdirSync, existsSync } from 'fs'\nimport { join } from 'path'\nimport { getOptimizedLLMsTxt } from './api'\nimport { generateLLMsTxt, generateLLMsFullTxt } from './generateLLMsTxt'\nimport type { LLMsDataResponse } from './types'\n\nexport interface WriteLLMsTxtOptions {\n /** Output directory (default: public, relative to cwd) */\n outputDir?: string\n /** Write llms-full.txt as well */\n full?: boolean\n /** Portal API URL */\n apiUrl?: string\n /** Portal API key */\n apiKey?: string\n /** Fallback to non-optimized when API fails */\n fallbackToLocal?: boolean\n /** When Portal returns empty services/faq/pages, use this to supply local site data */\n getLocalData?: () => Promise<LLMsDataResponse | null>\n}\n\n/**\n * Fetch optimized llms.txt from Portal and write to public/llms.txt\n * Called at build time after sitemap sync (when optimizedLLMsTxt is enabled)\n */\nexport async function writeLLMsTxtToPublic(\n options: WriteLLMsTxtOptions = {}\n): Promise<{ success: boolean; path: string; optimized: boolean }> {\n const {\n outputDir = 'public',\n full = false,\n apiUrl,\n apiKey,\n fallbackToLocal = true,\n getLocalData,\n } = options\n\n const cwd = typeof process !== 'undefined' ? process.cwd() : '.'\n const outPath = join(cwd, outputDir)\n const llmsPath = join(outPath, 'llms.txt')\n const llmsFullPath = join(outPath, 'llms-full.txt')\n\n // Ensure output directory exists\n if (!existsSync(outPath)) {\n mkdirSync(outPath, { recursive: true })\n }\n\n const apiOptions = { apiUrl, apiKey }\n\n // Fetch optimized content\n let markdown = await getOptimizedLLMsTxt({ ...apiOptions, full: false })\n let optimized = !!markdown\n\n if (!markdown && fallbackToLocal) {\n console.warn('[site-kit] Optimized llms.txt unavailable, using local generation')\n const result = await generateLLMsTxt({ getLocalData })\n markdown = result.markdown\n }\n\n if (!markdown) {\n console.error('[site-kit] Failed to generate llms.txt')\n return { success: false, path: llmsPath, optimized: false }\n }\n\n writeFileSync(llmsPath, markdown, 'utf-8')\n console.log(`[site-kit] Wrote llms.txt to ${llmsPath}`)\n\n if (full) {\n let fullMarkdown = await getOptimizedLLMsTxt({ ...apiOptions, full: true })\n if (!fullMarkdown && fallbackToLocal) {\n const result = await generateLLMsFullTxt({ getLocalData })\n fullMarkdown = result.markdown\n }\n if (fullMarkdown) {\n writeFileSync(llmsFullPath, fullMarkdown, 'utf-8')\n console.log(`[site-kit] Wrote llms-full.txt to ${llmsFullPath}`)\n }\n }\n\n return { success: true, path: llmsPath, optimized }\n}\n"]}
|
|
@@ -10,9 +10,13 @@ var React2__default = /*#__PURE__*/_interopDefault(React2);
|
|
|
10
10
|
|
|
11
11
|
// src/engage/ChatWidget.tsx
|
|
12
12
|
function getApiConfig() {
|
|
13
|
-
const
|
|
13
|
+
const isDev = typeof process !== "undefined" && process.env?.NODE_ENV === "development";
|
|
14
|
+
const defaultApiUrl = isDev && process.env?.NEXT_PUBLIC_UPTRADE_API_URL ? process.env.NEXT_PUBLIC_UPTRADE_API_URL : "https://api.uptrademedia.com";
|
|
15
|
+
const defaultSignalUrl = isDev && process.env?.NEXT_PUBLIC_SIGNAL_API_URL ? process.env.NEXT_PUBLIC_SIGNAL_API_URL : "https://signal.uptrademedia.com";
|
|
16
|
+
const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || defaultApiUrl : defaultApiUrl;
|
|
14
17
|
const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ : void 0;
|
|
15
|
-
|
|
18
|
+
const signalUrl = typeof window !== "undefined" ? window.__SITE_KIT_SIGNAL_URL__ || defaultSignalUrl : defaultSignalUrl;
|
|
19
|
+
return { apiUrl, apiKey, signalUrl };
|
|
16
20
|
}
|
|
17
21
|
function generateVisitorId() {
|
|
18
22
|
const stored = typeof localStorage !== "undefined" ? localStorage.getItem("engage_visitor_id") : null;
|
|
@@ -35,7 +39,7 @@ function isLightColor(hex) {
|
|
|
35
39
|
const b = num & 255;
|
|
36
40
|
return (r * 299 + g * 587 + b * 114) / 1e3 > 160;
|
|
37
41
|
}
|
|
38
|
-
function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
42
|
+
function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, signalUrl: propSignalUrl }) {
|
|
39
43
|
const [resolvedProjectId, setResolvedProjectId] = React2.useState(propProjectId || null);
|
|
40
44
|
const projectId = propProjectId || resolvedProjectId || "";
|
|
41
45
|
const [isOpen, setIsOpen] = React2.useState(false);
|
|
@@ -56,9 +60,11 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
56
60
|
const [lastFailedSend, setLastFailedSend] = React2.useState(null);
|
|
57
61
|
const [showWelcome, setShowWelcome] = React2.useState(true);
|
|
58
62
|
const [checkingAvailability, setCheckingAvailability] = React2.useState(false);
|
|
63
|
+
const [checkingHandoff, setCheckingHandoff] = React2.useState(false);
|
|
59
64
|
React2.useRef(null);
|
|
60
65
|
const pendingInitialMessageRef = React2.useRef(null);
|
|
61
66
|
const apiKeyMissingWarnedRef = React2.useRef(false);
|
|
67
|
+
const siteContextRef = React2.useRef(null);
|
|
62
68
|
function ensureApiKey() {
|
|
63
69
|
const { apiKey } = getApiConfig();
|
|
64
70
|
if (apiKey) return apiKey;
|
|
@@ -83,6 +89,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
83
89
|
const offlineHeading = widgetConfig?.offline_heading ?? "No agents available right now";
|
|
84
90
|
const offlineSubheading = handoffOfflinePrompt ?? widgetConfig?.offline_subheading ?? widgetConfig?.form_description ?? widgetConfig?.offline_message ?? config?.offlineMessage ?? "Leave us a message and we'll get back to you!";
|
|
85
91
|
const baseUrl = propApiUrl || getApiConfig().apiUrl;
|
|
92
|
+
const signalUrl = propSignalUrl || getApiConfig().signalUrl;
|
|
86
93
|
React2.useEffect(() => {
|
|
87
94
|
if (propProjectId || resolvedProjectId) return;
|
|
88
95
|
const { apiKey } = getApiConfig();
|
|
@@ -155,6 +162,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
155
162
|
const { data } = await response.json();
|
|
156
163
|
const session = data.session ?? data;
|
|
157
164
|
const sid = session?.id ?? session?.session_id ?? data.id ?? data.session_id;
|
|
165
|
+
const signalEnabled = session?.chat_mode === "ai" || session?.chat_mode === "hybrid";
|
|
158
166
|
setSessionId(sid);
|
|
159
167
|
const messages2 = session?.messages ?? data.messages ?? [];
|
|
160
168
|
if (messages2.length > 0) {
|
|
@@ -168,13 +176,55 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
168
176
|
}))
|
|
169
177
|
);
|
|
170
178
|
}
|
|
171
|
-
return sid;
|
|
179
|
+
return { id: sid, signalEnabled };
|
|
172
180
|
}
|
|
173
181
|
} catch (error) {
|
|
174
182
|
console.error("[ChatWidget] Session init failed:", error);
|
|
175
183
|
}
|
|
176
184
|
return null;
|
|
177
185
|
}, [projectId, visitorId, baseUrl]);
|
|
186
|
+
const fetchSiteContext = React2.useCallback(async () => {
|
|
187
|
+
if (siteContextRef.current) return siteContextRef.current;
|
|
188
|
+
try {
|
|
189
|
+
const base = typeof window !== "undefined" ? window.location.origin : "";
|
|
190
|
+
const res = await fetch(`${base}/llms.txt`, { cache: "no-store" });
|
|
191
|
+
if (res.ok) {
|
|
192
|
+
const text = await res.text();
|
|
193
|
+
if (text?.trim()) siteContextRef.current = text.trim();
|
|
194
|
+
}
|
|
195
|
+
} catch {
|
|
196
|
+
}
|
|
197
|
+
return siteContextRef.current;
|
|
198
|
+
}, []);
|
|
199
|
+
const sendToSignalApi = React2.useCallback(
|
|
200
|
+
async (content, conversationId) => {
|
|
201
|
+
const url = `${signalUrl.replace(/\/$/, "")}/echo/public/chat`;
|
|
202
|
+
const siteContext = await fetchSiteContext();
|
|
203
|
+
const body = {
|
|
204
|
+
message: content,
|
|
205
|
+
projectId,
|
|
206
|
+
visitorId,
|
|
207
|
+
...conversationId ? { conversationId } : {},
|
|
208
|
+
pageUrl: typeof window !== "undefined" ? window.location.href : void 0,
|
|
209
|
+
...siteContext ? { siteContext } : {}
|
|
210
|
+
};
|
|
211
|
+
const res = await fetch(url, {
|
|
212
|
+
method: "POST",
|
|
213
|
+
headers: { "Content-Type": "application/json" },
|
|
214
|
+
body: JSON.stringify(body)
|
|
215
|
+
});
|
|
216
|
+
const json = await res.json();
|
|
217
|
+
if (!res.ok) {
|
|
218
|
+
throw new Error(json?.error?.message || json?.message || `Signal API error: ${res.status}`);
|
|
219
|
+
}
|
|
220
|
+
const data = json?.data ?? json;
|
|
221
|
+
const aiContent = data?.content ?? data?.response ?? data?.message ?? "I'm sorry, I couldn't process that.";
|
|
222
|
+
const suggestions = data?.suggestions;
|
|
223
|
+
const newConversationId = data?.conversationId ?? conversationId;
|
|
224
|
+
return { content: aiContent, suggestions, conversationId: newConversationId };
|
|
225
|
+
},
|
|
226
|
+
[signalUrl, projectId, visitorId, fetchSiteContext]
|
|
227
|
+
);
|
|
178
228
|
const handleSocketMessage = React2.useCallback((data) => {
|
|
179
229
|
switch (data.type || data.event) {
|
|
180
230
|
case "message": {
|
|
@@ -363,13 +413,50 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
363
413
|
}, [fetchWidgetConfig, checkAvailability]);
|
|
364
414
|
React2.useEffect(() => {
|
|
365
415
|
if (isOpen && !showWelcome && !checkingAvailability && !showOfflineForm && !sessionId) {
|
|
366
|
-
initSession().then(async (
|
|
367
|
-
if (!id) return;
|
|
368
|
-
|
|
369
|
-
await connectSocket(id);
|
|
416
|
+
initSession().then(async (result) => {
|
|
417
|
+
if (!result?.id) return;
|
|
418
|
+
const { id, signalEnabled } = result;
|
|
370
419
|
const pending = pendingInitialMessageRef.current;
|
|
371
420
|
if (pending) {
|
|
372
421
|
pendingInitialMessageRef.current = null;
|
|
422
|
+
}
|
|
423
|
+
if (signalEnabled && pending) {
|
|
424
|
+
setIsLoading(true);
|
|
425
|
+
setMessages((prev) => [
|
|
426
|
+
...prev,
|
|
427
|
+
{ id: `u-${Date.now()}`, role: "user", content: pending, timestamp: /* @__PURE__ */ new Date() }
|
|
428
|
+
]);
|
|
429
|
+
try {
|
|
430
|
+
const { content: aiContent, suggestions } = await sendToSignalApi(pending, id);
|
|
431
|
+
setMessages((prev) => [
|
|
432
|
+
...prev,
|
|
433
|
+
{
|
|
434
|
+
id: `ai-${Date.now()}`,
|
|
435
|
+
role: "assistant",
|
|
436
|
+
content: aiContent,
|
|
437
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
438
|
+
...suggestions?.length ? { suggestions } : {}
|
|
439
|
+
}
|
|
440
|
+
]);
|
|
441
|
+
} catch (err) {
|
|
442
|
+
console.error("[ChatWidget] Signal API error:", err);
|
|
443
|
+
setMessages((prev) => [
|
|
444
|
+
...prev,
|
|
445
|
+
{
|
|
446
|
+
id: `err-${Date.now()}`,
|
|
447
|
+
role: "assistant",
|
|
448
|
+
content: "I apologize, but I encountered an error. Would you like to speak with a team member?",
|
|
449
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
450
|
+
suggestions: ["Talk to a person", "Try again"]
|
|
451
|
+
}
|
|
452
|
+
]);
|
|
453
|
+
} finally {
|
|
454
|
+
setIsLoading(false);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
setConnectionStatus("connecting");
|
|
458
|
+
await connectSocket(id);
|
|
459
|
+
if (!signalEnabled && pending) {
|
|
373
460
|
const waitForSocket = () => new Promise((resolve) => {
|
|
374
461
|
const check = (attempts = 0) => {
|
|
375
462
|
if (socketRef.current?.connected || attempts > 20) {
|
|
@@ -390,7 +477,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
390
477
|
return () => {
|
|
391
478
|
if (pollingIntervalRef.current) clearInterval(pollingIntervalRef.current);
|
|
392
479
|
};
|
|
393
|
-
}, [isOpen, showWelcome, checkingAvailability, showOfflineForm, sessionId, initSession, connectSocket]);
|
|
480
|
+
}, [isOpen, showWelcome, checkingAvailability, showOfflineForm, sessionId, initSession, connectSocket, sendToSignalApi]);
|
|
394
481
|
const handleToggle = React2.useCallback(() => {
|
|
395
482
|
setIsOpen((prev) => !prev);
|
|
396
483
|
}, []);
|
|
@@ -480,6 +567,36 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
480
567
|
setMessages((prev) => [...prev, userMessage]);
|
|
481
568
|
setInputValue("");
|
|
482
569
|
setIsLoading(true);
|
|
570
|
+
if (widgetConfig?.signal_enabled && hasText) {
|
|
571
|
+
try {
|
|
572
|
+
const { content: aiContent, suggestions } = await sendToSignalApi(content, sessionId);
|
|
573
|
+
setMessages((prev) => [
|
|
574
|
+
...prev,
|
|
575
|
+
{
|
|
576
|
+
id: `ai-${Date.now()}`,
|
|
577
|
+
role: "assistant",
|
|
578
|
+
content: aiContent,
|
|
579
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
580
|
+
...suggestions?.length ? { suggestions } : {}
|
|
581
|
+
}
|
|
582
|
+
]);
|
|
583
|
+
} catch (err) {
|
|
584
|
+
console.error("[ChatWidget] Signal API error:", err);
|
|
585
|
+
setMessages((prev) => [
|
|
586
|
+
...prev,
|
|
587
|
+
{
|
|
588
|
+
id: `err-${Date.now()}`,
|
|
589
|
+
role: "assistant",
|
|
590
|
+
content: "I apologize, but I encountered an error. Would you like to speak with a team member?",
|
|
591
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
592
|
+
suggestions: ["Talk to a person", "Try again"]
|
|
593
|
+
}
|
|
594
|
+
]);
|
|
595
|
+
} finally {
|
|
596
|
+
setIsLoading(false);
|
|
597
|
+
}
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
483
600
|
const socket = socketRef.current;
|
|
484
601
|
if (socket?.connected) {
|
|
485
602
|
socket.emit("visitor:message", { content: userMessage.content, attachments: attachments.length ? attachments : void 0 });
|
|
@@ -497,7 +614,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
497
614
|
}
|
|
498
615
|
}, 3e3);
|
|
499
616
|
},
|
|
500
|
-
[inputValue, isLoading, pendingFiles, uploadWidgetFile]
|
|
617
|
+
[inputValue, isLoading, pendingFiles, uploadWidgetFile, widgetConfig?.signal_enabled, sendToSignalApi, sessionId]
|
|
501
618
|
);
|
|
502
619
|
const retryFailedSend = React2.useCallback(() => {
|
|
503
620
|
if (!lastFailedSend || !sessionId) return;
|
|
@@ -515,33 +632,48 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
515
632
|
if (!sessionId) return;
|
|
516
633
|
const apiKey = ensureApiKey();
|
|
517
634
|
if (!apiKey) return;
|
|
635
|
+
setCheckingHandoff(true);
|
|
518
636
|
try {
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
637
|
+
const firstAvail = await checkAvailability();
|
|
638
|
+
if (firstAvail?.agentsOnline && firstAvail.agentsOnline > 0) {
|
|
639
|
+
setCheckingHandoff(false);
|
|
640
|
+
await fetch(`${baseUrl}/engage/widget/handoff`, {
|
|
641
|
+
method: "POST",
|
|
642
|
+
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
643
|
+
body: JSON.stringify({ sessionId })
|
|
644
|
+
});
|
|
645
|
+
setMessages((prev) => [
|
|
646
|
+
...prev,
|
|
647
|
+
{ id: `handoff-${Date.now()}`, role: "system", content: "Connecting you with a team member. Please hold on!", timestamp: /* @__PURE__ */ new Date() }
|
|
648
|
+
]);
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
652
|
+
const secondAvail = await checkAvailability();
|
|
653
|
+
setCheckingHandoff(false);
|
|
654
|
+
if (secondAvail?.agentsOnline && secondAvail.agentsOnline > 0) {
|
|
655
|
+
await fetch(`${baseUrl}/engage/widget/handoff`, {
|
|
656
|
+
method: "POST",
|
|
657
|
+
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
658
|
+
body: JSON.stringify({ sessionId })
|
|
659
|
+
});
|
|
660
|
+
setMessages((prev) => [
|
|
661
|
+
...prev,
|
|
662
|
+
{ id: `handoff-${Date.now()}`, role: "system", content: "Connecting you with a team member. Please hold on!", timestamp: /* @__PURE__ */ new Date() }
|
|
663
|
+
]);
|
|
664
|
+
} else {
|
|
524
665
|
setHandoffOfflinePrompt(widgetConfig?.offline_subheading ?? "Nobody is online right now. Leave your details and we'll get back to you.");
|
|
525
666
|
setShowOfflineForm(true);
|
|
526
667
|
setMessages((prev) => [
|
|
527
668
|
...prev,
|
|
528
669
|
{ id: `handoff-offline-${Date.now()}`, role: "system", content: offlineHeading, timestamp: /* @__PURE__ */ new Date() }
|
|
529
670
|
]);
|
|
530
|
-
return;
|
|
531
671
|
}
|
|
532
|
-
await fetch(`${baseUrl}/engage/widget/handoff`, {
|
|
533
|
-
method: "POST",
|
|
534
|
-
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
535
|
-
body: JSON.stringify({ sessionId })
|
|
536
|
-
});
|
|
537
|
-
setMessages((prev) => [
|
|
538
|
-
...prev,
|
|
539
|
-
{ id: `handoff-${Date.now()}`, role: "system", content: "Connecting you with a team member. Please hold on!", timestamp: /* @__PURE__ */ new Date() }
|
|
540
|
-
]);
|
|
541
672
|
} catch (error) {
|
|
673
|
+
setCheckingHandoff(false);
|
|
542
674
|
console.error("[ChatWidget] Handoff request failed:", error);
|
|
543
675
|
}
|
|
544
|
-
}, [sessionId, baseUrl, projectId, widgetConfig, offlineHeading]);
|
|
676
|
+
}, [sessionId, baseUrl, projectId, widgetConfig, offlineHeading, checkAvailability]);
|
|
545
677
|
const [offlineError, setOfflineError] = React2.useState(null);
|
|
546
678
|
const handleOfflineSubmit = React2.useCallback(
|
|
547
679
|
async (e) => {
|
|
@@ -842,7 +974,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
842
974
|
)
|
|
843
975
|
] }),
|
|
844
976
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
845
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 600, color: "#111827", marginBottom: 6 }, children: "Checking for a team member" }),
|
|
977
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 600, color: "#111827", marginBottom: 6 }, children: checkingHandoff ? "Looking for online support" : "Checking for a team member" }),
|
|
846
978
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 14, color: "#6b7280", lineHeight: 1.5 }, children: [
|
|
847
979
|
"One moment please",
|
|
848
980
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "inline-flex", width: 20 }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { animation: "checkDots 1.5s infinite steps(4, end)" }, children: "..." }) })
|
|
@@ -1045,11 +1177,11 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
1045
1177
|
},
|
|
1046
1178
|
children: [
|
|
1047
1179
|
Header,
|
|
1048
|
-
checkingAvailability ? CheckingScreen : showOfflineForm ? OfflineFormView : showWelcome && welcomeEnabled && messages.length === 0 ? WelcomeScreen : MessagesView,
|
|
1180
|
+
checkingAvailability || checkingHandoff ? CheckingScreen : showOfflineForm ? OfflineFormView : showWelcome && welcomeEnabled && messages.length === 0 ? WelcomeScreen : MessagesView,
|
|
1049
1181
|
showPoweredBy && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "6px 0", textAlign: "center", fontSize: 11, color: "#9ca3af", backgroundColor: "#ffffff", borderTop: "1px solid #f3f4f6" }, children: [
|
|
1050
1182
|
"Powered by",
|
|
1051
1183
|
" ",
|
|
1052
|
-
/* @__PURE__ */ jsxRuntime.jsx("a", { href: "https://uptrademedia.com", target: "_blank", rel: "noopener noreferrer", style: { color: "#6b7280", textDecoration: "none", fontWeight: 500 }, children: "
|
|
1184
|
+
/* @__PURE__ */ jsxRuntime.jsx("a", { href: "https://uptrademedia.com", target: "_blank", rel: "noopener noreferrer", style: { color: "#6b7280", textDecoration: "none", fontWeight: 500 }, children: "Sonor" })
|
|
1053
1185
|
] }),
|
|
1054
1186
|
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
1055
1187
|
@keyframes chatSlideUp {
|
|
@@ -1344,7 +1476,9 @@ function DesignRenderer({
|
|
|
1344
1476
|
)) });
|
|
1345
1477
|
}
|
|
1346
1478
|
function getApiConfig2() {
|
|
1347
|
-
const
|
|
1479
|
+
const isDev = typeof process !== "undefined" && process.env?.NODE_ENV === "development";
|
|
1480
|
+
const defaultApiUrl = isDev && process.env?.NEXT_PUBLIC_UPTRADE_API_URL ? process.env.NEXT_PUBLIC_UPTRADE_API_URL : "https://api.uptrademedia.com";
|
|
1481
|
+
const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || defaultApiUrl : defaultApiUrl;
|
|
1348
1482
|
const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ : void 0;
|
|
1349
1483
|
return { apiUrl, apiKey };
|
|
1350
1484
|
}
|
|
@@ -1705,5 +1839,5 @@ function getDeviceType() {
|
|
|
1705
1839
|
exports.ChatWidget = ChatWidget;
|
|
1706
1840
|
exports.DesignRenderer = DesignRenderer;
|
|
1707
1841
|
exports.EngageWidget = EngageWidget;
|
|
1708
|
-
//# sourceMappingURL=chunk-
|
|
1709
|
-
//# sourceMappingURL=chunk-
|
|
1842
|
+
//# sourceMappingURL=chunk-C5TQLU5U.js.map
|
|
1843
|
+
//# sourceMappingURL=chunk-C5TQLU5U.js.map
|