@sentrial/sdk 0.1.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/README.md +208 -0
- package/dist/index.cjs +595 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +642 -0
- package/dist/index.d.ts +642 -0
- package/dist/index.js +556 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,595 @@
|
|
|
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 index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ApiError: () => ApiError,
|
|
24
|
+
EventType: () => EventType,
|
|
25
|
+
Interaction: () => Interaction,
|
|
26
|
+
NetworkError: () => NetworkError,
|
|
27
|
+
SentrialClient: () => SentrialClient,
|
|
28
|
+
SentrialError: () => SentrialError,
|
|
29
|
+
ValidationError: () => ValidationError,
|
|
30
|
+
begin: () => begin,
|
|
31
|
+
calculateAnthropicCost: () => calculateAnthropicCost,
|
|
32
|
+
calculateGoogleCost: () => calculateGoogleCost,
|
|
33
|
+
calculateOpenAICost: () => calculateOpenAICost,
|
|
34
|
+
configure: () => configure,
|
|
35
|
+
sentrial: () => sentrial
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
|
|
39
|
+
// src/errors.ts
|
|
40
|
+
var SentrialError = class _SentrialError extends Error {
|
|
41
|
+
/** HTTP status code (if applicable) */
|
|
42
|
+
status;
|
|
43
|
+
/** Error code from the API */
|
|
44
|
+
code;
|
|
45
|
+
/** Additional error details */
|
|
46
|
+
details;
|
|
47
|
+
constructor(message, options) {
|
|
48
|
+
super(message, { cause: options?.cause });
|
|
49
|
+
this.name = "SentrialError";
|
|
50
|
+
this.status = options?.status;
|
|
51
|
+
this.code = options?.code;
|
|
52
|
+
this.details = options?.details;
|
|
53
|
+
if (Error.captureStackTrace) {
|
|
54
|
+
Error.captureStackTrace(this, _SentrialError);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if the error is a rate limit error
|
|
59
|
+
*/
|
|
60
|
+
isRateLimitError() {
|
|
61
|
+
return this.status === 429;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if the error is an authentication error
|
|
65
|
+
*/
|
|
66
|
+
isAuthError() {
|
|
67
|
+
return this.status === 401 || this.status === 403;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if the error is a network/connection error
|
|
71
|
+
*/
|
|
72
|
+
isNetworkError() {
|
|
73
|
+
return this.code === "NETWORK_ERROR" || this.code === "ECONNREFUSED";
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Convert to a plain object for logging
|
|
77
|
+
*/
|
|
78
|
+
toJSON() {
|
|
79
|
+
return {
|
|
80
|
+
name: this.name,
|
|
81
|
+
message: this.message,
|
|
82
|
+
status: this.status,
|
|
83
|
+
code: this.code,
|
|
84
|
+
details: this.details,
|
|
85
|
+
stack: this.stack
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
var ApiError = class extends SentrialError {
|
|
90
|
+
constructor(message, status, code, details) {
|
|
91
|
+
super(message, { status, code, details });
|
|
92
|
+
this.name = "ApiError";
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
var NetworkError = class extends SentrialError {
|
|
96
|
+
constructor(message, cause) {
|
|
97
|
+
super(message, { code: "NETWORK_ERROR", cause });
|
|
98
|
+
this.name = "NetworkError";
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
var ValidationError = class extends SentrialError {
|
|
102
|
+
constructor(message, details) {
|
|
103
|
+
super(message, { code: "VALIDATION_ERROR", details });
|
|
104
|
+
this.name = "ValidationError";
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// src/cost.ts
|
|
109
|
+
var OPENAI_PRICING = {
|
|
110
|
+
"gpt-5.2": { input: 5, output: 15 },
|
|
111
|
+
"gpt-5": { input: 4, output: 12 },
|
|
112
|
+
"gpt-4o": { input: 2.5, output: 10 },
|
|
113
|
+
"gpt-4o-mini": { input: 0.15, output: 0.6 },
|
|
114
|
+
"gpt-4-turbo": { input: 10, output: 30 },
|
|
115
|
+
"gpt-4": { input: 30, output: 60 },
|
|
116
|
+
"gpt-3.5-turbo": { input: 0.5, output: 1.5 },
|
|
117
|
+
"o3": { input: 10, output: 40 },
|
|
118
|
+
"o3-mini": { input: 3, output: 12 },
|
|
119
|
+
"o1-preview": { input: 15, output: 60 },
|
|
120
|
+
"o1-mini": { input: 3, output: 12 }
|
|
121
|
+
};
|
|
122
|
+
var ANTHROPIC_PRICING = {
|
|
123
|
+
"claude-4.5-opus": { input: 20, output: 100 },
|
|
124
|
+
"claude-4.5-sonnet": { input: 4, output: 20 },
|
|
125
|
+
"claude-4-opus": { input: 18, output: 90 },
|
|
126
|
+
"claude-4-sonnet": { input: 3.5, output: 17.5 },
|
|
127
|
+
"claude-3-5-sonnet": { input: 3, output: 15 },
|
|
128
|
+
"claude-3-opus": { input: 15, output: 75 },
|
|
129
|
+
"claude-3-sonnet": { input: 3, output: 15 },
|
|
130
|
+
"claude-3-haiku": { input: 0.25, output: 1.25 }
|
|
131
|
+
};
|
|
132
|
+
var GOOGLE_PRICING = {
|
|
133
|
+
// Gemini 3 - Preview (Jan 2026)
|
|
134
|
+
"gemini-3-pro": { input: 2, output: 12 },
|
|
135
|
+
"gemini-3-flash": { input: 0.5, output: 3 },
|
|
136
|
+
// Gemini 2.5
|
|
137
|
+
"gemini-2.5-pro": { input: 1.25, output: 5 },
|
|
138
|
+
"gemini-2.5-flash": { input: 0.15, output: 0.6 },
|
|
139
|
+
// Gemini 2.0
|
|
140
|
+
"gemini-2.0-flash": { input: 0.1, output: 0.4 },
|
|
141
|
+
"gemini-2.0-flash-lite": { input: 0.075, output: 0.3 },
|
|
142
|
+
// Gemini 1.5
|
|
143
|
+
"gemini-1.5-pro": { input: 1.25, output: 5 },
|
|
144
|
+
"gemini-1.5-flash": { input: 0.075, output: 0.3 },
|
|
145
|
+
// Gemini 1.0
|
|
146
|
+
"gemini-1.0-pro": { input: 0.5, output: 1.5 }
|
|
147
|
+
};
|
|
148
|
+
function findModelKey(model, pricing) {
|
|
149
|
+
for (const key of Object.keys(pricing)) {
|
|
150
|
+
if (model.startsWith(key)) {
|
|
151
|
+
return key;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
function calculateCost(inputTokens, outputTokens, rates) {
|
|
157
|
+
const inputCost = inputTokens / 1e6 * rates.input;
|
|
158
|
+
const outputCost = outputTokens / 1e6 * rates.output;
|
|
159
|
+
return inputCost + outputCost;
|
|
160
|
+
}
|
|
161
|
+
function calculateOpenAICost(params) {
|
|
162
|
+
const { model, inputTokens, outputTokens } = params;
|
|
163
|
+
const modelKey = findModelKey(model, OPENAI_PRICING) ?? "gpt-4";
|
|
164
|
+
return calculateCost(inputTokens, outputTokens, OPENAI_PRICING[modelKey]);
|
|
165
|
+
}
|
|
166
|
+
function calculateAnthropicCost(params) {
|
|
167
|
+
const { model, inputTokens, outputTokens } = params;
|
|
168
|
+
const modelKey = findModelKey(model, ANTHROPIC_PRICING) ?? "claude-3-sonnet";
|
|
169
|
+
return calculateCost(inputTokens, outputTokens, ANTHROPIC_PRICING[modelKey]);
|
|
170
|
+
}
|
|
171
|
+
function calculateGoogleCost(params) {
|
|
172
|
+
const { model, inputTokens, outputTokens } = params;
|
|
173
|
+
const modelKey = findModelKey(model, GOOGLE_PRICING) ?? "gemini-2.0-flash";
|
|
174
|
+
return calculateCost(inputTokens, outputTokens, GOOGLE_PRICING[modelKey]);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// src/types.ts
|
|
178
|
+
var EventType = /* @__PURE__ */ ((EventType2) => {
|
|
179
|
+
EventType2["TOOL_CALL"] = "tool_call";
|
|
180
|
+
EventType2["LLM_DECISION"] = "llm_decision";
|
|
181
|
+
EventType2["STATE_CHANGE"] = "state_change";
|
|
182
|
+
EventType2["ERROR"] = "error";
|
|
183
|
+
return EventType2;
|
|
184
|
+
})(EventType || {});
|
|
185
|
+
|
|
186
|
+
// src/client.ts
|
|
187
|
+
var DEFAULT_API_URL = "https://api.sentrial.com";
|
|
188
|
+
var SentrialClient = class {
|
|
189
|
+
apiUrl;
|
|
190
|
+
apiKey;
|
|
191
|
+
failSilently;
|
|
192
|
+
currentState = {};
|
|
193
|
+
constructor(config = {}) {
|
|
194
|
+
this.apiUrl = (config.apiUrl ?? (typeof process !== "undefined" ? process.env?.SENTRIAL_API_URL : void 0) ?? DEFAULT_API_URL).replace(/\/$/, "");
|
|
195
|
+
this.apiKey = config.apiKey ?? (typeof process !== "undefined" ? process.env?.SENTRIAL_API_KEY : void 0);
|
|
196
|
+
this.failSilently = config.failSilently ?? true;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Make an HTTP request with graceful error handling
|
|
200
|
+
*/
|
|
201
|
+
async safeRequest(method, url, body) {
|
|
202
|
+
try {
|
|
203
|
+
const headers = {
|
|
204
|
+
"Content-Type": "application/json"
|
|
205
|
+
};
|
|
206
|
+
if (this.apiKey) {
|
|
207
|
+
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
208
|
+
}
|
|
209
|
+
const response = await fetch(url, {
|
|
210
|
+
method,
|
|
211
|
+
headers,
|
|
212
|
+
body: body ? JSON.stringify(body) : void 0
|
|
213
|
+
});
|
|
214
|
+
if (!response.ok) {
|
|
215
|
+
const errorBody = await response.text();
|
|
216
|
+
let errorData = {};
|
|
217
|
+
try {
|
|
218
|
+
errorData = JSON.parse(errorBody);
|
|
219
|
+
} catch {
|
|
220
|
+
}
|
|
221
|
+
const error = new ApiError(
|
|
222
|
+
errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`,
|
|
223
|
+
response.status,
|
|
224
|
+
errorData.error?.code
|
|
225
|
+
);
|
|
226
|
+
if (this.failSilently) {
|
|
227
|
+
console.warn(`Sentrial: Request failed (${method} ${url}):`, error.message);
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
return await response.json();
|
|
233
|
+
} catch (error) {
|
|
234
|
+
if (error instanceof SentrialError) {
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
const networkError = new NetworkError(
|
|
238
|
+
error instanceof Error ? error.message : "Unknown network error",
|
|
239
|
+
error instanceof Error ? error : void 0
|
|
240
|
+
);
|
|
241
|
+
if (this.failSilently) {
|
|
242
|
+
console.warn(`Sentrial: Request failed (${method} ${url}):`, networkError.message);
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
throw networkError;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Create a new session
|
|
250
|
+
*
|
|
251
|
+
* @param params - Session creation parameters
|
|
252
|
+
* @returns Session ID, or null if the request failed and failSilently is true
|
|
253
|
+
*/
|
|
254
|
+
async createSession(params) {
|
|
255
|
+
this.currentState = {};
|
|
256
|
+
const payload = {
|
|
257
|
+
name: params.name,
|
|
258
|
+
agentName: params.agentName,
|
|
259
|
+
userId: params.userId,
|
|
260
|
+
metadata: params.metadata
|
|
261
|
+
};
|
|
262
|
+
const response = await this.safeRequest(
|
|
263
|
+
"POST",
|
|
264
|
+
`${this.apiUrl}/api/sdk/sessions`,
|
|
265
|
+
payload
|
|
266
|
+
);
|
|
267
|
+
return response?.id ?? null;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Track a tool call event
|
|
271
|
+
*
|
|
272
|
+
* @param params - Tool call parameters
|
|
273
|
+
* @returns Event data
|
|
274
|
+
*/
|
|
275
|
+
async trackToolCall(params) {
|
|
276
|
+
const stateBefore = { ...this.currentState };
|
|
277
|
+
this.currentState[`${params.toolName}_result`] = params.toolOutput;
|
|
278
|
+
const payload = {
|
|
279
|
+
sessionId: params.sessionId,
|
|
280
|
+
eventType: "tool_call",
|
|
281
|
+
toolName: params.toolName,
|
|
282
|
+
toolInput: params.toolInput,
|
|
283
|
+
toolOutput: params.toolOutput,
|
|
284
|
+
reasoning: params.reasoning,
|
|
285
|
+
stateBefore,
|
|
286
|
+
stateAfter: { ...this.currentState },
|
|
287
|
+
estimatedCost: params.estimatedCost ?? 0
|
|
288
|
+
};
|
|
289
|
+
if (params.toolError !== void 0) payload.toolError = params.toolError;
|
|
290
|
+
if (params.tokenCount !== void 0) payload.tokenCount = params.tokenCount;
|
|
291
|
+
if (params.traceId !== void 0) payload.traceId = params.traceId;
|
|
292
|
+
if (params.spanId !== void 0) payload.spanId = params.spanId;
|
|
293
|
+
if (params.metadata !== void 0) payload.metadata = params.metadata;
|
|
294
|
+
return this.safeRequest("POST", `${this.apiUrl}/api/sdk/events`, payload);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Track an LLM decision event
|
|
298
|
+
*
|
|
299
|
+
* @param params - Decision parameters
|
|
300
|
+
* @returns Event data
|
|
301
|
+
*/
|
|
302
|
+
async trackDecision(params) {
|
|
303
|
+
const stateBefore = { ...this.currentState };
|
|
304
|
+
const payload = {
|
|
305
|
+
sessionId: params.sessionId,
|
|
306
|
+
eventType: "llm_decision",
|
|
307
|
+
reasoning: params.reasoning,
|
|
308
|
+
alternativesConsidered: params.alternatives,
|
|
309
|
+
confidence: params.confidence,
|
|
310
|
+
stateBefore,
|
|
311
|
+
stateAfter: { ...this.currentState },
|
|
312
|
+
estimatedCost: params.estimatedCost ?? 0
|
|
313
|
+
};
|
|
314
|
+
if (params.tokenCount !== void 0) payload.tokenCount = params.tokenCount;
|
|
315
|
+
if (params.traceId !== void 0) payload.traceId = params.traceId;
|
|
316
|
+
if (params.spanId !== void 0) payload.spanId = params.spanId;
|
|
317
|
+
if (params.metadata !== void 0) payload.metadata = params.metadata;
|
|
318
|
+
return this.safeRequest("POST", `${this.apiUrl}/api/sdk/events`, payload);
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Track an error event
|
|
322
|
+
*
|
|
323
|
+
* @param params - Error parameters
|
|
324
|
+
* @returns Event data
|
|
325
|
+
*/
|
|
326
|
+
async trackError(params) {
|
|
327
|
+
const stateBefore = { ...this.currentState };
|
|
328
|
+
const toolError = {
|
|
329
|
+
message: params.errorMessage
|
|
330
|
+
};
|
|
331
|
+
if (params.errorType) toolError.type = params.errorType;
|
|
332
|
+
if (params.stackTrace) toolError.stack_trace = params.stackTrace;
|
|
333
|
+
const payload = {
|
|
334
|
+
sessionId: params.sessionId,
|
|
335
|
+
eventType: "error",
|
|
336
|
+
toolError,
|
|
337
|
+
stateBefore,
|
|
338
|
+
stateAfter: { ...this.currentState }
|
|
339
|
+
};
|
|
340
|
+
if (params.toolName !== void 0) payload.toolName = params.toolName;
|
|
341
|
+
if (params.traceId !== void 0) payload.traceId = params.traceId;
|
|
342
|
+
if (params.spanId !== void 0) payload.spanId = params.spanId;
|
|
343
|
+
if (params.metadata !== void 0) payload.metadata = params.metadata;
|
|
344
|
+
return this.safeRequest("POST", `${this.apiUrl}/api/sdk/events`, payload);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Update the current state
|
|
348
|
+
*
|
|
349
|
+
* @param key - State key
|
|
350
|
+
* @param value - State value
|
|
351
|
+
*/
|
|
352
|
+
updateState(key, value) {
|
|
353
|
+
this.currentState[key] = value;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Complete a session with performance metrics
|
|
357
|
+
*
|
|
358
|
+
* This is the recommended way to close sessions for performance monitoring.
|
|
359
|
+
*
|
|
360
|
+
* @param params - Session completion parameters
|
|
361
|
+
* @returns Updated session data
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```ts
|
|
365
|
+
* await client.completeSession({
|
|
366
|
+
* sessionId,
|
|
367
|
+
* success: true,
|
|
368
|
+
* estimatedCost: 0.023,
|
|
369
|
+
* promptTokens: 1500,
|
|
370
|
+
* completionTokens: 500,
|
|
371
|
+
* totalTokens: 2000,
|
|
372
|
+
* userInput: "What's the weather in San Francisco?",
|
|
373
|
+
* assistantOutput: "The weather in San Francisco is 65°F and sunny.",
|
|
374
|
+
* customMetrics: {
|
|
375
|
+
* customer_satisfaction: 4.5,
|
|
376
|
+
* order_value: 129.99,
|
|
377
|
+
* },
|
|
378
|
+
* });
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
async completeSession(params) {
|
|
382
|
+
const payload = {
|
|
383
|
+
status: params.success !== false ? "completed" : "failed",
|
|
384
|
+
success: params.success ?? true
|
|
385
|
+
};
|
|
386
|
+
if (params.failureReason !== void 0) payload.failureReason = params.failureReason;
|
|
387
|
+
if (params.estimatedCost !== void 0) payload.estimatedCost = params.estimatedCost;
|
|
388
|
+
if (params.customMetrics !== void 0) payload.customMetrics = params.customMetrics;
|
|
389
|
+
if (params.durationMs !== void 0) payload.durationMs = params.durationMs;
|
|
390
|
+
if (params.promptTokens !== void 0) payload.promptTokens = params.promptTokens;
|
|
391
|
+
if (params.completionTokens !== void 0) payload.completionTokens = params.completionTokens;
|
|
392
|
+
if (params.totalTokens !== void 0) payload.totalTokens = params.totalTokens;
|
|
393
|
+
if (params.userInput !== void 0) payload.userInput = params.userInput;
|
|
394
|
+
if (params.assistantOutput !== void 0) payload.assistantOutput = params.assistantOutput;
|
|
395
|
+
return this.safeRequest(
|
|
396
|
+
"PATCH",
|
|
397
|
+
`${this.apiUrl}/api/sdk/sessions/${params.sessionId}`,
|
|
398
|
+
payload
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Begin tracking an interaction (simplified API)
|
|
403
|
+
*
|
|
404
|
+
* @param params - Interaction parameters
|
|
405
|
+
* @returns Interaction object with finish() method
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* ```ts
|
|
409
|
+
* const interaction = await client.begin({
|
|
410
|
+
* userId: 'user_123',
|
|
411
|
+
* event: 'chat_message',
|
|
412
|
+
* input: message,
|
|
413
|
+
* convoId: 'convo_456',
|
|
414
|
+
* });
|
|
415
|
+
*
|
|
416
|
+
* // ... do your agent work ...
|
|
417
|
+
*
|
|
418
|
+
* await interaction.finish({ output: responseText });
|
|
419
|
+
* ```
|
|
420
|
+
*/
|
|
421
|
+
async begin(params) {
|
|
422
|
+
const eventId = params.eventId ?? crypto.randomUUID();
|
|
423
|
+
const fullMetadata = params.metadata ? { ...params.metadata } : {};
|
|
424
|
+
if (params.input) fullMetadata.input = params.input;
|
|
425
|
+
if (params.convoId) fullMetadata.convo_id = params.convoId;
|
|
426
|
+
fullMetadata.event_id = eventId;
|
|
427
|
+
const sessionId = await this.createSession({
|
|
428
|
+
name: `${params.event}:${eventId.slice(0, 8)}`,
|
|
429
|
+
agentName: params.event,
|
|
430
|
+
userId: params.userId,
|
|
431
|
+
metadata: fullMetadata
|
|
432
|
+
});
|
|
433
|
+
if (params.input) {
|
|
434
|
+
this.currentState.input = params.input;
|
|
435
|
+
}
|
|
436
|
+
return new Interaction({
|
|
437
|
+
client: this,
|
|
438
|
+
sessionId,
|
|
439
|
+
eventId,
|
|
440
|
+
userId: params.userId,
|
|
441
|
+
event: params.event
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
// Cost calculation static methods for convenience
|
|
445
|
+
static calculateOpenAICost = calculateOpenAICost;
|
|
446
|
+
static calculateAnthropicCost = calculateAnthropicCost;
|
|
447
|
+
static calculateGoogleCost = calculateGoogleCost;
|
|
448
|
+
};
|
|
449
|
+
var Interaction = class {
|
|
450
|
+
client;
|
|
451
|
+
sessionId;
|
|
452
|
+
/** Event ID for this interaction */
|
|
453
|
+
eventId;
|
|
454
|
+
/** User ID for this interaction */
|
|
455
|
+
userId;
|
|
456
|
+
/** Event name for this interaction */
|
|
457
|
+
event;
|
|
458
|
+
finished = false;
|
|
459
|
+
success = true;
|
|
460
|
+
failureReason;
|
|
461
|
+
output;
|
|
462
|
+
degraded;
|
|
463
|
+
constructor(config) {
|
|
464
|
+
this.client = config.client;
|
|
465
|
+
this.sessionId = config.sessionId;
|
|
466
|
+
this.eventId = config.eventId;
|
|
467
|
+
this.userId = config.userId;
|
|
468
|
+
this.event = config.event;
|
|
469
|
+
this.degraded = config.sessionId === null;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Set the output for this interaction
|
|
473
|
+
*
|
|
474
|
+
* This will be used when finish() is called.
|
|
475
|
+
* Useful when you want to set the output but call finish() later.
|
|
476
|
+
*
|
|
477
|
+
* @param output - The output/response text
|
|
478
|
+
*/
|
|
479
|
+
setOutput(output) {
|
|
480
|
+
this.output = output;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Finish the interaction and record metrics
|
|
484
|
+
*
|
|
485
|
+
* @param params - Finish parameters
|
|
486
|
+
* @returns Updated session data, or null if degraded/already finished
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```ts
|
|
490
|
+
* await interaction.finish({
|
|
491
|
+
* output: "Here's the answer to your question...",
|
|
492
|
+
* success: true,
|
|
493
|
+
* customMetrics: { satisfaction: 4.5 },
|
|
494
|
+
* });
|
|
495
|
+
* ```
|
|
496
|
+
*/
|
|
497
|
+
async finish(params = {}) {
|
|
498
|
+
if (this.finished) return null;
|
|
499
|
+
if (this.degraded) {
|
|
500
|
+
this.finished = true;
|
|
501
|
+
return null;
|
|
502
|
+
}
|
|
503
|
+
this.finished = true;
|
|
504
|
+
const finalOutput = params.output ?? this.output;
|
|
505
|
+
return this.client.completeSession({
|
|
506
|
+
sessionId: this.sessionId,
|
|
507
|
+
success: params.success ?? this.success,
|
|
508
|
+
failureReason: params.failureReason ?? this.failureReason,
|
|
509
|
+
estimatedCost: params.estimatedCost,
|
|
510
|
+
customMetrics: params.customMetrics,
|
|
511
|
+
promptTokens: params.promptTokens,
|
|
512
|
+
completionTokens: params.completionTokens,
|
|
513
|
+
totalTokens: params.totalTokens,
|
|
514
|
+
assistantOutput: finalOutput
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Track a tool call within this interaction
|
|
519
|
+
*/
|
|
520
|
+
async trackToolCall(params) {
|
|
521
|
+
if (this.degraded) return null;
|
|
522
|
+
return this.client.trackToolCall({
|
|
523
|
+
...params,
|
|
524
|
+
sessionId: this.sessionId
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Track an LLM decision within this interaction
|
|
529
|
+
*/
|
|
530
|
+
async trackDecision(params) {
|
|
531
|
+
if (this.degraded) return null;
|
|
532
|
+
return this.client.trackDecision({
|
|
533
|
+
...params,
|
|
534
|
+
sessionId: this.sessionId
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Track an error within this interaction
|
|
539
|
+
*/
|
|
540
|
+
async trackError(params) {
|
|
541
|
+
this.success = false;
|
|
542
|
+
this.failureReason = params.errorMessage;
|
|
543
|
+
if (this.degraded) return null;
|
|
544
|
+
return this.client.trackError({
|
|
545
|
+
...params,
|
|
546
|
+
sessionId: this.sessionId
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Get the session ID (null if session creation failed)
|
|
551
|
+
*/
|
|
552
|
+
getSessionId() {
|
|
553
|
+
return this.sessionId;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Check if the interaction is in a degraded state (session creation failed)
|
|
557
|
+
*/
|
|
558
|
+
isDegraded() {
|
|
559
|
+
return this.degraded;
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
var defaultClient = null;
|
|
563
|
+
function getClient() {
|
|
564
|
+
if (!defaultClient) {
|
|
565
|
+
defaultClient = new SentrialClient();
|
|
566
|
+
}
|
|
567
|
+
return defaultClient;
|
|
568
|
+
}
|
|
569
|
+
function configure(config) {
|
|
570
|
+
defaultClient = new SentrialClient(config);
|
|
571
|
+
}
|
|
572
|
+
function begin(params) {
|
|
573
|
+
return getClient().begin(params);
|
|
574
|
+
}
|
|
575
|
+
var sentrial = {
|
|
576
|
+
configure,
|
|
577
|
+
begin
|
|
578
|
+
};
|
|
579
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
580
|
+
0 && (module.exports = {
|
|
581
|
+
ApiError,
|
|
582
|
+
EventType,
|
|
583
|
+
Interaction,
|
|
584
|
+
NetworkError,
|
|
585
|
+
SentrialClient,
|
|
586
|
+
SentrialError,
|
|
587
|
+
ValidationError,
|
|
588
|
+
begin,
|
|
589
|
+
calculateAnthropicCost,
|
|
590
|
+
calculateGoogleCost,
|
|
591
|
+
calculateOpenAICost,
|
|
592
|
+
configure,
|
|
593
|
+
sentrial
|
|
594
|
+
});
|
|
595
|
+
//# sourceMappingURL=index.cjs.map
|