@courseecho/ai-core-sdk 1.0.23 → 1.0.26

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.
@@ -24,6 +24,11 @@ export declare class AiCommunicationService {
24
24
  * Send query to backend API
25
25
  */
26
26
  sendQuery(request: AiQueryRequest): Promise<AiQueryResponse>;
27
+ /**
28
+ * Exchange an API key for a short-lived JWT via POST /api/auth/token.
29
+ * Returns the JWT string on success; throws ApiError on failure.
30
+ */
31
+ fetchToken(apiKey: string): Promise<string>;
27
32
  /**
28
33
  * Check backend health
29
34
  */
@@ -80,6 +80,32 @@ export class AiCommunicationService {
80
80
  throw new ApiError(`Failed to send query: ${String(error)}`, 500);
81
81
  }
82
82
  }
83
+ /**
84
+ * Exchange an API key for a short-lived JWT via POST /api/auth/token.
85
+ * Returns the JWT string on success; throws ApiError on failure.
86
+ */
87
+ async fetchToken(apiKey) {
88
+ try {
89
+ const response = await fetch(`${this.apiEndpoint}/api/auth/token`, {
90
+ method: 'POST',
91
+ headers: { 'Content-Type': 'application/json' },
92
+ body: JSON.stringify({ apiKey }),
93
+ });
94
+ const data = await safeJson(response);
95
+ if (!response.ok) {
96
+ throw new ApiError(data?.error || `Token exchange failed: HTTP ${response.status}`, response.status, data);
97
+ }
98
+ if (!data?.token) {
99
+ throw new ApiError('No token returned from auth endpoint', 500);
100
+ }
101
+ return data.token;
102
+ }
103
+ catch (error) {
104
+ if (error instanceof ApiError)
105
+ throw error;
106
+ throw new ApiError(`Failed to fetch token: ${String(error)}`, 500);
107
+ }
108
+ }
83
109
  /**
84
110
  * Check backend health
85
111
  */
package/dist/sdk.d.ts CHANGED
@@ -21,6 +21,17 @@ export declare class AiWidgetSDK {
21
21
  * Initialize auto-suggestions based on page content
22
22
  */
23
23
  initializeAutoSuggestions(): Promise<void>;
24
+ /**
25
+ * Auto-authenticate: exchange apiKey for a JWT via POST /api/auth/token,
26
+ * set it on the communication service, then refresh suggestions.
27
+ * No-op if already authenticated or no apiKey is configured.
28
+ */
29
+ autoAuthenticate(): Promise<void>;
30
+ /**
31
+ * Re-generate suggestions for the current URL (call after SPA navigation).
32
+ * Clears stale suggestions and rescans the new page content.
33
+ */
34
+ refreshSuggestionsForCurrentUrl(): Promise<void>;
24
35
  /**
25
36
  * Validate configuration
26
37
  */
@@ -29,6 +40,8 @@ export declare class AiWidgetSDK {
29
40
  * Set JWT token for authentication
30
41
  */
31
42
  setJwtToken(token: string): void;
43
+ /** Get the currently stored JWT token (if any). */
44
+ getJwtToken(): string | undefined;
32
45
  /**
33
46
  * Send a query to the AI backend
34
47
  */
package/dist/sdk.js CHANGED
@@ -66,6 +66,37 @@ export class AiWidgetSDK {
66
66
  }, scanInterval);
67
67
  }
68
68
  }
69
+ /**
70
+ * Auto-authenticate: exchange apiKey for a JWT via POST /api/auth/token,
71
+ * set it on the communication service, then refresh suggestions.
72
+ * No-op if already authenticated or no apiKey is configured.
73
+ */
74
+ async autoAuthenticate() {
75
+ if (this.communicationService.isAuthenticated())
76
+ return;
77
+ if (!this.config.apiKey)
78
+ return;
79
+ const jwt = await this.communicationService.fetchToken(this.config.apiKey);
80
+ this.communicationService.setJwtToken(jwt);
81
+ // Refresh suggestions now that auth is established
82
+ if (this.config.suggestionConfig?.autoGenerate !== false) {
83
+ this.suggestionManager.clearSuggestions();
84
+ await this.initializeAutoSuggestions();
85
+ }
86
+ }
87
+ /**
88
+ * Re-generate suggestions for the current URL (call after SPA navigation).
89
+ * Clears stale suggestions and rescans the new page content.
90
+ */
91
+ async refreshSuggestionsForCurrentUrl() {
92
+ this.suggestionManager.clearSuggestions();
93
+ // PageContentScanner caches by URL, so a new URL will be scanned fresh.
94
+ // Also clear the old-URL cache entry to free memory.
95
+ this.pageContentScanner.clearCache();
96
+ if (this.config.suggestionConfig?.autoGenerate !== false) {
97
+ await this.initializeAutoSuggestions();
98
+ }
99
+ }
69
100
  /**
70
101
  * Validate configuration
71
102
  */
@@ -80,6 +111,10 @@ export class AiWidgetSDK {
80
111
  setJwtToken(token) {
81
112
  this.communicationService.setJwtToken(token);
82
113
  }
114
+ /** Get the currently stored JWT token (if any). */
115
+ getJwtToken() {
116
+ return this.communicationService.getJwtToken();
117
+ }
83
118
  /**
84
119
  * Send a query to the AI backend
85
120
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@courseecho/ai-core-sdk",
3
- "version": "1.0.23",
3
+ "version": "1.0.26",
4
4
  "description": "Framework-agnostic core AI chat SDK. Shared logic for all framework wrappers.",
5
5
  "license": "MIT",
6
6
  "author": "CourseEcho",