@tinkrapp/widget 1.1.2 → 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/{client-CExUGn7b.d.cts → client-BFcAYuri.d.cts} +19 -1
- package/dist/{client-CExUGn7b.d.ts → client-BFcAYuri.d.ts} +19 -1
- package/dist/course-ai-widget.global.js +88 -88
- package/dist/course-ai-widget.global.js.map +1 -1
- package/dist/index.cjs +8 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +141 -36
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +141 -36
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -60,10 +60,13 @@ var WidgetAPI = class {
|
|
|
60
60
|
return response;
|
|
61
61
|
}
|
|
62
62
|
async sendMessage(sessionId, content) {
|
|
63
|
-
const response = await this.request(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
const response = await this.request(
|
|
64
|
+
`/sessions/${sessionId}/messages`,
|
|
65
|
+
{
|
|
66
|
+
method: "POST",
|
|
67
|
+
body: JSON.stringify({ content })
|
|
68
|
+
}
|
|
69
|
+
);
|
|
67
70
|
return response;
|
|
68
71
|
}
|
|
69
72
|
async getHistory(sessionId) {
|
|
@@ -91,7 +94,7 @@ var WidgetAPI = class {
|
|
|
91
94
|
...options,
|
|
92
95
|
headers: {
|
|
93
96
|
"Content-Type": "application/json",
|
|
94
|
-
|
|
97
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
95
98
|
...options.headers
|
|
96
99
|
}
|
|
97
100
|
});
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/events.ts","../src/core/api.ts","../src/core/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["type EventHandler<T = unknown> = (payload: T) => void;\n\nexport class TypedEventEmitter<TEvents extends Record<string, unknown>> {\n private listeners = new Map<keyof TEvents, Set<EventHandler>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): void {\n this.listeners.get(event)?.delete(handler as EventHandler);\n }\n\n emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n console.error(`Error in ${String(event)} handler:`, error);\n }\n });\n }\n\n clear(): void {\n this.listeners.clear();\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n\n","import type { WidgetConfig, Message, ChatSession, Artifact } from './types';\n\nexport class WidgetAPI {\n private config: Required<WidgetConfig>;\n\n constructor(config: WidgetConfig) {\n this.config = {\n baseUrl: process.env.WIDGET_API_URL || 'http://localhost:3000',\n userId: '',\n debug: false,\n assistantId: config.apiKey, // Default to apiKey for backwards compatibility\n ...config,\n };\n }\n\n async createSession(): Promise<ChatSession> {\n const response = await this.request<ChatSession>('/sessions', {\n method: 'POST',\n body: JSON.stringify({\n // apiKey IS the assistantId\n assistantId: this.config.apiKey,\n userId: this.config.userId,\n }),\n });\n return response;\n }\n\n async sendMessage(sessionId: string, content: string): Promise<Message> {\n const response = await this.request<Message>(`/sessions/${sessionId}/messages`, {\n method: 'POST',\n body: JSON.stringify({ content }),\n });\n return response;\n }\n\n async getHistory(sessionId: string): Promise<Message[]> {\n return this.request<Message[]>(`/sessions/${sessionId}/messages`);\n }\n\n async getSessions(): Promise<ChatSession[]> {\n return this.request<ChatSession[]>('/sessions');\n }\n\n async getArtifacts(): Promise<Artifact[]> {\n return this.request<Artifact[]>('/artifacts');\n }\n\n async getArtifact(id: string): Promise<Artifact> {\n return this.request<Artifact>(`/artifacts/${id}`);\n }\n\n async createArtifact(artifact: Omit<Artifact, 'id' | 'createdAt' | 'updatedAt'>): Promise<Artifact> {\n return this.request<Artifact>('/artifacts', {\n method: 'POST',\n body: JSON.stringify(artifact),\n });\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n \n this.log('Request:', url, options);\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.message || `HTTP ${response.status}`);\n }\n\n return response.json();\n }\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[CourseAI]', ...args);\n }\n }\n}\n\n","import { TypedEventEmitter } from './events';\nimport { WidgetAPI } from './api';\nimport type {\n WidgetConfig,\n WidgetState,\n WidgetEvents,\n Message,\n ChatSession,\n} from './types';\n\nexport class WidgetClient {\n private config: WidgetConfig;\n private state: WidgetState = { status: 'idle' };\n private events = new TypedEventEmitter<WidgetEvents>();\n private api: WidgetAPI;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.api = new WidgetAPI(config);\n }\n\n /**\n * Initialize the widget and create a chat session\n */\n async initialize(): Promise<void> {\n if (this.state.status !== 'idle') {\n throw new Error('Widget already initialized');\n }\n\n this.setState({ status: 'initializing' });\n\n try {\n const session = await this.api.createSession();\n this.setState({ status: 'ready', session });\n this.events.emit('session:created', { session });\n } catch (error) {\n const widgetError = {\n code: 'INIT_FAILED',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n };\n this.setState({ status: 'error', error: widgetError });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Send a message to the AI assistant\n */\n async sendMessage(content: string): Promise<Message> {\n if (this.state.status !== 'ready') {\n throw new Error('Widget not ready. Call initialize() first.');\n }\n\n const userMessage: Message = {\n id: crypto.randomUUID(),\n role: 'user',\n content,\n timestamp: Date.now(),\n };\n\n // Optimistically add user message\n const session = {\n ...this.state.session,\n messages: [...this.state.session.messages, userMessage],\n };\n this.setState({ status: 'ready', session });\n this.events.emit('message:sent', { message: userMessage });\n\n // Set loading state\n this.setState({ status: 'loading' });\n\n try {\n const assistantMessage = await this.api.sendMessage(\n session.id,\n content\n );\n\n const updatedSession = {\n ...session,\n messages: [...session.messages, assistantMessage],\n };\n\n this.setState({ status: 'ready', session: updatedSession });\n this.events.emit('message:received', { message: assistantMessage });\n\n return assistantMessage;\n } catch (error) {\n const widgetError = {\n code: 'SEND_MESSAGE_FAILED',\n message: error instanceof Error ? error.message : 'Failed to send message',\n details: error,\n };\n \n // Revert to previous state with user message still included\n this.setState({ status: 'ready', session });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return this.state;\n }\n\n /**\n * Get the API instance for direct calls\n */\n getAPI(): WidgetAPI {\n return this.api;\n }\n\n /**\n * Get the widget configuration\n */\n getConfig(): WidgetConfig {\n return this.config;\n }\n\n /**\n * Subscribe to events\n */\n on<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): () => void {\n return this.events.on(event, handler);\n }\n\n /**\n * Unsubscribe from events\n */\n off<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): void {\n this.events.off(event, handler);\n }\n\n /**\n * Clean up resources\n */\n destroy(): void {\n this.events.clear();\n this.setState({ status: 'idle' });\n }\n\n private setState(newState: WidgetState): void {\n const previous = this.state;\n this.state = newState;\n this.events.emit('state:change', { previous, current: newState });\n }\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/events.ts","../src/core/api.ts","../src/core/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["type EventHandler<T = unknown> = (payload: T) => void;\n\nexport class TypedEventEmitter<TEvents extends Record<string, unknown>> {\n private listeners = new Map<keyof TEvents, Set<EventHandler>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): void {\n this.listeners.get(event)?.delete(handler as EventHandler);\n }\n\n emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n console.error(`Error in ${String(event)} handler:`, error);\n }\n });\n }\n\n clear(): void {\n this.listeners.clear();\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n\n","import type { Artifact, ChatSession, Message, WidgetConfig } from './types'\n\n/**\n * Resolved config with required core fields but optional context fields\n */\ntype ResolvedConfig = Required<\n Pick<WidgetConfig, 'apiKey' | 'assistantId' | 'baseUrl' | 'userId' | 'debug'>\n> &\n Pick<WidgetConfig, 'userContext' | 'lessonContext'>\n\nexport class WidgetAPI {\n private config: ResolvedConfig\n\n constructor(config: WidgetConfig) {\n this.config = {\n baseUrl: process.env.APP_URL || 'http://localhost:3000',\n userId: '',\n debug: false,\n assistantId: config.apiKey, // Default to apiKey for backwards compatibility\n ...config,\n }\n }\n\n async createSession(): Promise<ChatSession> {\n const response = await this.request<ChatSession>('/sessions', {\n method: 'POST',\n body: JSON.stringify({\n // apiKey IS the assistantId\n assistantId: this.config.apiKey,\n userId: this.config.userId,\n }),\n })\n return response\n }\n\n async sendMessage(sessionId: string, content: string): Promise<Message> {\n const response = await this.request<Message>(\n `/sessions/${sessionId}/messages`,\n {\n method: 'POST',\n body: JSON.stringify({ content }),\n },\n )\n return response\n }\n\n async getHistory(sessionId: string): Promise<Message[]> {\n return this.request<Message[]>(`/sessions/${sessionId}/messages`)\n }\n\n async getSessions(): Promise<ChatSession[]> {\n return this.request<ChatSession[]>('/sessions')\n }\n\n async getArtifacts(): Promise<Artifact[]> {\n return this.request<Artifact[]>('/artifacts')\n }\n\n async getArtifact(id: string): Promise<Artifact> {\n return this.request<Artifact>(`/artifacts/${id}`)\n }\n\n async createArtifact(\n artifact: Omit<Artifact, 'id' | 'createdAt' | 'updatedAt'>,\n ): Promise<Artifact> {\n return this.request<Artifact>('/artifacts', {\n method: 'POST',\n body: JSON.stringify(artifact),\n })\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`\n\n this.log('Request:', url, options)\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.config.apiKey}`,\n ...options.headers,\n },\n })\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}))\n throw new Error(error.message || `HTTP ${response.status}`)\n }\n\n return response.json()\n }\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[CourseAI]', ...args)\n }\n }\n}\n","import { TypedEventEmitter } from './events';\nimport { WidgetAPI } from './api';\nimport type {\n WidgetConfig,\n WidgetState,\n WidgetEvents,\n Message,\n ChatSession,\n} from './types';\n\nexport class WidgetClient {\n private config: WidgetConfig;\n private state: WidgetState = { status: 'idle' };\n private events = new TypedEventEmitter<WidgetEvents>();\n private api: WidgetAPI;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.api = new WidgetAPI(config);\n }\n\n /**\n * Initialize the widget and create a chat session\n */\n async initialize(): Promise<void> {\n if (this.state.status !== 'idle') {\n throw new Error('Widget already initialized');\n }\n\n this.setState({ status: 'initializing' });\n\n try {\n const session = await this.api.createSession();\n this.setState({ status: 'ready', session });\n this.events.emit('session:created', { session });\n } catch (error) {\n const widgetError = {\n code: 'INIT_FAILED',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n };\n this.setState({ status: 'error', error: widgetError });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Send a message to the AI assistant\n */\n async sendMessage(content: string): Promise<Message> {\n if (this.state.status !== 'ready') {\n throw new Error('Widget not ready. Call initialize() first.');\n }\n\n const userMessage: Message = {\n id: crypto.randomUUID(),\n role: 'user',\n content,\n timestamp: Date.now(),\n };\n\n // Optimistically add user message\n const session = {\n ...this.state.session,\n messages: [...this.state.session.messages, userMessage],\n };\n this.setState({ status: 'ready', session });\n this.events.emit('message:sent', { message: userMessage });\n\n // Set loading state\n this.setState({ status: 'loading' });\n\n try {\n const assistantMessage = await this.api.sendMessage(\n session.id,\n content\n );\n\n const updatedSession = {\n ...session,\n messages: [...session.messages, assistantMessage],\n };\n\n this.setState({ status: 'ready', session: updatedSession });\n this.events.emit('message:received', { message: assistantMessage });\n\n return assistantMessage;\n } catch (error) {\n const widgetError = {\n code: 'SEND_MESSAGE_FAILED',\n message: error instanceof Error ? error.message : 'Failed to send message',\n details: error,\n };\n \n // Revert to previous state with user message still included\n this.setState({ status: 'ready', session });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return this.state;\n }\n\n /**\n * Get the API instance for direct calls\n */\n getAPI(): WidgetAPI {\n return this.api;\n }\n\n /**\n * Get the widget configuration\n */\n getConfig(): WidgetConfig {\n return this.config;\n }\n\n /**\n * Subscribe to events\n */\n on<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): () => void {\n return this.events.on(event, handler);\n }\n\n /**\n * Unsubscribe from events\n */\n off<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): void {\n this.events.off(event, handler);\n }\n\n /**\n * Clean up resources\n */\n destroy(): void {\n this.events.clear();\n this.setState({ status: 'idle' });\n }\n\n private setState(newState: WidgetState): void {\n const previous = this.state;\n this.state = newState;\n this.events.emit('state:change', { previous, current: newState });\n }\n}\n\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Artifact, f as ArtifactCategory, C as ChatSession, M as Message, a as WidgetAPI, W as WidgetClient, b as WidgetConfig, e as WidgetError, d as WidgetEvents, c as WidgetState } from './client-
|
|
1
|
+
export { A as Artifact, f as ArtifactCategory, C as ChatSession, M as Message, a as WidgetAPI, W as WidgetClient, b as WidgetConfig, e as WidgetError, d as WidgetEvents, c as WidgetState } from './client-BFcAYuri.cjs';
|
|
2
2
|
|
|
3
3
|
type EventHandler<T = unknown> = (payload: T) => void;
|
|
4
4
|
declare class TypedEventEmitter<TEvents extends Record<string, unknown>> {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Artifact, f as ArtifactCategory, C as ChatSession, M as Message, a as WidgetAPI, W as WidgetClient, b as WidgetConfig, e as WidgetError, d as WidgetEvents, c as WidgetState } from './client-
|
|
1
|
+
export { A as Artifact, f as ArtifactCategory, C as ChatSession, M as Message, a as WidgetAPI, W as WidgetClient, b as WidgetConfig, e as WidgetError, d as WidgetEvents, c as WidgetState } from './client-BFcAYuri.js';
|
|
2
2
|
|
|
3
3
|
type EventHandler<T = unknown> = (payload: T) => void;
|
|
4
4
|
declare class TypedEventEmitter<TEvents extends Record<string, unknown>> {
|
package/dist/index.js
CHANGED
|
@@ -58,10 +58,13 @@ var WidgetAPI = class {
|
|
|
58
58
|
return response;
|
|
59
59
|
}
|
|
60
60
|
async sendMessage(sessionId, content) {
|
|
61
|
-
const response = await this.request(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
const response = await this.request(
|
|
62
|
+
`/sessions/${sessionId}/messages`,
|
|
63
|
+
{
|
|
64
|
+
method: "POST",
|
|
65
|
+
body: JSON.stringify({ content })
|
|
66
|
+
}
|
|
67
|
+
);
|
|
65
68
|
return response;
|
|
66
69
|
}
|
|
67
70
|
async getHistory(sessionId) {
|
|
@@ -89,7 +92,7 @@ var WidgetAPI = class {
|
|
|
89
92
|
...options,
|
|
90
93
|
headers: {
|
|
91
94
|
"Content-Type": "application/json",
|
|
92
|
-
|
|
95
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
93
96
|
...options.headers
|
|
94
97
|
}
|
|
95
98
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/events.ts","../src/core/api.ts","../src/core/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["type EventHandler<T = unknown> = (payload: T) => void;\n\nexport class TypedEventEmitter<TEvents extends Record<string, unknown>> {\n private listeners = new Map<keyof TEvents, Set<EventHandler>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): void {\n this.listeners.get(event)?.delete(handler as EventHandler);\n }\n\n emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n console.error(`Error in ${String(event)} handler:`, error);\n }\n });\n }\n\n clear(): void {\n this.listeners.clear();\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n\n","import type { WidgetConfig, Message, ChatSession, Artifact } from './types';\n\nexport class WidgetAPI {\n private config: Required<WidgetConfig>;\n\n constructor(config: WidgetConfig) {\n this.config = {\n baseUrl: process.env.WIDGET_API_URL || 'http://localhost:3000',\n userId: '',\n debug: false,\n assistantId: config.apiKey, // Default to apiKey for backwards compatibility\n ...config,\n };\n }\n\n async createSession(): Promise<ChatSession> {\n const response = await this.request<ChatSession>('/sessions', {\n method: 'POST',\n body: JSON.stringify({\n // apiKey IS the assistantId\n assistantId: this.config.apiKey,\n userId: this.config.userId,\n }),\n });\n return response;\n }\n\n async sendMessage(sessionId: string, content: string): Promise<Message> {\n const response = await this.request<Message>(`/sessions/${sessionId}/messages`, {\n method: 'POST',\n body: JSON.stringify({ content }),\n });\n return response;\n }\n\n async getHistory(sessionId: string): Promise<Message[]> {\n return this.request<Message[]>(`/sessions/${sessionId}/messages`);\n }\n\n async getSessions(): Promise<ChatSession[]> {\n return this.request<ChatSession[]>('/sessions');\n }\n\n async getArtifacts(): Promise<Artifact[]> {\n return this.request<Artifact[]>('/artifacts');\n }\n\n async getArtifact(id: string): Promise<Artifact> {\n return this.request<Artifact>(`/artifacts/${id}`);\n }\n\n async createArtifact(artifact: Omit<Artifact, 'id' | 'createdAt' | 'updatedAt'>): Promise<Artifact> {\n return this.request<Artifact>('/artifacts', {\n method: 'POST',\n body: JSON.stringify(artifact),\n });\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n \n this.log('Request:', url, options);\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.message || `HTTP ${response.status}`);\n }\n\n return response.json();\n }\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[CourseAI]', ...args);\n }\n }\n}\n\n","import { TypedEventEmitter } from './events';\nimport { WidgetAPI } from './api';\nimport type {\n WidgetConfig,\n WidgetState,\n WidgetEvents,\n Message,\n ChatSession,\n} from './types';\n\nexport class WidgetClient {\n private config: WidgetConfig;\n private state: WidgetState = { status: 'idle' };\n private events = new TypedEventEmitter<WidgetEvents>();\n private api: WidgetAPI;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.api = new WidgetAPI(config);\n }\n\n /**\n * Initialize the widget and create a chat session\n */\n async initialize(): Promise<void> {\n if (this.state.status !== 'idle') {\n throw new Error('Widget already initialized');\n }\n\n this.setState({ status: 'initializing' });\n\n try {\n const session = await this.api.createSession();\n this.setState({ status: 'ready', session });\n this.events.emit('session:created', { session });\n } catch (error) {\n const widgetError = {\n code: 'INIT_FAILED',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n };\n this.setState({ status: 'error', error: widgetError });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Send a message to the AI assistant\n */\n async sendMessage(content: string): Promise<Message> {\n if (this.state.status !== 'ready') {\n throw new Error('Widget not ready. Call initialize() first.');\n }\n\n const userMessage: Message = {\n id: crypto.randomUUID(),\n role: 'user',\n content,\n timestamp: Date.now(),\n };\n\n // Optimistically add user message\n const session = {\n ...this.state.session,\n messages: [...this.state.session.messages, userMessage],\n };\n this.setState({ status: 'ready', session });\n this.events.emit('message:sent', { message: userMessage });\n\n // Set loading state\n this.setState({ status: 'loading' });\n\n try {\n const assistantMessage = await this.api.sendMessage(\n session.id,\n content\n );\n\n const updatedSession = {\n ...session,\n messages: [...session.messages, assistantMessage],\n };\n\n this.setState({ status: 'ready', session: updatedSession });\n this.events.emit('message:received', { message: assistantMessage });\n\n return assistantMessage;\n } catch (error) {\n const widgetError = {\n code: 'SEND_MESSAGE_FAILED',\n message: error instanceof Error ? error.message : 'Failed to send message',\n details: error,\n };\n \n // Revert to previous state with user message still included\n this.setState({ status: 'ready', session });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return this.state;\n }\n\n /**\n * Get the API instance for direct calls\n */\n getAPI(): WidgetAPI {\n return this.api;\n }\n\n /**\n * Get the widget configuration\n */\n getConfig(): WidgetConfig {\n return this.config;\n }\n\n /**\n * Subscribe to events\n */\n on<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): () => void {\n return this.events.on(event, handler);\n }\n\n /**\n * Unsubscribe from events\n */\n off<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): void {\n this.events.off(event, handler);\n }\n\n /**\n * Clean up resources\n */\n destroy(): void {\n this.events.clear();\n this.setState({ status: 'idle' });\n }\n\n private setState(newState: WidgetState): void {\n const previous = this.state;\n this.state = newState;\n this.events.emit('state:change', { previous, current: newState });\n }\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/events.ts","../src/core/api.ts","../src/core/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["type EventHandler<T = unknown> = (payload: T) => void;\n\nexport class TypedEventEmitter<TEvents extends Record<string, unknown>> {\n private listeners = new Map<keyof TEvents, Set<EventHandler>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): void {\n this.listeners.get(event)?.delete(handler as EventHandler);\n }\n\n emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n console.error(`Error in ${String(event)} handler:`, error);\n }\n });\n }\n\n clear(): void {\n this.listeners.clear();\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n\n","import type { Artifact, ChatSession, Message, WidgetConfig } from './types'\n\n/**\n * Resolved config with required core fields but optional context fields\n */\ntype ResolvedConfig = Required<\n Pick<WidgetConfig, 'apiKey' | 'assistantId' | 'baseUrl' | 'userId' | 'debug'>\n> &\n Pick<WidgetConfig, 'userContext' | 'lessonContext'>\n\nexport class WidgetAPI {\n private config: ResolvedConfig\n\n constructor(config: WidgetConfig) {\n this.config = {\n baseUrl: process.env.APP_URL || 'http://localhost:3000',\n userId: '',\n debug: false,\n assistantId: config.apiKey, // Default to apiKey for backwards compatibility\n ...config,\n }\n }\n\n async createSession(): Promise<ChatSession> {\n const response = await this.request<ChatSession>('/sessions', {\n method: 'POST',\n body: JSON.stringify({\n // apiKey IS the assistantId\n assistantId: this.config.apiKey,\n userId: this.config.userId,\n }),\n })\n return response\n }\n\n async sendMessage(sessionId: string, content: string): Promise<Message> {\n const response = await this.request<Message>(\n `/sessions/${sessionId}/messages`,\n {\n method: 'POST',\n body: JSON.stringify({ content }),\n },\n )\n return response\n }\n\n async getHistory(sessionId: string): Promise<Message[]> {\n return this.request<Message[]>(`/sessions/${sessionId}/messages`)\n }\n\n async getSessions(): Promise<ChatSession[]> {\n return this.request<ChatSession[]>('/sessions')\n }\n\n async getArtifacts(): Promise<Artifact[]> {\n return this.request<Artifact[]>('/artifacts')\n }\n\n async getArtifact(id: string): Promise<Artifact> {\n return this.request<Artifact>(`/artifacts/${id}`)\n }\n\n async createArtifact(\n artifact: Omit<Artifact, 'id' | 'createdAt' | 'updatedAt'>,\n ): Promise<Artifact> {\n return this.request<Artifact>('/artifacts', {\n method: 'POST',\n body: JSON.stringify(artifact),\n })\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`\n\n this.log('Request:', url, options)\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.config.apiKey}`,\n ...options.headers,\n },\n })\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}))\n throw new Error(error.message || `HTTP ${response.status}`)\n }\n\n return response.json()\n }\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[CourseAI]', ...args)\n }\n }\n}\n","import { TypedEventEmitter } from './events';\nimport { WidgetAPI } from './api';\nimport type {\n WidgetConfig,\n WidgetState,\n WidgetEvents,\n Message,\n ChatSession,\n} from './types';\n\nexport class WidgetClient {\n private config: WidgetConfig;\n private state: WidgetState = { status: 'idle' };\n private events = new TypedEventEmitter<WidgetEvents>();\n private api: WidgetAPI;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.api = new WidgetAPI(config);\n }\n\n /**\n * Initialize the widget and create a chat session\n */\n async initialize(): Promise<void> {\n if (this.state.status !== 'idle') {\n throw new Error('Widget already initialized');\n }\n\n this.setState({ status: 'initializing' });\n\n try {\n const session = await this.api.createSession();\n this.setState({ status: 'ready', session });\n this.events.emit('session:created', { session });\n } catch (error) {\n const widgetError = {\n code: 'INIT_FAILED',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n };\n this.setState({ status: 'error', error: widgetError });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Send a message to the AI assistant\n */\n async sendMessage(content: string): Promise<Message> {\n if (this.state.status !== 'ready') {\n throw new Error('Widget not ready. Call initialize() first.');\n }\n\n const userMessage: Message = {\n id: crypto.randomUUID(),\n role: 'user',\n content,\n timestamp: Date.now(),\n };\n\n // Optimistically add user message\n const session = {\n ...this.state.session,\n messages: [...this.state.session.messages, userMessage],\n };\n this.setState({ status: 'ready', session });\n this.events.emit('message:sent', { message: userMessage });\n\n // Set loading state\n this.setState({ status: 'loading' });\n\n try {\n const assistantMessage = await this.api.sendMessage(\n session.id,\n content\n );\n\n const updatedSession = {\n ...session,\n messages: [...session.messages, assistantMessage],\n };\n\n this.setState({ status: 'ready', session: updatedSession });\n this.events.emit('message:received', { message: assistantMessage });\n\n return assistantMessage;\n } catch (error) {\n const widgetError = {\n code: 'SEND_MESSAGE_FAILED',\n message: error instanceof Error ? error.message : 'Failed to send message',\n details: error,\n };\n \n // Revert to previous state with user message still included\n this.setState({ status: 'ready', session });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return this.state;\n }\n\n /**\n * Get the API instance for direct calls\n */\n getAPI(): WidgetAPI {\n return this.api;\n }\n\n /**\n * Get the widget configuration\n */\n getConfig(): WidgetConfig {\n return this.config;\n }\n\n /**\n * Subscribe to events\n */\n on<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): () => void {\n return this.events.on(event, handler);\n }\n\n /**\n * Unsubscribe from events\n */\n off<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): void {\n this.events.off(event, handler);\n }\n\n /**\n * Clean up resources\n */\n destroy(): void {\n this.events.clear();\n this.setState({ status: 'idle' });\n }\n\n private setState(newState: WidgetState): void {\n const previous = this.state;\n this.state = newState;\n this.events.emit('state:change', { previous, current: newState });\n }\n}\n\n"]}
|
package/dist/react.cjs
CHANGED
|
@@ -114,10 +114,13 @@ var WidgetAPI = class {
|
|
|
114
114
|
return response;
|
|
115
115
|
}
|
|
116
116
|
async sendMessage(sessionId, content) {
|
|
117
|
-
const response = await this.request(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
const response = await this.request(
|
|
118
|
+
`/sessions/${sessionId}/messages`,
|
|
119
|
+
{
|
|
120
|
+
method: "POST",
|
|
121
|
+
body: JSON.stringify({ content })
|
|
122
|
+
}
|
|
123
|
+
);
|
|
121
124
|
return response;
|
|
122
125
|
}
|
|
123
126
|
async getHistory(sessionId) {
|
|
@@ -145,7 +148,7 @@ var WidgetAPI = class {
|
|
|
145
148
|
...options,
|
|
146
149
|
headers: {
|
|
147
150
|
"Content-Type": "application/json",
|
|
148
|
-
|
|
151
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
149
152
|
...options.headers
|
|
150
153
|
}
|
|
151
154
|
});
|
|
@@ -279,6 +282,28 @@ var WidgetClient = class {
|
|
|
279
282
|
this.events.emit("state:change", { previous, current: newState });
|
|
280
283
|
}
|
|
281
284
|
};
|
|
285
|
+
var LessonContext = React2.createContext({
|
|
286
|
+
lessonContext: null,
|
|
287
|
+
hasLessonContext: false
|
|
288
|
+
});
|
|
289
|
+
function LessonContextProvider({
|
|
290
|
+
children,
|
|
291
|
+
lessonContext
|
|
292
|
+
}) {
|
|
293
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
294
|
+
LessonContext.Provider,
|
|
295
|
+
{
|
|
296
|
+
value: {
|
|
297
|
+
lessonContext: lessonContext ?? null,
|
|
298
|
+
hasLessonContext: !!lessonContext
|
|
299
|
+
},
|
|
300
|
+
children
|
|
301
|
+
}
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
function useLessonContext() {
|
|
305
|
+
return React2.useContext(LessonContext);
|
|
306
|
+
}
|
|
282
307
|
var MessageContext = React2.createContext(null);
|
|
283
308
|
function MessageContextProvider({ children }) {
|
|
284
309
|
const [selectedContext, setSelectedContext] = React2.useState([]);
|
|
@@ -1674,15 +1699,25 @@ var WidgetContext = React2.createContext(null);
|
|
|
1674
1699
|
function generateUserId() {
|
|
1675
1700
|
return crypto.randomUUID();
|
|
1676
1701
|
}
|
|
1677
|
-
function createApiHeaders(userId, assistantId) {
|
|
1678
|
-
|
|
1702
|
+
function createApiHeaders(userId, assistantId, userContext) {
|
|
1703
|
+
const headers = {
|
|
1679
1704
|
"Content-Type": "application/json",
|
|
1680
1705
|
"X-User-Id": userId,
|
|
1681
1706
|
"X-Assistant-Id": assistantId
|
|
1682
1707
|
};
|
|
1708
|
+
if (userContext?.firstName) {
|
|
1709
|
+
headers["X-User-First-Name"] = userContext.firstName;
|
|
1710
|
+
}
|
|
1711
|
+
if (userContext?.lastName) {
|
|
1712
|
+
headers["X-User-Last-Name"] = userContext.lastName;
|
|
1713
|
+
}
|
|
1714
|
+
if (userContext?.email) {
|
|
1715
|
+
headers["X-User-Email"] = userContext.email;
|
|
1716
|
+
}
|
|
1717
|
+
return headers;
|
|
1683
1718
|
}
|
|
1684
|
-
function createThreadListAdapter(baseUrl, userId, assistantId) {
|
|
1685
|
-
const headers = createApiHeaders(userId, assistantId);
|
|
1719
|
+
function createThreadListAdapter(baseUrl, userId, assistantId, userContext) {
|
|
1720
|
+
const headers = createApiHeaders(userId, assistantId, userContext);
|
|
1686
1721
|
return {
|
|
1687
1722
|
// List all threads for this user
|
|
1688
1723
|
async list() {
|
|
@@ -1809,13 +1844,13 @@ function createThreadListAdapter(baseUrl, userId, assistantId) {
|
|
|
1809
1844
|
}
|
|
1810
1845
|
};
|
|
1811
1846
|
}
|
|
1812
|
-
async function saveMessages(baseUrl, userId, assistantId, threadId, messages) {
|
|
1847
|
+
async function saveMessages(baseUrl, userId, assistantId, threadId, messages, userContext) {
|
|
1813
1848
|
try {
|
|
1814
1849
|
const response = await fetch(
|
|
1815
1850
|
`${baseUrl}/api/widget/threads/${threadId}/messages/sync`,
|
|
1816
1851
|
{
|
|
1817
1852
|
method: "POST",
|
|
1818
|
-
headers: createApiHeaders(userId, assistantId),
|
|
1853
|
+
headers: createApiHeaders(userId, assistantId, userContext),
|
|
1819
1854
|
body: JSON.stringify({ messages })
|
|
1820
1855
|
}
|
|
1821
1856
|
);
|
|
@@ -1826,8 +1861,8 @@ async function saveMessages(baseUrl, userId, assistantId, threadId, messages) {
|
|
|
1826
1861
|
console.error("[Messages] Sync error:", error);
|
|
1827
1862
|
}
|
|
1828
1863
|
}
|
|
1829
|
-
function createHistoryAdapter(baseUrl, userId, assistantId, remoteId) {
|
|
1830
|
-
const headers = createApiHeaders(userId, assistantId);
|
|
1864
|
+
function createHistoryAdapter(baseUrl, userId, assistantId, remoteId, userContext) {
|
|
1865
|
+
const headers = createApiHeaders(userId, assistantId, userContext);
|
|
1831
1866
|
return {
|
|
1832
1867
|
async load() {
|
|
1833
1868
|
console.log("[History] load() called, remoteId:", remoteId);
|
|
@@ -1925,8 +1960,8 @@ function AssistantRuntimeWrapper({
|
|
|
1925
1960
|
const clearContextRef = React2.useRef(clearContext);
|
|
1926
1961
|
clearContextRef.current = clearContext;
|
|
1927
1962
|
const threadListAdapter = React2.useMemo(
|
|
1928
|
-
() => createThreadListAdapter(baseUrl, userId, assistantId),
|
|
1929
|
-
[baseUrl, userId, assistantId]
|
|
1963
|
+
() => createThreadListAdapter(baseUrl, userId, assistantId, config.userContext),
|
|
1964
|
+
[baseUrl, userId, assistantId, config.userContext]
|
|
1930
1965
|
);
|
|
1931
1966
|
const runtime = react$1.unstable_useRemoteThreadListRuntime({
|
|
1932
1967
|
runtimeHook: function useChatThreadRuntime() {
|
|
@@ -1936,17 +1971,33 @@ function AssistantRuntimeWrapper({
|
|
|
1936
1971
|
const threadIdRef = React2.useRef(threadId);
|
|
1937
1972
|
threadIdRef.current = threadId;
|
|
1938
1973
|
const history = React2.useMemo(
|
|
1939
|
-
() => createHistoryAdapter(
|
|
1940
|
-
|
|
1974
|
+
() => createHistoryAdapter(
|
|
1975
|
+
baseUrl,
|
|
1976
|
+
userId,
|
|
1977
|
+
assistantId,
|
|
1978
|
+
threadId,
|
|
1979
|
+
config.userContext
|
|
1980
|
+
),
|
|
1981
|
+
[threadId, config.userContext]
|
|
1941
1982
|
);
|
|
1942
1983
|
const transport = React2.useMemo(() => {
|
|
1943
1984
|
console.log("[Widget] Creating transport for threadId:", threadId);
|
|
1985
|
+
const transportHeaders = {
|
|
1986
|
+
"X-User-Id": userId,
|
|
1987
|
+
"X-Assistant-Id": assistantId
|
|
1988
|
+
};
|
|
1989
|
+
if (config.userContext?.firstName) {
|
|
1990
|
+
transportHeaders["X-User-First-Name"] = config.userContext.firstName;
|
|
1991
|
+
}
|
|
1992
|
+
if (config.userContext?.lastName) {
|
|
1993
|
+
transportHeaders["X-User-Last-Name"] = config.userContext.lastName;
|
|
1994
|
+
}
|
|
1995
|
+
if (config.userContext?.email) {
|
|
1996
|
+
transportHeaders["X-User-Email"] = config.userContext.email;
|
|
1997
|
+
}
|
|
1944
1998
|
return new reactAiSdk.AssistantChatTransport({
|
|
1945
1999
|
api: `${baseUrl}/api/widget/chat`,
|
|
1946
|
-
headers:
|
|
1947
|
-
"X-User-Id": userId,
|
|
1948
|
-
"X-Assistant-Id": assistantId
|
|
1949
|
-
},
|
|
2000
|
+
headers: transportHeaders,
|
|
1950
2001
|
// Use body as a function to dynamically include context
|
|
1951
2002
|
body: () => {
|
|
1952
2003
|
const currentContext = contextRef.current();
|
|
@@ -1972,7 +2023,7 @@ function AssistantRuntimeWrapper({
|
|
|
1972
2023
|
};
|
|
1973
2024
|
}
|
|
1974
2025
|
});
|
|
1975
|
-
}, [threadId]);
|
|
2026
|
+
}, [threadId, config.userContext]);
|
|
1976
2027
|
const runtime2 = reactAiSdk.useChatRuntime({
|
|
1977
2028
|
transport,
|
|
1978
2029
|
adapters: { history },
|
|
@@ -1990,7 +2041,8 @@ function AssistantRuntimeWrapper({
|
|
|
1990
2041
|
userId,
|
|
1991
2042
|
assistantId,
|
|
1992
2043
|
currentThreadId,
|
|
1993
|
-
messages
|
|
2044
|
+
messages,
|
|
2045
|
+
config.userContext
|
|
1994
2046
|
);
|
|
1995
2047
|
}
|
|
1996
2048
|
}
|
|
@@ -2004,7 +2056,9 @@ function AssistantRuntimeWrapper({
|
|
|
2004
2056
|
function WidgetProvider({
|
|
2005
2057
|
config,
|
|
2006
2058
|
children,
|
|
2007
|
-
|
|
2059
|
+
// Legacy client initialization - disabled by default as the new assistant-ui
|
|
2060
|
+
// runtime handles session/thread management via the thread list adapter
|
|
2061
|
+
autoInitialize = false
|
|
2008
2062
|
}) {
|
|
2009
2063
|
const [userId] = React2.useState(() => config.userId || generateUserId());
|
|
2010
2064
|
const [client] = React2.useState(() => new WidgetClient(config));
|
|
@@ -2025,7 +2079,7 @@ function WidgetProvider({
|
|
|
2025
2079
|
() => ({ client, state, userId }),
|
|
2026
2080
|
[client, state, userId]
|
|
2027
2081
|
);
|
|
2028
|
-
return /* @__PURE__ */ jsxRuntime.jsx(react$2.CacheProvider, { value: widgetCache, children: /* @__PURE__ */ jsxRuntime.jsx(react$2.ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(WidgetContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(MessageContextProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(AssistantRuntimeWrapper, { config, userId, children }) }) }) }) });
|
|
2082
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react$2.CacheProvider, { value: widgetCache, children: /* @__PURE__ */ jsxRuntime.jsx(react$2.ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(WidgetContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(LessonContextProvider, { lessonContext: config.lessonContext, children: /* @__PURE__ */ jsxRuntime.jsx(MessageContextProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(AssistantRuntimeWrapper, { config, userId, children }) }) }) }) }) });
|
|
2029
2083
|
}
|
|
2030
2084
|
function useWidget() {
|
|
2031
2085
|
const context = React2.useContext(WidgetContext);
|
|
@@ -3428,7 +3482,10 @@ var MentionComposerInput = React2.forwardRef(
|
|
|
3428
3482
|
const walkForText = (node2) => {
|
|
3429
3483
|
if (node2 === range.endContainer) {
|
|
3430
3484
|
if (node2.nodeType === Node.TEXT_NODE) {
|
|
3431
|
-
textBeforeCursor += (node2.textContent || "").slice(
|
|
3485
|
+
textBeforeCursor += (node2.textContent || "").slice(
|
|
3486
|
+
0,
|
|
3487
|
+
range.endOffset
|
|
3488
|
+
);
|
|
3432
3489
|
}
|
|
3433
3490
|
return true;
|
|
3434
3491
|
}
|
|
@@ -3467,7 +3524,14 @@ var MentionComposerInput = React2.forwardRef(
|
|
|
3467
3524
|
triggerPositionRef.current = null;
|
|
3468
3525
|
onTriggerDismissed?.();
|
|
3469
3526
|
}
|
|
3470
|
-
}, [
|
|
3527
|
+
}, [
|
|
3528
|
+
syncToRuntime,
|
|
3529
|
+
getPlainText,
|
|
3530
|
+
getCursorPosition,
|
|
3531
|
+
onInput,
|
|
3532
|
+
onTriggerDetected,
|
|
3533
|
+
onTriggerDismissed
|
|
3534
|
+
]);
|
|
3471
3535
|
const handleKeyDown = React2.useCallback(
|
|
3472
3536
|
(e) => {
|
|
3473
3537
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
@@ -3500,7 +3564,9 @@ var MentionComposerInput = React2.forwardRef(
|
|
|
3500
3564
|
e.preventDefault();
|
|
3501
3565
|
const mentionId = prevSibling.dataset.mentionId;
|
|
3502
3566
|
prevSibling.parentNode?.removeChild(prevSibling);
|
|
3503
|
-
setInlineMentions(
|
|
3567
|
+
setInlineMentions(
|
|
3568
|
+
(prev2) => prev2.filter((m) => m.id !== mentionId)
|
|
3569
|
+
);
|
|
3504
3570
|
onMentionRemove?.(mentionId);
|
|
3505
3571
|
syncToRuntime();
|
|
3506
3572
|
return;
|
|
@@ -3513,7 +3579,9 @@ var MentionComposerInput = React2.forwardRef(
|
|
|
3513
3579
|
e.preventDefault();
|
|
3514
3580
|
const mentionId = childAtOffset.dataset.mentionId;
|
|
3515
3581
|
childAtOffset.parentNode?.removeChild(childAtOffset);
|
|
3516
|
-
setInlineMentions(
|
|
3582
|
+
setInlineMentions(
|
|
3583
|
+
(prev2) => prev2.filter((m) => m.id !== mentionId)
|
|
3584
|
+
);
|
|
3517
3585
|
onMentionRemove?.(mentionId);
|
|
3518
3586
|
syncToRuntime();
|
|
3519
3587
|
return;
|
|
@@ -3750,7 +3818,8 @@ var CATEGORY_LABELS = {
|
|
|
3750
3818
|
attachment: "Attachments",
|
|
3751
3819
|
description: "Description",
|
|
3752
3820
|
caption: "Video",
|
|
3753
|
-
link: "Links"
|
|
3821
|
+
link: "Links",
|
|
3822
|
+
lesson: "Current Lesson"
|
|
3754
3823
|
};
|
|
3755
3824
|
function useContextMention(options = {}) {
|
|
3756
3825
|
const { onInsertMention } = options;
|
|
@@ -3759,7 +3828,31 @@ function useContextMention(options = {}) {
|
|
|
3759
3828
|
throw new Error("useContextMention must be used within a WidgetProvider");
|
|
3760
3829
|
}
|
|
3761
3830
|
const { client } = widgetContext;
|
|
3762
|
-
const {
|
|
3831
|
+
const {
|
|
3832
|
+
selectedContext: selectedItems,
|
|
3833
|
+
addContextItem,
|
|
3834
|
+
removeContextItem,
|
|
3835
|
+
clearContext
|
|
3836
|
+
} = useMessageContext();
|
|
3837
|
+
const { lessonContext, hasLessonContext } = useLessonContext();
|
|
3838
|
+
React2.useEffect(() => {
|
|
3839
|
+
if (hasLessonContext && lessonContext) {
|
|
3840
|
+
const lessonItem = {
|
|
3841
|
+
id: lessonContext.lessonId,
|
|
3842
|
+
type: "lesson",
|
|
3843
|
+
title: lessonContext.lessonTitle,
|
|
3844
|
+
lessonTitle: lessonContext.lessonTitle,
|
|
3845
|
+
chapterTitle: lessonContext.chapterTitle
|
|
3846
|
+
};
|
|
3847
|
+
if (!selectedItems.some((item) => item.id === lessonItem.id)) {
|
|
3848
|
+
console.log(
|
|
3849
|
+
"[ContextMention] Auto-adding current lesson context:",
|
|
3850
|
+
lessonItem.title
|
|
3851
|
+
);
|
|
3852
|
+
addContextItem(lessonItem);
|
|
3853
|
+
}
|
|
3854
|
+
}
|
|
3855
|
+
}, [hasLessonContext]);
|
|
3763
3856
|
const [isOpen, setIsOpen] = React2.useState(false);
|
|
3764
3857
|
const [searchTerm, setSearchTerm] = React2.useState("");
|
|
3765
3858
|
const [activeIndex, setActiveIndex] = React2.useState(0);
|
|
@@ -3789,7 +3882,10 @@ function useContextMention(options = {}) {
|
|
|
3789
3882
|
}
|
|
3790
3883
|
);
|
|
3791
3884
|
if (!response.ok) {
|
|
3792
|
-
console.error(
|
|
3885
|
+
console.error(
|
|
3886
|
+
"[ContextMention] Failed to fetch context:",
|
|
3887
|
+
response.status
|
|
3888
|
+
);
|
|
3793
3889
|
return;
|
|
3794
3890
|
}
|
|
3795
3891
|
const data = await response.json();
|
|
@@ -3840,7 +3936,13 @@ function useContextMention(options = {}) {
|
|
|
3840
3936
|
closePopover();
|
|
3841
3937
|
onInsertMention?.(item);
|
|
3842
3938
|
}
|
|
3843
|
-
}, [
|
|
3939
|
+
}, [
|
|
3940
|
+
flattenedItems,
|
|
3941
|
+
activeIndex,
|
|
3942
|
+
addContextItem,
|
|
3943
|
+
closePopover,
|
|
3944
|
+
onInsertMention
|
|
3945
|
+
]);
|
|
3844
3946
|
const selectItem = React2.useCallback(
|
|
3845
3947
|
(item) => {
|
|
3846
3948
|
addContextItem(item);
|
|
@@ -3849,9 +3951,12 @@ function useContextMention(options = {}) {
|
|
|
3849
3951
|
},
|
|
3850
3952
|
[addContextItem, closePopover, onInsertMention]
|
|
3851
3953
|
);
|
|
3852
|
-
const removeItem = React2.useCallback(
|
|
3853
|
-
|
|
3854
|
-
|
|
3954
|
+
const removeItem = React2.useCallback(
|
|
3955
|
+
(itemId) => {
|
|
3956
|
+
removeContextItem(itemId);
|
|
3957
|
+
},
|
|
3958
|
+
[removeContextItem]
|
|
3959
|
+
);
|
|
3855
3960
|
const clearAll = React2.useCallback(() => {
|
|
3856
3961
|
clearContext();
|
|
3857
3962
|
}, [clearContext]);
|