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