@courseecho/ai-core-sdk 1.0.27 → 1.0.28
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/communication-service.js +37 -1
- package/dist/models.d.ts +45 -0
- package/package.json +1 -1
|
@@ -14,6 +14,33 @@ async function safeJson(res) {
|
|
|
14
14
|
return null;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
// ─── Page-text capture helper ─────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* Extracts visible rendered text from the current page, deduplicated and capped
|
|
20
|
+
* at `maxChars` characters. Covers SPA content (course cards, mentor profiles,
|
|
21
|
+
* employee tables, etc.) that server-side crawlers cannot see.
|
|
22
|
+
*
|
|
23
|
+
* Priority: <main> → [role="main"] → <article> → document.body
|
|
24
|
+
* Safe to call in SSR/Node environments — returns '' when `document` is absent.
|
|
25
|
+
*/
|
|
26
|
+
function capturePageText(maxChars = 8000) {
|
|
27
|
+
try {
|
|
28
|
+
if (typeof document === 'undefined')
|
|
29
|
+
return '';
|
|
30
|
+
const candidates = [
|
|
31
|
+
document.querySelector('main'),
|
|
32
|
+
document.querySelector('[role="main"]'),
|
|
33
|
+
document.querySelector('article'),
|
|
34
|
+
document.body,
|
|
35
|
+
];
|
|
36
|
+
const el = candidates.find((c) => c && (c.innerText?.trim().length ?? 0) > 50) ?? document.body;
|
|
37
|
+
const raw = (el?.innerText ?? '').replace(/\s{3,}/g, '\n\n').trim();
|
|
38
|
+
return raw.length > maxChars ? raw.slice(0, maxChars) : raw;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
17
44
|
export class AiCommunicationService {
|
|
18
45
|
constructor(apiEndpoint, apiKey, minRequestIntervalMs = 1500) {
|
|
19
46
|
this.lastQuotaInfo = null;
|
|
@@ -123,11 +150,20 @@ export class AiCommunicationService {
|
|
|
123
150
|
else if (this.apiKey) {
|
|
124
151
|
headers['X-API-Key'] = this.apiKey;
|
|
125
152
|
}
|
|
153
|
+
// Capture live rendered page text so the AI can answer from SPA content
|
|
154
|
+
// (mentor cards, course listings, employee tables, etc.) that server-side
|
|
155
|
+
// crawlers cannot see. We prefer targeted semantic regions for cleaner data.
|
|
156
|
+
const enrichedRequest = {
|
|
157
|
+
...request,
|
|
158
|
+
pageText: request.pageText ?? capturePageText(8000),
|
|
159
|
+
pageUrl: request.pageUrl ?? (typeof window !== 'undefined' ? window.location.href : undefined),
|
|
160
|
+
pageTitle: request.pageTitle ?? (typeof window !== 'undefined' ? document.title : undefined),
|
|
161
|
+
};
|
|
126
162
|
try {
|
|
127
163
|
const response = await fetch(`${this.apiEndpoint}/api/aiorchestrator/query`, {
|
|
128
164
|
method: 'POST',
|
|
129
165
|
headers,
|
|
130
|
-
body: JSON.stringify(
|
|
166
|
+
body: JSON.stringify(enrichedRequest),
|
|
131
167
|
});
|
|
132
168
|
if (!response.ok) {
|
|
133
169
|
const errorData = await safeJson(response);
|
package/dist/models.d.ts
CHANGED
|
@@ -159,12 +159,57 @@ export interface AiContextConfig {
|
|
|
159
159
|
*/
|
|
160
160
|
minRequestIntervalMs?: number;
|
|
161
161
|
};
|
|
162
|
+
/**
|
|
163
|
+
* Mobile responsiveness configuration.
|
|
164
|
+
* Controls how the widget behaves on mobile devices (< 768px).
|
|
165
|
+
*/
|
|
166
|
+
mobileConfig?: {
|
|
167
|
+
/**
|
|
168
|
+
* Enable collapsible mobile view.
|
|
169
|
+
* On small screens, shows a small icon that expands when clicked.
|
|
170
|
+
* Default: true
|
|
171
|
+
*/
|
|
172
|
+
enableCollapsible?: boolean;
|
|
173
|
+
/**
|
|
174
|
+
* Width breakpoint (in px) below which mobile view activates.
|
|
175
|
+
* Default: 768
|
|
176
|
+
*/
|
|
177
|
+
breakpoint?: number;
|
|
178
|
+
/**
|
|
179
|
+
* Height of the collapsed preview badge (in px).
|
|
180
|
+
* Default: 60
|
|
181
|
+
*/
|
|
182
|
+
collapsedHeight?: number;
|
|
183
|
+
/**
|
|
184
|
+
* Width of the collapsed preview badge (in px).
|
|
185
|
+
* Default: 60
|
|
186
|
+
*/
|
|
187
|
+
collapsedWidth?: number;
|
|
188
|
+
/**
|
|
189
|
+
* Animation duration for expand/collapse (in ms).
|
|
190
|
+
* Default: 300
|
|
191
|
+
*/
|
|
192
|
+
animationDuration?: number;
|
|
193
|
+
/**
|
|
194
|
+
* Show a pulsing indicator on the collapsed badge to attract attention.
|
|
195
|
+
* Default: true
|
|
196
|
+
*/
|
|
197
|
+
showPulsingIndicator?: boolean;
|
|
198
|
+
};
|
|
162
199
|
}
|
|
163
200
|
export interface AiQueryRequest {
|
|
164
201
|
userQuery: string;
|
|
165
202
|
pageType: string;
|
|
166
203
|
entityId?: string;
|
|
167
204
|
contextData?: Record<string, any>;
|
|
205
|
+
pageUrl?: string;
|
|
206
|
+
pageTitle?: string;
|
|
207
|
+
/**
|
|
208
|
+
* Rendered page text captured from the user's browser (document.body.innerText).
|
|
209
|
+
* Provides live page content for SPAs where content is injected via API calls
|
|
210
|
+
* and is not available in the server-side crawl.
|
|
211
|
+
*/
|
|
212
|
+
pageText?: string;
|
|
168
213
|
[key: string]: any;
|
|
169
214
|
}
|
|
170
215
|
export interface AiQueryResponse {
|