@prodact.ai/sdk 0.0.2

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/index.mjs ADDED
@@ -0,0 +1,481 @@
1
+ // src/core.ts
2
+ var ProduckSDK = class {
3
+ constructor(config) {
4
+ this.actions = /* @__PURE__ */ new Map();
5
+ this.eventListeners = /* @__PURE__ */ new Map();
6
+ this.sessionToken = null;
7
+ this.isReady = false;
8
+ let apiUrl = config.apiUrl;
9
+ if (!apiUrl) {
10
+ if (typeof window !== "undefined") {
11
+ apiUrl = window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" ? "http://localhost:4001/api/v1" : `${window.location.protocol}//${window.location.host}/api/v1`;
12
+ } else {
13
+ apiUrl = "http://localhost:4001/api/v1";
14
+ }
15
+ }
16
+ this.config = {
17
+ apiUrl,
18
+ ...config
19
+ };
20
+ }
21
+ /**
22
+ * Initialize the SDK and create a chat session
23
+ */
24
+ async init() {
25
+ await this.log("info", "SDK Initializing", {
26
+ apiUrl: this.config.apiUrl,
27
+ hasSDKKey: !!this.config.sdkKey,
28
+ hasGuiderId: !!this.config.guiderId
29
+ });
30
+ try {
31
+ let endpoint;
32
+ if (this.config.sdkKey) {
33
+ endpoint = `${this.config.apiUrl}/sdk/session`;
34
+ await this.log("info", "Using SDK key authentication");
35
+ } else if (this.config.guiderId) {
36
+ endpoint = `${this.config.apiUrl}/chat/${this.config.guiderId}/session`;
37
+ await this.log("info", "Using guider ID authentication");
38
+ } else {
39
+ throw new Error("Either sdkKey or guiderId must be provided");
40
+ }
41
+ await this.log("info", "Creating session", { endpoint });
42
+ const headers = { "Content-Type": "application/json" };
43
+ if (this.config.sdkKey) {
44
+ headers["X-SDK-Key"] = this.config.sdkKey;
45
+ }
46
+ const response = await fetch(endpoint, {
47
+ method: "POST",
48
+ headers
49
+ });
50
+ if (!response.ok) {
51
+ await this.log("error", "Failed to create session", { status: response.status });
52
+ throw new Error(`Failed to create session: ${response.status}`);
53
+ }
54
+ const session = await response.json();
55
+ this.sessionToken = session.session_token;
56
+ this.isReady = true;
57
+ await this.log("info", "SDK initialized successfully", { hasSessionToken: !!this.sessionToken });
58
+ this.emit("ready", { sessionToken: this.sessionToken });
59
+ } catch (error) {
60
+ await this.log("error", "SDK initialization failed", { error: error instanceof Error ? error.message : String(error) });
61
+ this.emit("error", error);
62
+ throw error;
63
+ }
64
+ }
65
+ /**
66
+ * Register an action handler
67
+ */
68
+ register(actionKey, handler) {
69
+ this.actions.set(actionKey, handler);
70
+ this.log("info", "Action handler registered", { actionKey, totalActions: this.actions.size });
71
+ }
72
+ /**
73
+ * Unregister an action handler
74
+ */
75
+ unregister(actionKey) {
76
+ this.actions.delete(actionKey);
77
+ this.log("info", "Action handler unregistered", { actionKey, remainingActions: this.actions.size });
78
+ }
79
+ /**
80
+ * Send a message and handle potential action or flow triggers
81
+ */
82
+ async sendMessage(message) {
83
+ if (!this.isReady || !this.sessionToken) {
84
+ throw new Error("SDK not initialized. Call init() first.");
85
+ }
86
+ const startTime = Date.now();
87
+ await this.log("info", "sendMessage called", { message });
88
+ try {
89
+ let intentEndpoint;
90
+ const headers = { "Content-Type": "application/json" };
91
+ if (this.config.sdkKey) {
92
+ intentEndpoint = `${this.config.apiUrl}/sdk/match-intent`;
93
+ headers["X-SDK-Key"] = this.config.sdkKey;
94
+ } else {
95
+ intentEndpoint = `${this.config.apiUrl}/sdk/public/${this.config.guiderId}/match-intent`;
96
+ }
97
+ const intentResponse = await fetch(intentEndpoint, {
98
+ method: "POST",
99
+ headers,
100
+ body: JSON.stringify({ userMessage: message })
101
+ });
102
+ await this.log("info", "Match-intent response received", { status: intentResponse.status });
103
+ if (intentResponse.ok) {
104
+ const intentResult = await intentResponse.json();
105
+ if (intentResult.matched && intentResult.type === "flow" && intentResult.flow) {
106
+ await this.log("info", "Flow matched", {
107
+ flowId: intentResult.flow.flowId,
108
+ name: intentResult.flow.name,
109
+ stepCount: intentResult.flow.steps?.length
110
+ });
111
+ await this.sendLogToBackend({
112
+ userMessage: message,
113
+ matched: true,
114
+ actionKey: `flow:${intentResult.flow.flowId}`,
115
+ responseMessage: intentResult.responseMessage,
116
+ executionTimeMs: Date.now() - startTime
117
+ });
118
+ const flowResult = await this.executeFlow(intentResult.flow);
119
+ const flowMessage = {
120
+ role: "assistant",
121
+ content: intentResult.responseMessage || `I've completed the "${intentResult.flow.name}" flow for you.`,
122
+ flow: intentResult.flow,
123
+ flowResult
124
+ };
125
+ this.emit("message", flowMessage);
126
+ return flowMessage;
127
+ }
128
+ if (intentResult.matched && (intentResult.type === "operation" || intentResult.action)) {
129
+ const action = intentResult.action;
130
+ await this.log("info", "Action matched", {
131
+ actionKey: action.actionKey,
132
+ actionType: action.actionType,
133
+ responseMessage: action.responseMessage
134
+ });
135
+ await this.sendLogToBackend({
136
+ userMessage: message,
137
+ matched: true,
138
+ actionKey: action.actionKey,
139
+ responseMessage: action.responseMessage,
140
+ executionTimeMs: Date.now() - startTime
141
+ });
142
+ await this.executeAction(action);
143
+ const actionMessage = {
144
+ role: "assistant",
145
+ content: action.responseMessage || `I've triggered the "${action.name}" action for you.`,
146
+ action
147
+ };
148
+ this.emit("message", actionMessage);
149
+ return actionMessage;
150
+ } else {
151
+ await this.sendLogToBackend({
152
+ userMessage: message,
153
+ matched: false,
154
+ executionTimeMs: Date.now() - startTime
155
+ });
156
+ }
157
+ }
158
+ const sessionResponse = await fetch(
159
+ `${this.config.apiUrl}/chat/sessions/${this.sessionToken}/message`,
160
+ {
161
+ method: "POST",
162
+ headers: { "Content-Type": "application/json" },
163
+ body: JSON.stringify({ message })
164
+ }
165
+ );
166
+ if (!sessionResponse.ok) {
167
+ throw new Error(`Failed to send message: ${sessionResponse.status}`);
168
+ }
169
+ const result = await sessionResponse.json();
170
+ const chatMessage = {
171
+ role: "assistant",
172
+ content: result.message?.content || result.response || ""
173
+ };
174
+ await this.log("info", "Chat response received");
175
+ this.emit("message", chatMessage);
176
+ return chatMessage;
177
+ } catch (error) {
178
+ await this.log("error", "Error in sendMessage", { error: error instanceof Error ? error.message : String(error) });
179
+ this.emit("error", error);
180
+ throw error;
181
+ }
182
+ }
183
+ /**
184
+ * Execute a flow by running each step's operation sequentially
185
+ */
186
+ async executeFlow(flow) {
187
+ await this.log("info", "executeFlow started", {
188
+ flowId: flow.flowId,
189
+ name: flow.name,
190
+ stepCount: flow.steps.length
191
+ });
192
+ this.emit("flowStart", flow);
193
+ if (this.config.onFlowStart) {
194
+ this.config.onFlowStart(flow);
195
+ }
196
+ const stepResults = [];
197
+ let context = {};
198
+ const sortedSteps = [...flow.steps].sort((a, b) => a.order - b.order);
199
+ for (const step of sortedSteps) {
200
+ await this.log("info", "Executing flow step", {
201
+ flowId: flow.flowId,
202
+ operationId: step.operationId,
203
+ order: step.order
204
+ });
205
+ const stepResult = {
206
+ operationId: step.operationId,
207
+ order: step.order,
208
+ success: false
209
+ };
210
+ try {
211
+ const handler = this.actions.get(step.operationId);
212
+ if (handler) {
213
+ const actionPayload = {
214
+ actionKey: step.operationId,
215
+ name: step.operationId,
216
+ actionType: "callback",
217
+ actionConfig: {
218
+ flowContext: context,
219
+ inputMapping: step.inputMapping
220
+ }
221
+ };
222
+ const result = await handler(actionPayload);
223
+ stepResult.success = true;
224
+ stepResult.data = result;
225
+ context = {
226
+ ...context,
227
+ [`step_${step.order}`]: result,
228
+ previousResult: result
229
+ };
230
+ await this.log("info", "Flow step completed successfully", {
231
+ flowId: flow.flowId,
232
+ operationId: step.operationId,
233
+ order: step.order
234
+ });
235
+ } else {
236
+ await this.log("warn", "No handler registered for flow step", {
237
+ flowId: flow.flowId,
238
+ operationId: step.operationId
239
+ });
240
+ stepResult.success = true;
241
+ stepResult.data = { skipped: true, reason: "No handler registered" };
242
+ }
243
+ } catch (error) {
244
+ stepResult.success = false;
245
+ stepResult.error = error instanceof Error ? error.message : String(error);
246
+ await this.log("error", "Flow step failed", {
247
+ flowId: flow.flowId,
248
+ operationId: step.operationId,
249
+ error: stepResult.error
250
+ });
251
+ }
252
+ stepResults.push(stepResult);
253
+ this.emit("flowStepComplete", { step: stepResult, flow });
254
+ if (this.config.onFlowStepComplete) {
255
+ this.config.onFlowStepComplete(stepResult, flow);
256
+ }
257
+ }
258
+ const flowResult = {
259
+ flowId: flow.flowId,
260
+ name: flow.name,
261
+ steps: stepResults,
262
+ completed: true,
263
+ totalSteps: flow.steps.length,
264
+ successfulSteps: stepResults.filter((s) => s.success).length
265
+ };
266
+ await this.log("info", "Flow execution completed", {
267
+ flowId: flow.flowId,
268
+ totalSteps: flowResult.totalSteps,
269
+ successfulSteps: flowResult.successfulSteps
270
+ });
271
+ this.emit("flowComplete", flowResult);
272
+ if (this.config.onFlowComplete) {
273
+ this.config.onFlowComplete(flowResult);
274
+ }
275
+ return flowResult;
276
+ }
277
+ /**
278
+ * Send log data to backend for analytics
279
+ */
280
+ async sendLogToBackend(logData) {
281
+ try {
282
+ const headers = { "Content-Type": "application/json" };
283
+ if (this.config.sdkKey) {
284
+ headers["X-SDK-Key"] = this.config.sdkKey;
285
+ }
286
+ const logEndpoint = `${this.config.apiUrl}/sdk-logs/client`;
287
+ await fetch(logEndpoint, {
288
+ method: "POST",
289
+ headers,
290
+ body: JSON.stringify({
291
+ ...logData,
292
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
293
+ sessionToken: this.sessionToken
294
+ })
295
+ });
296
+ } catch (error) {
297
+ }
298
+ }
299
+ /**
300
+ * Send detailed log to backend
301
+ */
302
+ async log(level, message, data) {
303
+ try {
304
+ const headers = { "Content-Type": "application/json" };
305
+ if (this.config.sdkKey) {
306
+ headers["X-SDK-Key"] = this.config.sdkKey;
307
+ }
308
+ const logEndpoint = `${this.config.apiUrl}/sdk-logs/client`;
309
+ await fetch(logEndpoint, {
310
+ method: "POST",
311
+ headers,
312
+ body: JSON.stringify({
313
+ level,
314
+ message,
315
+ data,
316
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
317
+ sessionToken: this.sessionToken
318
+ })
319
+ });
320
+ } catch (error) {
321
+ }
322
+ }
323
+ /**
324
+ * Execute a registered action
325
+ */
326
+ async executeAction(action) {
327
+ const registeredKeys = Array.from(this.actions.keys());
328
+ if (typeof window !== "undefined") {
329
+ console.log("%c\u{1F3AF} SDK executeAction", "background: #ff0; color: #000; font-size: 20px; padding: 10px;", {
330
+ actionKey: action.actionKey,
331
+ totalRegistered: this.actions.size,
332
+ registeredKeys
333
+ });
334
+ }
335
+ await this.log("info", "executeAction called", {
336
+ actionKey: action.actionKey,
337
+ actionType: typeof action.actionKey,
338
+ totalRegistered: this.actions.size,
339
+ registeredKeys,
340
+ keyComparisons: registeredKeys.map((key) => ({
341
+ key,
342
+ matches: key === action.actionKey,
343
+ keyLength: key.length,
344
+ actionKeyLength: action.actionKey.length
345
+ }))
346
+ });
347
+ const handler = this.actions.get(action.actionKey);
348
+ if (typeof window !== "undefined") {
349
+ console.log("%c\u{1F50D} SDK Handler Lookup", "background: #0ff; color: #000; font-size: 16px; padding: 5px;", {
350
+ actionKey: action.actionKey,
351
+ found: !!handler,
352
+ hasConfigOnAction: !!this.config.onAction,
353
+ registeredKeys: Array.from(this.actions.keys())
354
+ });
355
+ }
356
+ if (handler) {
357
+ try {
358
+ const startTime = Date.now();
359
+ await handler(action);
360
+ const executionTime = Date.now() - startTime;
361
+ await this.log("info", "Handler executed successfully", {
362
+ actionKey: action.actionKey,
363
+ executionTime
364
+ });
365
+ await this.sendLogToBackend({
366
+ userMessage: `Action executed: ${action.actionKey}`,
367
+ matched: true,
368
+ actionKey: action.actionKey,
369
+ responseMessage: action.responseMessage || `Executed ${action.name}`,
370
+ executionTimeMs: executionTime
371
+ });
372
+ this.emit("action", action);
373
+ this.config.onAction?.(action.actionKey, action);
374
+ } catch (error) {
375
+ await this.log("error", "Handler execution failed", {
376
+ actionKey: action.actionKey,
377
+ error: error instanceof Error ? error.message : String(error),
378
+ stack: error instanceof Error ? error.stack : void 0
379
+ });
380
+ await this.sendLogToBackend({
381
+ userMessage: `Action execution failed: ${action.actionKey}`,
382
+ matched: true,
383
+ actionKey: action.actionKey,
384
+ error: error instanceof Error ? error.message : String(error)
385
+ });
386
+ this.emit("error", error);
387
+ }
388
+ } else {
389
+ if (this.config.onAction) {
390
+ await this.log("info", "No internal handler, trying config.onAction callback", {
391
+ actionKey: action.actionKey
392
+ });
393
+ try {
394
+ this.config.onAction(action.actionKey, action);
395
+ this.emit("action", action);
396
+ await this.log("info", "Action dispatched via config.onAction", {
397
+ actionKey: action.actionKey
398
+ });
399
+ await this.sendLogToBackend({
400
+ userMessage: `Action dispatched: ${action.actionKey}`,
401
+ matched: true,
402
+ actionKey: action.actionKey,
403
+ responseMessage: action.responseMessage || `Dispatched ${action.name}`
404
+ });
405
+ return;
406
+ } catch (error) {
407
+ await this.log("error", "config.onAction callback failed", {
408
+ actionKey: action.actionKey,
409
+ error: error instanceof Error ? error.message : String(error)
410
+ });
411
+ }
412
+ }
413
+ await this.log("warn", "No handler registered for action", {
414
+ actionKey: action.actionKey,
415
+ registeredActions: Array.from(this.actions.keys())
416
+ });
417
+ await this.sendLogToBackend({
418
+ userMessage: `No handler for action: ${action.actionKey}`,
419
+ matched: false,
420
+ actionKey: action.actionKey,
421
+ error: `Handler not registered. Available: ${Array.from(this.actions.keys()).join(", ")}`
422
+ });
423
+ }
424
+ }
425
+ /**
426
+ * Add event listener
427
+ */
428
+ on(event, callback) {
429
+ if (!this.eventListeners.has(event)) {
430
+ this.eventListeners.set(event, /* @__PURE__ */ new Set());
431
+ }
432
+ this.eventListeners.get(event).add(callback);
433
+ }
434
+ /**
435
+ * Remove event listener
436
+ */
437
+ off(event, callback) {
438
+ this.eventListeners.get(event)?.delete(callback);
439
+ }
440
+ /**
441
+ * Emit event
442
+ */
443
+ emit(event, data) {
444
+ this.eventListeners.get(event)?.forEach((callback) => callback(data));
445
+ }
446
+ /**
447
+ * Get session token
448
+ */
449
+ getSessionToken() {
450
+ return this.sessionToken;
451
+ }
452
+ /**
453
+ * Check if SDK is ready
454
+ */
455
+ getIsReady() {
456
+ return this.isReady;
457
+ }
458
+ /**
459
+ * Get registered action keys
460
+ */
461
+ getRegisteredActions() {
462
+ return Array.from(this.actions.keys());
463
+ }
464
+ /**
465
+ * Destroy the SDK instance
466
+ */
467
+ destroy() {
468
+ this.actions.clear();
469
+ this.eventListeners.clear();
470
+ this.sessionToken = null;
471
+ this.isReady = false;
472
+ }
473
+ };
474
+ function createProduck(config) {
475
+ return new ProduckSDK(config);
476
+ }
477
+ export {
478
+ ProduckSDK,
479
+ createProduck
480
+ };
481
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core.ts"],"sourcesContent":["// Types\nexport interface ProduckConfig {\n guiderId?: string; // Legacy support\n sdkKey?: string; // New SDK key approach\n apiUrl?: string;\n onAction?: (actionKey: string, action: ActionPayload) => void;\n onMessage?: (message: ChatMessage) => void;\n onError?: (error: Error) => void;\n onFlowStart?: (flow: FlowPayload) => void;\n onFlowStepComplete?: (step: FlowStepResult, flow: FlowPayload) => void;\n onFlowComplete?: (result: FlowResult) => void;\n}\n\nexport interface ActionPayload {\n actionKey: string;\n name: string;\n actionType: string;\n actionConfig: Record<string, any>;\n responseMessage?: string;\n}\n\n// Flow types\nexport interface FlowStep {\n operationId: string;\n order: number;\n condition?: Record<string, any>;\n inputMapping?: Record<string, any>;\n}\n\nexport interface FlowPayload {\n flowId: string;\n name: string;\n description: string;\n steps: FlowStep[];\n}\n\nexport interface FlowStepResult {\n operationId: string;\n order: number;\n success: boolean;\n data?: any;\n error?: string;\n}\n\nexport interface FlowResult {\n flowId: string;\n name: string;\n steps: FlowStepResult[];\n completed: boolean;\n totalSteps: number;\n successfulSteps: number;\n}\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n action?: ActionPayload;\n flow?: FlowPayload;\n flowResult?: FlowResult;\n}\n\nexport interface ActionHandler {\n (payload: ActionPayload): void | Promise<void>;\n}\n\nexport interface RegisteredAction {\n key: string;\n handler: ActionHandler;\n}\n\nexport type ProduckEventType = 'action' | 'message' | 'error' | 'ready' | 'flowStart' | 'flowStepComplete' | 'flowComplete';\n\nexport interface ProduckEvent {\n type: ProduckEventType;\n data: any;\n}\n\n// Core SDK Class\nexport class ProduckSDK {\n private config: ProduckConfig;\n private actions: Map<string, ActionHandler> = new Map();\n private eventListeners: Map<ProduckEventType, Set<Function>> = new Map();\n private sessionToken: string | null = null;\n private isReady: boolean = false;\n\n constructor(config: ProduckConfig) {\n // Determine API URL - use custom if provided, otherwise use smart defaults\n let apiUrl = config.apiUrl;\n \n if (!apiUrl) {\n // Check if we're in a browser environment and running on localhost\n if (typeof window !== 'undefined') {\n apiUrl = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'\n ? 'http://localhost:4001/api/v1'\n : `${window.location.protocol}//${window.location.host}/api/v1`;\n } else {\n // Server-side default\n apiUrl = 'http://localhost:4001/api/v1';\n }\n }\n \n this.config = {\n apiUrl,\n ...config,\n };\n }\n\n /**\n * Initialize the SDK and create a chat session\n */\n async init(): Promise<void> {\n await this.log('info', 'SDK Initializing', {\n apiUrl: this.config.apiUrl,\n hasSDKKey: !!this.config.sdkKey,\n hasGuiderId: !!this.config.guiderId,\n });\n \n try {\n let endpoint: string;\n \n if (this.config.sdkKey) {\n // New SDK key approach\n endpoint = `${this.config.apiUrl}/sdk/session`;\n await this.log('info', 'Using SDK key authentication');\n } else if (this.config.guiderId) {\n // Legacy guider approach\n endpoint = `${this.config.apiUrl}/chat/${this.config.guiderId}/session`;\n await this.log('info', 'Using guider ID authentication');\n } else {\n throw new Error('Either sdkKey or guiderId must be provided');\n }\n\n await this.log('info', 'Creating session', { endpoint });\n\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.sdkKey) {\n headers['X-SDK-Key'] = this.config.sdkKey;\n }\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n });\n\n if (!response.ok) {\n await this.log('error', 'Failed to create session', { status: response.status });\n throw new Error(`Failed to create session: ${response.status}`);\n }\n\n const session = await response.json();\n this.sessionToken = session.session_token;\n this.isReady = true;\n \n await this.log('info', 'SDK initialized successfully', { hasSessionToken: !!this.sessionToken });\n \n this.emit('ready', { sessionToken: this.sessionToken });\n } catch (error) {\n await this.log('error', 'SDK initialization failed', { error: error instanceof Error ? error.message : String(error) });\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Register an action handler\n */\n register(actionKey: string, handler: ActionHandler): void {\n this.actions.set(actionKey, handler);\n this.log('info', 'Action handler registered', { actionKey, totalActions: this.actions.size });\n }\n\n /**\n * Unregister an action handler\n */\n unregister(actionKey: string): void {\n this.actions.delete(actionKey);\n this.log('info', 'Action handler unregistered', { actionKey, remainingActions: this.actions.size });\n }\n\n /**\n * Send a message and handle potential action or flow triggers\n */\n async sendMessage(message: string): Promise<ChatMessage> {\n if (!this.isReady || !this.sessionToken) {\n throw new Error('SDK not initialized. Call init() first.');\n }\n\n const startTime = Date.now();\n await this.log('info', 'sendMessage called', { message });\n\n try {\n // First, check if message matches any SDK action or flow\n let intentEndpoint: string;\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n \n if (this.config.sdkKey) {\n intentEndpoint = `${this.config.apiUrl}/sdk/match-intent`;\n headers['X-SDK-Key'] = this.config.sdkKey;\n } else {\n intentEndpoint = `${this.config.apiUrl}/sdk/public/${this.config.guiderId}/match-intent`;\n }\n\n const intentResponse = await fetch(intentEndpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({ userMessage: message }),\n });\n\n await this.log('info', 'Match-intent response received', { status: intentResponse.status });\n\n if (intentResponse.ok) {\n const intentResult = await intentResponse.json();\n \n // Handle FLOW match\n if (intentResult.matched && intentResult.type === 'flow' && intentResult.flow) {\n await this.log('info', 'Flow matched', {\n flowId: intentResult.flow.flowId,\n name: intentResult.flow.name,\n stepCount: intentResult.flow.steps?.length,\n });\n \n // Send log to backend\n await this.sendLogToBackend({\n userMessage: message,\n matched: true,\n actionKey: `flow:${intentResult.flow.flowId}`,\n responseMessage: intentResult.responseMessage,\n executionTimeMs: Date.now() - startTime,\n });\n \n // Execute the flow\n const flowResult = await this.executeFlow(intentResult.flow);\n \n const flowMessage: ChatMessage = {\n role: 'assistant',\n content: intentResult.responseMessage || `I've completed the \"${intentResult.flow.name}\" flow for you.`,\n flow: intentResult.flow,\n flowResult,\n };\n \n this.emit('message', flowMessage);\n return flowMessage;\n }\n \n // Handle OPERATION match (existing behavior)\n if (intentResult.matched && (intentResult.type === 'operation' || intentResult.action)) {\n const action = intentResult.action;\n await this.log('info', 'Action matched', {\n actionKey: action.actionKey,\n actionType: action.actionType,\n responseMessage: action.responseMessage,\n });\n \n // Send log to backend\n await this.sendLogToBackend({\n userMessage: message,\n matched: true,\n actionKey: action.actionKey,\n responseMessage: action.responseMessage,\n executionTimeMs: Date.now() - startTime,\n });\n \n // Execute the action\n await this.executeAction(action);\n \n const actionMessage: ChatMessage = {\n role: 'assistant',\n content: action.responseMessage || `I've triggered the \"${action.name}\" action for you.`,\n action: action,\n };\n \n this.emit('message', actionMessage);\n return actionMessage;\n } else {\n \n // Send log for no match\n await this.sendLogToBackend({\n userMessage: message,\n matched: false,\n executionTimeMs: Date.now() - startTime,\n });\n }\n }\n\n // No action matched, send to regular chat\n const sessionResponse = await fetch(\n `${this.config.apiUrl}/chat/sessions/${this.sessionToken}/message`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message }),\n }\n );\n\n if (!sessionResponse.ok) {\n throw new Error(`Failed to send message: ${sessionResponse.status}`);\n }\n\n const result = await sessionResponse.json();\n const chatMessage: ChatMessage = {\n role: 'assistant',\n content: result.message?.content || result.response || '',\n };\n\n await this.log('info', 'Chat response received');\n this.emit('message', chatMessage);\n return chatMessage;\n } catch (error) {\n await this.log('error', 'Error in sendMessage', { error: error instanceof Error ? error.message : String(error) });\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Execute a flow by running each step's operation sequentially\n */\n async executeFlow(flow: FlowPayload): Promise<FlowResult> {\n await this.log('info', 'executeFlow started', {\n flowId: flow.flowId,\n name: flow.name,\n stepCount: flow.steps.length,\n });\n\n // Emit flow start event\n this.emit('flowStart', flow);\n if (this.config.onFlowStart) {\n this.config.onFlowStart(flow);\n }\n\n const stepResults: FlowStepResult[] = [];\n let context: Record<string, any> = {};\n\n // Sort steps by order\n const sortedSteps = [...flow.steps].sort((a, b) => a.order - b.order);\n\n for (const step of sortedSteps) {\n await this.log('info', 'Executing flow step', {\n flowId: flow.flowId,\n operationId: step.operationId,\n order: step.order,\n });\n\n const stepResult: FlowStepResult = {\n operationId: step.operationId,\n order: step.order,\n success: false,\n };\n\n try {\n // Get the handler for this operation\n const handler = this.actions.get(step.operationId);\n \n if (handler) {\n // Create action payload for the step\n const actionPayload: ActionPayload = {\n actionKey: step.operationId,\n name: step.operationId,\n actionType: 'callback',\n actionConfig: {\n flowContext: context,\n inputMapping: step.inputMapping,\n },\n };\n\n // Execute the handler\n const result = await handler(actionPayload);\n \n stepResult.success = true;\n stepResult.data = result;\n \n // Update context with result for next step\n context = {\n ...context,\n [`step_${step.order}`]: result,\n previousResult: result,\n };\n\n await this.log('info', 'Flow step completed successfully', {\n flowId: flow.flowId,\n operationId: step.operationId,\n order: step.order,\n });\n } else {\n // No handler registered - log warning but continue\n await this.log('warn', 'No handler registered for flow step', {\n flowId: flow.flowId,\n operationId: step.operationId,\n });\n stepResult.success = true; // Consider it \"success\" if no handler needed\n stepResult.data = { skipped: true, reason: 'No handler registered' };\n }\n } catch (error) {\n stepResult.success = false;\n stepResult.error = error instanceof Error ? error.message : String(error);\n \n await this.log('error', 'Flow step failed', {\n flowId: flow.flowId,\n operationId: step.operationId,\n error: stepResult.error,\n });\n }\n\n stepResults.push(stepResult);\n\n // Emit step complete event\n this.emit('flowStepComplete', { step: stepResult, flow });\n if (this.config.onFlowStepComplete) {\n this.config.onFlowStepComplete(stepResult, flow);\n }\n }\n\n const flowResult: FlowResult = {\n flowId: flow.flowId,\n name: flow.name,\n steps: stepResults,\n completed: true,\n totalSteps: flow.steps.length,\n successfulSteps: stepResults.filter(s => s.success).length,\n };\n\n await this.log('info', 'Flow execution completed', {\n flowId: flow.flowId,\n totalSteps: flowResult.totalSteps,\n successfulSteps: flowResult.successfulSteps,\n });\n\n // Emit flow complete event\n this.emit('flowComplete', flowResult);\n if (this.config.onFlowComplete) {\n this.config.onFlowComplete(flowResult);\n }\n\n return flowResult;\n }\n\n /**\n * Send log data to backend for analytics\n */\n private async sendLogToBackend(logData: {\n userMessage: string;\n matched: boolean;\n actionKey?: string;\n responseMessage?: string;\n executionTimeMs?: number;\n error?: string;\n }): Promise<void> {\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.sdkKey) {\n headers['X-SDK-Key'] = this.config.sdkKey;\n }\n\n const logEndpoint = `${this.config.apiUrl}/sdk-logs/client`;\n \n await fetch(logEndpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n ...logData,\n timestamp: new Date().toISOString(),\n sessionToken: this.sessionToken,\n }),\n });\n } catch (error) {\n // Silently fail - don't block operations due to logging failures\n }\n }\n\n /**\n * Send detailed log to backend\n */\n private async log(level: 'info' | 'warn' | 'error', message: string, data?: any): Promise<void> {\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.sdkKey) {\n headers['X-SDK-Key'] = this.config.sdkKey;\n }\n\n const logEndpoint = `${this.config.apiUrl}/sdk-logs/client`;\n \n await fetch(logEndpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n level,\n message,\n data,\n timestamp: new Date().toISOString(),\n sessionToken: this.sessionToken,\n }),\n });\n } catch (error) {\n // Silently fail\n }\n }\n\n /**\n * Execute a registered action\n */\n private async executeAction(action: ActionPayload): Promise<void> {\n const registeredKeys = Array.from(this.actions.keys());\n \n // Very visible debug - will show popup in browser\n if (typeof window !== 'undefined') {\n console.log('%c🎯 SDK executeAction', 'background: #ff0; color: #000; font-size: 20px; padding: 10px;', {\n actionKey: action.actionKey,\n totalRegistered: this.actions.size,\n registeredKeys,\n });\n }\n \n await this.log('info', 'executeAction called', {\n actionKey: action.actionKey,\n actionType: typeof action.actionKey,\n totalRegistered: this.actions.size,\n registeredKeys,\n keyComparisons: registeredKeys.map(key => ({\n key,\n matches: key === action.actionKey,\n keyLength: key.length,\n actionKeyLength: action.actionKey.length,\n })),\n });\n \n const handler = this.actions.get(action.actionKey);\n \n if (typeof window !== 'undefined') {\n console.log('%c🔍 SDK Handler Lookup', 'background: #0ff; color: #000; font-size: 16px; padding: 5px;', {\n actionKey: action.actionKey,\n found: !!handler,\n hasConfigOnAction: !!this.config.onAction,\n registeredKeys: Array.from(this.actions.keys()),\n });\n }\n \n if (handler) {\n try {\n const startTime = Date.now();\n await handler(action);\n const executionTime = Date.now() - startTime;\n \n await this.log('info', 'Handler executed successfully', {\n actionKey: action.actionKey,\n executionTime,\n });\n \n await this.sendLogToBackend({\n userMessage: `Action executed: ${action.actionKey}`,\n matched: true,\n actionKey: action.actionKey,\n responseMessage: action.responseMessage || `Executed ${action.name}`,\n executionTimeMs: executionTime,\n });\n \n this.emit('action', action);\n this.config.onAction?.(action.actionKey, action);\n } catch (error) {\n await this.log('error', 'Handler execution failed', {\n actionKey: action.actionKey,\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n \n await this.sendLogToBackend({\n userMessage: `Action execution failed: ${action.actionKey}`,\n matched: true,\n actionKey: action.actionKey,\n error: error instanceof Error ? error.message : String(error),\n });\n \n this.emit('error', error);\n }\n } else {\n // No handler in SDK's internal registry, but try the config callback\n // (ProduckProvider registers handlers there via actionsRef)\n if (this.config.onAction) {\n await this.log('info', 'No internal handler, trying config.onAction callback', {\n actionKey: action.actionKey,\n });\n \n try {\n this.config.onAction(action.actionKey, action);\n this.emit('action', action);\n \n await this.log('info', 'Action dispatched via config.onAction', {\n actionKey: action.actionKey,\n });\n \n await this.sendLogToBackend({\n userMessage: `Action dispatched: ${action.actionKey}`,\n matched: true,\n actionKey: action.actionKey,\n responseMessage: action.responseMessage || `Dispatched ${action.name}`,\n });\n return;\n } catch (error) {\n await this.log('error', 'config.onAction callback failed', {\n actionKey: action.actionKey,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n \n await this.log('warn', 'No handler registered for action', {\n actionKey: action.actionKey,\n registeredActions: Array.from(this.actions.keys()),\n });\n \n await this.sendLogToBackend({\n userMessage: `No handler for action: ${action.actionKey}`,\n matched: false,\n actionKey: action.actionKey,\n error: `Handler not registered. Available: ${Array.from(this.actions.keys()).join(', ')}`,\n });\n }\n }\n\n /**\n * Add event listener\n */\n on(event: ProduckEventType, callback: Function): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Remove event listener\n */\n off(event: ProduckEventType, callback: Function): void {\n this.eventListeners.get(event)?.delete(callback);\n }\n\n /**\n * Emit event\n */\n private emit(event: ProduckEventType, data: any): void {\n this.eventListeners.get(event)?.forEach(callback => callback(data));\n }\n\n /**\n * Get session token\n */\n getSessionToken(): string | null {\n return this.sessionToken;\n }\n\n /**\n * Check if SDK is ready\n */\n getIsReady(): boolean {\n return this.isReady;\n }\n\n /**\n * Get registered action keys\n */\n getRegisteredActions(): string[] {\n return Array.from(this.actions.keys());\n }\n\n /**\n * Destroy the SDK instance\n */\n destroy(): void {\n this.actions.clear();\n this.eventListeners.clear();\n this.sessionToken = null;\n this.isReady = false;\n }\n}\n\n// Factory function\nexport function createProduck(config: ProduckConfig): ProduckSDK {\n return new ProduckSDK(config);\n}\n\n// Default export\nexport default ProduckSDK;\n"],"mappings":"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","names":[]}