@laikatest/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 ADDED
@@ -0,0 +1,285 @@
1
+ # @laikatest/sdk
2
+
3
+ Unified LaikaTest SDK for tracing and A/B testing. Single initialization for both observability and experiments.
4
+
5
+ ## Why This Package?
6
+
7
+ **Before** - confusing dual initialization:
8
+ ```typescript
9
+ import { initLaika } from '@laikatest/auto-otel';
10
+ import { LaikaTest } from '@laikatest/js-client';
11
+
12
+ initLaika({ apiKey: 'key', serviceName: 'app' }); // Tracing
13
+ const client = new LaikaTest('key'); // Same key again?
14
+ ```
15
+
16
+ **After** - single unified init:
17
+ ```typescript
18
+ import { Laika } from '@laikatest/sdk';
19
+
20
+ const laika = Laika.init({
21
+ apiKey: 'key',
22
+ serviceName: 'app',
23
+ });
24
+ // Both tracing AND experiments enabled by default
25
+ ```
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ npm install @laikatest/sdk
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ```typescript
36
+ import { Laika, setSessionId } from '@laikatest/sdk';
37
+
38
+ // Initialize once - enables both tracing and experiments
39
+ const laika = Laika.init({
40
+ apiKey: process.env.LAIKA_API_KEY,
41
+ serviceName: 'my-app',
42
+ });
43
+
44
+ // Set context for multi-turn conversations
45
+ setSessionId('conversation-123');
46
+
47
+ // Get A/B tested prompt
48
+ const prompt = await laika.getExperimentPrompt('my-experiment', {
49
+ userId: 'user-123',
50
+ });
51
+
52
+ // Make LLM call (automatically traced with experiment context)
53
+ const response = await openai.chat.completions.create({
54
+ model: 'gpt-4',
55
+ messages: [{ role: 'user', content: prompt.getContent() }],
56
+ });
57
+
58
+ // Track outcome score
59
+ await prompt.pushScore(
60
+ [{ name: 'rating', type: 'int', value: 5 }],
61
+ { userId: 'user-123' }
62
+ );
63
+
64
+ // Cleanup before exit
65
+ await laika.shutdown();
66
+ ```
67
+
68
+ ## Configuration
69
+
70
+ ```typescript
71
+ interface LaikaConfig {
72
+ // Required
73
+ apiKey: string; // Your LaikaTest API key
74
+ serviceName: string; // Service name for traces
75
+
76
+ // Feature toggles (both default: true)
77
+ tracing?: boolean; // Enable OpenTelemetry tracing
78
+ experiments?: boolean; // Enable A/B testing client
79
+
80
+ // Tracing options (passed to @laikatest/auto-otel)
81
+ endpoint?: string; // OTLP endpoint (default: https://api.laikatest.com/otel/v1/traces)
82
+ captureContent?: boolean; // Capture prompt/response content (default: false)
83
+ debug?: boolean; // Enable debug logging
84
+
85
+ // Shared context
86
+ sessionId?: string; // Static session ID
87
+ getSessionId?: () => string; // Dynamic session ID getter
88
+ userId?: string; // Static user ID
89
+ getUserId?: () => string; // Dynamic user ID getter
90
+ defaultProperties?: Record<string, string | number | boolean>;
91
+
92
+ // Client options (passed to @laikatest/js-client)
93
+ baseUrl?: string; // API base URL (default: https://api.laikatest.com)
94
+ timeout?: number; // Request timeout ms (default: 10000)
95
+ cacheEnabled?: boolean; // Enable prompt caching (default: true)
96
+ cacheTTL?: number; // Cache TTL ms (default: 30 minutes)
97
+ }
98
+ ```
99
+
100
+ ## Feature Toggles
101
+
102
+ Enable only what you need:
103
+
104
+ ```typescript
105
+ // Tracing only (observability without experiments)
106
+ const laika = Laika.init({
107
+ apiKey: 'key',
108
+ serviceName: 'app',
109
+ experiments: false,
110
+ });
111
+
112
+ // Experiments only (A/B testing without tracing)
113
+ const laika = Laika.init({
114
+ apiKey: 'key',
115
+ serviceName: 'app',
116
+ tracing: false,
117
+ });
118
+
119
+ // Check what's enabled
120
+ laika.isTracingEnabled(); // true/false
121
+ laika.isExperimentsEnabled(); // true/false
122
+ ```
123
+
124
+ ## Context Management
125
+
126
+ All context functions are re-exported from `@laikatest/auto-otel`:
127
+
128
+ ```typescript
129
+ import {
130
+ // Session tracking (multi-turn conversations)
131
+ setSessionId,
132
+ getSessionId,
133
+ clearSessionId,
134
+
135
+ // User tracking (per-user analytics)
136
+ setUserId,
137
+ getUserId,
138
+ clearUserId,
139
+
140
+ // Custom properties (filtering/segmentation)
141
+ setProperty,
142
+ setProperties,
143
+ getProperties,
144
+ clearProperties,
145
+ removeProperty,
146
+ } from '@laikatest/sdk';
147
+
148
+ // Example: Set context for a chat session
149
+ setSessionId('conversation-123');
150
+ setUserId('user-456');
151
+ setProperties({
152
+ environment: 'production',
153
+ feature: 'checkout',
154
+ tier: 'enterprise',
155
+ });
156
+ ```
157
+
158
+ ## API Reference
159
+
160
+ ### Laika Class
161
+
162
+ | Method | Description |
163
+ |--------|-------------|
164
+ | `Laika.init(config)` | Initialize SDK (static factory) |
165
+ | `laika.getPrompt(name, options?)` | Fetch prompt by name |
166
+ | `laika.getExperimentPrompt(title, context?)` | Get A/B tested prompt |
167
+ | `laika.shutdown()` | Cleanup resources |
168
+ | `laika.isTracingEnabled()` | Check if tracing is on |
169
+ | `laika.isExperimentsEnabled()` | Check if experiments is on |
170
+
171
+ ### Re-exported from @laikatest/js-client
172
+
173
+ | Export | Description |
174
+ |--------|-------------|
175
+ | `Prompt` | Prompt class with `getContent()`, `pushScore()` |
176
+ | `LaikaServiceError` | API error (4xx/5xx) |
177
+ | `NetworkError` | Network/timeout error |
178
+ | `ValidationError` | Input validation error |
179
+ | `AuthenticationError` | Auth failure error |
180
+
181
+ ### Re-exported Types
182
+
183
+ ```typescript
184
+ import type {
185
+ PromptContent,
186
+ ScoreInput,
187
+ ScoreType,
188
+ PushScoreOptions,
189
+ PushScoreResponse,
190
+ ClientOptions,
191
+ GetPromptOptions,
192
+ } from '@laikatest/sdk';
193
+ ```
194
+
195
+ ## Integration Patterns
196
+
197
+ ### Multi-Turn Chatbot
198
+
199
+ ```typescript
200
+ import { Laika, setSessionId, setUserId } from '@laikatest/sdk';
201
+
202
+ const laika = Laika.init({
203
+ apiKey: process.env.LAIKA_API_KEY,
204
+ serviceName: 'chatbot',
205
+ });
206
+
207
+ async function handleMessage(userId: string, conversationId: string, message: string) {
208
+ // Set context (appears in all traces)
209
+ setSessionId(conversationId);
210
+ setUserId(userId);
211
+
212
+ // Get experiment prompt
213
+ const prompt = await laika.getExperimentPrompt('system-prompt-v2', { userId });
214
+
215
+ // Call LLM (auto-traced with session, user, experiment context)
216
+ const response = await openai.chat.completions.create({
217
+ model: 'gpt-4',
218
+ messages: [
219
+ { role: 'system', content: prompt.getContent() },
220
+ { role: 'user', content: message },
221
+ ],
222
+ });
223
+
224
+ return response.choices[0].message.content;
225
+ }
226
+ ```
227
+
228
+ ### Express.js Middleware
229
+
230
+ ```typescript
231
+ import { Laika, setSessionId, setUserId, setProperty } from '@laikatest/sdk';
232
+
233
+ const laika = Laika.init({
234
+ apiKey: process.env.LAIKA_API_KEY,
235
+ serviceName: 'api-server',
236
+ });
237
+
238
+ // Middleware to set context per request
239
+ app.use((req, res, next) => {
240
+ if (req.headers['x-session-id']) {
241
+ setSessionId(req.headers['x-session-id']);
242
+ }
243
+ if (req.user?.id) {
244
+ setUserId(req.user.id);
245
+ }
246
+ setProperty('endpoint', req.path);
247
+ next();
248
+ });
249
+ ```
250
+
251
+ ## Migration from Separate Packages
252
+
253
+ ### Before (Two Packages)
254
+
255
+ ```typescript
256
+ import { initLaika, setSessionId } from '@laikatest/auto-otel';
257
+ import { LaikaTest } from '@laikatest/js-client';
258
+
259
+ initLaika({ apiKey: 'key', serviceName: 'app' });
260
+ const client = new LaikaTest('key');
261
+
262
+ setSessionId('conv-123');
263
+ const prompt = await client.getExperimentPrompt('exp', { userId: 'u1' });
264
+ ```
265
+
266
+ ### After (Unified SDK)
267
+
268
+ ```typescript
269
+ import { Laika, setSessionId } from '@laikatest/sdk';
270
+
271
+ const laika = Laika.init({ apiKey: 'key', serviceName: 'app' });
272
+
273
+ setSessionId('conv-123');
274
+ const prompt = await laika.getExperimentPrompt('exp', { userId: 'u1' });
275
+ ```
276
+
277
+ ## Backward Compatibility
278
+
279
+ - `@laikatest/auto-otel` continues to work standalone
280
+ - `@laikatest/js-client` continues to work standalone
281
+ - Migrate to `@laikatest/sdk` at your own pace
282
+
283
+ ## License
284
+
285
+ MIT
@@ -0,0 +1,5 @@
1
+ export { Laika } from './laika';
2
+ export { LaikaConfig } from './types';
3
+ export { setSessionId, getSessionId, clearSessionId, setUserId, getUserId, clearUserId, runWithContext, runWithContextAsync, setProperty, setProperties, getProperties, clearProperties, removeProperty, runWithProperties, runWithPropertiesAsync, shutdown, } from '@laikatest/auto-otel';
4
+ export { Prompt, LaikaServiceError, NetworkError, ValidationError, AuthenticationError, } from '@laikatest/js-client';
5
+ export type { PromptContent, ScoreInput, ScoreType, ScoreSource, PushScoreOptions, PushScoreResponse, ClientOptions, GetPromptOptions, } from '@laikatest/js-client';
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AuthenticationError = exports.ValidationError = exports.NetworkError = exports.LaikaServiceError = exports.Prompt = exports.shutdown = exports.runWithPropertiesAsync = exports.runWithProperties = exports.removeProperty = exports.clearProperties = exports.getProperties = exports.setProperties = exports.setProperty = exports.runWithContextAsync = exports.runWithContext = exports.clearUserId = exports.getUserId = exports.setUserId = exports.clearSessionId = exports.getSessionId = exports.setSessionId = exports.Laika = void 0;
4
+ // Main class
5
+ var laika_1 = require("./laika");
6
+ Object.defineProperty(exports, "Laika", { enumerable: true, get: function () { return laika_1.Laika; } });
7
+ // Re-export from auto-otel for convenience
8
+ var auto_otel_1 = require("@laikatest/auto-otel");
9
+ Object.defineProperty(exports, "setSessionId", { enumerable: true, get: function () { return auto_otel_1.setSessionId; } });
10
+ Object.defineProperty(exports, "getSessionId", { enumerable: true, get: function () { return auto_otel_1.getSessionId; } });
11
+ Object.defineProperty(exports, "clearSessionId", { enumerable: true, get: function () { return auto_otel_1.clearSessionId; } });
12
+ Object.defineProperty(exports, "setUserId", { enumerable: true, get: function () { return auto_otel_1.setUserId; } });
13
+ Object.defineProperty(exports, "getUserId", { enumerable: true, get: function () { return auto_otel_1.getUserId; } });
14
+ Object.defineProperty(exports, "clearUserId", { enumerable: true, get: function () { return auto_otel_1.clearUserId; } });
15
+ Object.defineProperty(exports, "runWithContext", { enumerable: true, get: function () { return auto_otel_1.runWithContext; } });
16
+ Object.defineProperty(exports, "runWithContextAsync", { enumerable: true, get: function () { return auto_otel_1.runWithContextAsync; } });
17
+ Object.defineProperty(exports, "setProperty", { enumerable: true, get: function () { return auto_otel_1.setProperty; } });
18
+ Object.defineProperty(exports, "setProperties", { enumerable: true, get: function () { return auto_otel_1.setProperties; } });
19
+ Object.defineProperty(exports, "getProperties", { enumerable: true, get: function () { return auto_otel_1.getProperties; } });
20
+ Object.defineProperty(exports, "clearProperties", { enumerable: true, get: function () { return auto_otel_1.clearProperties; } });
21
+ Object.defineProperty(exports, "removeProperty", { enumerable: true, get: function () { return auto_otel_1.removeProperty; } });
22
+ Object.defineProperty(exports, "runWithProperties", { enumerable: true, get: function () { return auto_otel_1.runWithProperties; } });
23
+ Object.defineProperty(exports, "runWithPropertiesAsync", { enumerable: true, get: function () { return auto_otel_1.runWithPropertiesAsync; } });
24
+ Object.defineProperty(exports, "shutdown", { enumerable: true, get: function () { return auto_otel_1.shutdown; } });
25
+ // Re-export from client for convenience
26
+ var js_client_1 = require("@laikatest/js-client");
27
+ Object.defineProperty(exports, "Prompt", { enumerable: true, get: function () { return js_client_1.Prompt; } });
28
+ Object.defineProperty(exports, "LaikaServiceError", { enumerable: true, get: function () { return js_client_1.LaikaServiceError; } });
29
+ Object.defineProperty(exports, "NetworkError", { enumerable: true, get: function () { return js_client_1.NetworkError; } });
30
+ Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return js_client_1.ValidationError; } });
31
+ Object.defineProperty(exports, "AuthenticationError", { enumerable: true, get: function () { return js_client_1.AuthenticationError; } });
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsYUFBYTtBQUNiLGlDQUFnQztBQUF2Qiw4RkFBQSxLQUFLLE9BQUE7QUFHZCwyQ0FBMkM7QUFDM0Msa0RBaUI4QjtBQWhCNUIseUdBQUEsWUFBWSxPQUFBO0FBQ1oseUdBQUEsWUFBWSxPQUFBO0FBQ1osMkdBQUEsY0FBYyxPQUFBO0FBQ2Qsc0dBQUEsU0FBUyxPQUFBO0FBQ1Qsc0dBQUEsU0FBUyxPQUFBO0FBQ1Qsd0dBQUEsV0FBVyxPQUFBO0FBQ1gsMkdBQUEsY0FBYyxPQUFBO0FBQ2QsZ0hBQUEsbUJBQW1CLE9BQUE7QUFDbkIsd0dBQUEsV0FBVyxPQUFBO0FBQ1gsMEdBQUEsYUFBYSxPQUFBO0FBQ2IsMEdBQUEsYUFBYSxPQUFBO0FBQ2IsNEdBQUEsZUFBZSxPQUFBO0FBQ2YsMkdBQUEsY0FBYyxPQUFBO0FBQ2QsOEdBQUEsaUJBQWlCLE9BQUE7QUFDakIsbUhBQUEsc0JBQXNCLE9BQUE7QUFDdEIscUdBQUEsUUFBUSxPQUFBO0FBR1Ysd0NBQXdDO0FBQ3hDLGtEQU04QjtBQUw1QixtR0FBQSxNQUFNLE9BQUE7QUFDTiw4R0FBQSxpQkFBaUIsT0FBQTtBQUNqQix5R0FBQSxZQUFZLE9BQUE7QUFDWiw0R0FBQSxlQUFlLE9BQUE7QUFDZixnSEFBQSxtQkFBbUIsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIE1haW4gY2xhc3NcbmV4cG9ydCB7IExhaWthIH0gZnJvbSAnLi9sYWlrYSc7XG5leHBvcnQgeyBMYWlrYUNvbmZpZyB9IGZyb20gJy4vdHlwZXMnO1xuXG4vLyBSZS1leHBvcnQgZnJvbSBhdXRvLW90ZWwgZm9yIGNvbnZlbmllbmNlXG5leHBvcnQge1xuICBzZXRTZXNzaW9uSWQsXG4gIGdldFNlc3Npb25JZCxcbiAgY2xlYXJTZXNzaW9uSWQsXG4gIHNldFVzZXJJZCxcbiAgZ2V0VXNlcklkLFxuICBjbGVhclVzZXJJZCxcbiAgcnVuV2l0aENvbnRleHQsXG4gIHJ1bldpdGhDb250ZXh0QXN5bmMsXG4gIHNldFByb3BlcnR5LFxuICBzZXRQcm9wZXJ0aWVzLFxuICBnZXRQcm9wZXJ0aWVzLFxuICBjbGVhclByb3BlcnRpZXMsXG4gIHJlbW92ZVByb3BlcnR5LFxuICBydW5XaXRoUHJvcGVydGllcyxcbiAgcnVuV2l0aFByb3BlcnRpZXNBc3luYyxcbiAgc2h1dGRvd24sXG59IGZyb20gJ0BsYWlrYXRlc3QvYXV0by1vdGVsJztcblxuLy8gUmUtZXhwb3J0IGZyb20gY2xpZW50IGZvciBjb252ZW5pZW5jZVxuZXhwb3J0IHtcbiAgUHJvbXB0LFxuICBMYWlrYVNlcnZpY2VFcnJvcixcbiAgTmV0d29ya0Vycm9yLFxuICBWYWxpZGF0aW9uRXJyb3IsXG4gIEF1dGhlbnRpY2F0aW9uRXJyb3IsXG59IGZyb20gJ0BsYWlrYXRlc3QvanMtY2xpZW50JztcblxuLy8gUmUtZXhwb3J0IHR5cGVzIGZyb20gY2xpZW50XG5leHBvcnQgdHlwZSB7XG4gIFByb21wdENvbnRlbnQsXG4gIFNjb3JlSW5wdXQsXG4gIFNjb3JlVHlwZSxcbiAgU2NvcmVTb3VyY2UsXG4gIFB1c2hTY29yZU9wdGlvbnMsXG4gIFB1c2hTY29yZVJlc3BvbnNlLFxuICBDbGllbnRPcHRpb25zLFxuICBHZXRQcm9tcHRPcHRpb25zLFxufSBmcm9tICdAbGFpa2F0ZXN0L2pzLWNsaWVudCc7XG4iXX0=
@@ -0,0 +1,49 @@
1
+ import { Prompt, GetPromptOptions } from '@laikatest/js-client';
2
+ import { LaikaConfig } from './types';
3
+ /**
4
+ * Unified LaikaTest SDK for tracing and experiments.
5
+ * Provides a single entry point for both observability and A/B testing.
6
+ */
7
+ export declare class Laika {
8
+ private client;
9
+ private tracingEnabled;
10
+ private constructor();
11
+ /**
12
+ * Initialize LaikaTest with unified configuration.
13
+ * Enables both tracing and experiments by default.
14
+ * @throws {Error} If apiKey or serviceName is missing/invalid
15
+ * @throws {Error} If OpenTelemetry SDK fails to start
16
+ */
17
+ static init(config: LaikaConfig): Laika;
18
+ /**
19
+ * Fetch prompt content by name.
20
+ * Requires experiments to be enabled.
21
+ * @throws {Error} If experiments are not enabled
22
+ * @throws {ValidationError} If prompt name is invalid
23
+ * @throws {AuthenticationError} If API key is invalid
24
+ * @throws {LaikaServiceError} If API returns an error
25
+ * @throws {NetworkError} If network request fails
26
+ */
27
+ getPrompt<C = unknown>(promptName: string, options?: GetPromptOptions): Promise<Prompt<C>>;
28
+ /**
29
+ * Get experiment prompt with automatic bucketing.
30
+ * Requires experiments to be enabled.
31
+ * @throws {Error} If experiments are not enabled
32
+ * @throws {ValidationError} If experiment title or context is invalid
33
+ * @throws {AuthenticationError} If API key is invalid
34
+ * @throws {LaikaServiceError} If API returns an error
35
+ * @throws {NetworkError} If network request fails
36
+ */
37
+ getExperimentPrompt<C = unknown>(experimentTitle: string, context?: Record<string, unknown>): Promise<Prompt<C>>;
38
+ /** Returns true if tracing is enabled. */
39
+ isTracingEnabled(): boolean;
40
+ /** Returns true if experiments client is enabled. */
41
+ isExperimentsEnabled(): boolean;
42
+ /**
43
+ * Shutdown both tracing and client resources.
44
+ * Call this before process exit for clean shutdown.
45
+ */
46
+ shutdown(): Promise<void>;
47
+ /** Throws if experiments not enabled. */
48
+ private ensureClient;
49
+ }
package/dist/laika.js ADDED
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Laika = void 0;
4
+ const auto_otel_1 = require("@laikatest/auto-otel");
5
+ const js_client_1 = require("@laikatest/js-client");
6
+ /**
7
+ * Unified LaikaTest SDK for tracing and experiments.
8
+ * Provides a single entry point for both observability and A/B testing.
9
+ */
10
+ class Laika {
11
+ constructor() {
12
+ this.client = null;
13
+ this.tracingEnabled = false;
14
+ }
15
+ /**
16
+ * Initialize LaikaTest with unified configuration.
17
+ * Enables both tracing and experiments by default.
18
+ * @throws {Error} If apiKey or serviceName is missing/invalid
19
+ * @throws {Error} If OpenTelemetry SDK fails to start
20
+ */
21
+ static init(config) {
22
+ const instance = new Laika();
23
+ try {
24
+ // Initialize tracing (if enabled, default: true)
25
+ if (config.tracing !== false) {
26
+ (0, auto_otel_1.initLaika)({
27
+ apiKey: config.apiKey,
28
+ serviceName: config.serviceName,
29
+ endpoint: config.endpoint,
30
+ captureContent: config.captureContent,
31
+ debug: config.debug,
32
+ sessionId: config.sessionId,
33
+ getSessionId: config.getSessionId,
34
+ userId: config.userId,
35
+ getUserId: config.getUserId,
36
+ defaultProperties: config.defaultProperties,
37
+ });
38
+ instance.tracingEnabled = true;
39
+ }
40
+ // Initialize experiments client (if enabled, default: true)
41
+ if (config.experiments !== false) {
42
+ instance.client = new js_client_1.LaikaTest(config.apiKey, {
43
+ baseUrl: config.baseUrl,
44
+ timeout: config.timeout,
45
+ cacheEnabled: config.cacheEnabled,
46
+ cacheTTL: config.cacheTTL,
47
+ });
48
+ }
49
+ return instance;
50
+ }
51
+ catch (error) {
52
+ // Cleanup any partial initialization
53
+ if (instance.tracingEnabled) {
54
+ (0, auto_otel_1.shutdown)().catch(() => { });
55
+ }
56
+ throw error;
57
+ }
58
+ }
59
+ /**
60
+ * Fetch prompt content by name.
61
+ * Requires experiments to be enabled.
62
+ * @throws {Error} If experiments are not enabled
63
+ * @throws {ValidationError} If prompt name is invalid
64
+ * @throws {AuthenticationError} If API key is invalid
65
+ * @throws {LaikaServiceError} If API returns an error
66
+ * @throws {NetworkError} If network request fails
67
+ */
68
+ async getPrompt(promptName, options) {
69
+ this.ensureClient();
70
+ return this.client.getPrompt(promptName, options);
71
+ }
72
+ /**
73
+ * Get experiment prompt with automatic bucketing.
74
+ * Requires experiments to be enabled.
75
+ * @throws {Error} If experiments are not enabled
76
+ * @throws {ValidationError} If experiment title or context is invalid
77
+ * @throws {AuthenticationError} If API key is invalid
78
+ * @throws {LaikaServiceError} If API returns an error
79
+ * @throws {NetworkError} If network request fails
80
+ */
81
+ async getExperimentPrompt(experimentTitle, context) {
82
+ this.ensureClient();
83
+ return this.client.getExperimentPrompt(experimentTitle, context);
84
+ }
85
+ /** Returns true if tracing is enabled. */
86
+ isTracingEnabled() {
87
+ return this.tracingEnabled;
88
+ }
89
+ /** Returns true if experiments client is enabled. */
90
+ isExperimentsEnabled() {
91
+ return this.client !== null;
92
+ }
93
+ /**
94
+ * Shutdown both tracing and client resources.
95
+ * Call this before process exit for clean shutdown.
96
+ */
97
+ async shutdown() {
98
+ const errors = [];
99
+ if (this.tracingEnabled) {
100
+ try {
101
+ await (0, auto_otel_1.shutdown)();
102
+ }
103
+ catch (error) {
104
+ errors.push(error);
105
+ }
106
+ }
107
+ if (this.client) {
108
+ try {
109
+ this.client.destroy();
110
+ }
111
+ catch (error) {
112
+ errors.push(error);
113
+ }
114
+ }
115
+ if (errors.length > 0) {
116
+ console.error('[Laika] Errors during shutdown:', errors);
117
+ }
118
+ }
119
+ /** Throws if experiments not enabled. */
120
+ ensureClient() {
121
+ if (!this.client) {
122
+ throw new Error('Experiments not enabled. Set experiments: true in config.');
123
+ }
124
+ }
125
+ }
126
+ exports.Laika = Laika;
127
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGFpa2EuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbGFpa2EudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsb0RBQTJEO0FBQzNELG9EQUEyRTtBQUczRTs7O0dBR0c7QUFDSCxNQUFhLEtBQUs7SUFJaEI7UUFIUSxXQUFNLEdBQXFCLElBQUksQ0FBQztRQUNoQyxtQkFBYyxHQUFZLEtBQUssQ0FBQztJQUVqQixDQUFDO0lBRXhCOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFtQjtRQUM3QixNQUFNLFFBQVEsR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBRTdCLElBQUksQ0FBQztZQUNILGlEQUFpRDtZQUNqRCxJQUFJLE1BQU0sQ0FBQyxPQUFPLEtBQUssS0FBSyxFQUFFLENBQUM7Z0JBQzdCLElBQUEscUJBQVMsRUFBQztvQkFDUixNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU07b0JBQ3JCLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVztvQkFDL0IsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRO29CQUN6QixjQUFjLEVBQUUsTUFBTSxDQUFDLGNBQWM7b0JBQ3JDLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztvQkFDbkIsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTO29CQUMzQixZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVk7b0JBQ2pDLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTTtvQkFDckIsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTO29CQUMzQixpQkFBaUIsRUFBRSxNQUFNLENBQUMsaUJBQWlCO2lCQUM1QyxDQUFDLENBQUM7Z0JBQ0gsUUFBUSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDakMsQ0FBQztZQUVELDREQUE0RDtZQUM1RCxJQUFJLE1BQU0sQ0FBQyxXQUFXLEtBQUssS0FBSyxFQUFFLENBQUM7Z0JBQ2pDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsSUFBSSxxQkFBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7b0JBQzdDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztvQkFDdkIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO29CQUN2QixZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVk7b0JBQ2pDLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtpQkFDMUIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELE9BQU8sUUFBUSxDQUFDO1FBQ2xCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YscUNBQXFDO1lBQ3JDLElBQUksUUFBUSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUM1QixJQUFBLG9CQUFRLEdBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQUM7WUFDN0IsQ0FBQztZQUNELE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQ2IsVUFBa0IsRUFDbEIsT0FBMEI7UUFFMUIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLE1BQU8sQ0FBQyxTQUFTLENBQUksVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILEtBQUssQ0FBQyxtQkFBbUIsQ0FDdkIsZUFBdUIsRUFDdkIsT0FBaUM7UUFFakMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLE1BQU8sQ0FBQyxtQkFBbUIsQ0FBSSxlQUFlLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUVELDBDQUEwQztJQUMxQyxnQkFBZ0I7UUFDZCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUVELHFEQUFxRDtJQUNyRCxvQkFBb0I7UUFDbEIsT0FBTyxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQztJQUM5QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLFFBQVE7UUFDWixNQUFNLE1BQU0sR0FBWSxFQUFFLENBQUM7UUFFM0IsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBQSxvQkFBUSxHQUFFLENBQUM7WUFDbkIsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFjLENBQUMsQ0FBQztZQUM5QixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQztnQkFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3hCLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBYyxDQUFDLENBQUM7WUFDOUIsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdEIsT0FBTyxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMzRCxDQUFDO0lBQ0gsQ0FBQztJQUVELHlDQUF5QztJQUNqQyxZQUFZO1FBQ2xCLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FDYiwyREFBMkQsQ0FDNUQsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFySUQsc0JBcUlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5pdExhaWthLCBzaHV0ZG93biB9IGZyb20gJ0BsYWlrYXRlc3QvYXV0by1vdGVsJztcbmltcG9ydCB7IExhaWthVGVzdCwgUHJvbXB0LCBHZXRQcm9tcHRPcHRpb25zIH0gZnJvbSAnQGxhaWthdGVzdC9qcy1jbGllbnQnO1xuaW1wb3J0IHsgTGFpa2FDb25maWcgfSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiBVbmlmaWVkIExhaWthVGVzdCBTREsgZm9yIHRyYWNpbmcgYW5kIGV4cGVyaW1lbnRzLlxuICogUHJvdmlkZXMgYSBzaW5nbGUgZW50cnkgcG9pbnQgZm9yIGJvdGggb2JzZXJ2YWJpbGl0eSBhbmQgQS9CIHRlc3RpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBMYWlrYSB7XG4gIHByaXZhdGUgY2xpZW50OiBMYWlrYVRlc3QgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB0cmFjaW5nRW5hYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIExhaWthVGVzdCB3aXRoIHVuaWZpZWQgY29uZmlndXJhdGlvbi5cbiAgICogRW5hYmxlcyBib3RoIHRyYWNpbmcgYW5kIGV4cGVyaW1lbnRzIGJ5IGRlZmF1bHQuXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBhcGlLZXkgb3Igc2VydmljZU5hbWUgaXMgbWlzc2luZy9pbnZhbGlkXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBPcGVuVGVsZW1ldHJ5IFNESyBmYWlscyB0byBzdGFydFxuICAgKi9cbiAgc3RhdGljIGluaXQoY29uZmlnOiBMYWlrYUNvbmZpZyk6IExhaWthIHtcbiAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyBMYWlrYSgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIEluaXRpYWxpemUgdHJhY2luZyAoaWYgZW5hYmxlZCwgZGVmYXVsdDogdHJ1ZSlcbiAgICAgIGlmIChjb25maWcudHJhY2luZyAhPT0gZmFsc2UpIHtcbiAgICAgICAgaW5pdExhaWthKHtcbiAgICAgICAgICBhcGlLZXk6IGNvbmZpZy5hcGlLZXksXG4gICAgICAgICAgc2VydmljZU5hbWU6IGNvbmZpZy5zZXJ2aWNlTmFtZSxcbiAgICAgICAgICBlbmRwb2ludDogY29uZmlnLmVuZHBvaW50LFxuICAgICAgICAgIGNhcHR1cmVDb250ZW50OiBjb25maWcuY2FwdHVyZUNvbnRlbnQsXG4gICAgICAgICAgZGVidWc6IGNvbmZpZy5kZWJ1ZyxcbiAgICAgICAgICBzZXNzaW9uSWQ6IGNvbmZpZy5zZXNzaW9uSWQsXG4gICAgICAgICAgZ2V0U2Vzc2lvbklkOiBjb25maWcuZ2V0U2Vzc2lvbklkLFxuICAgICAgICAgIHVzZXJJZDogY29uZmlnLnVzZXJJZCxcbiAgICAgICAgICBnZXRVc2VySWQ6IGNvbmZpZy5nZXRVc2VySWQsXG4gICAgICAgICAgZGVmYXVsdFByb3BlcnRpZXM6IGNvbmZpZy5kZWZhdWx0UHJvcGVydGllcyxcbiAgICAgICAgfSk7XG4gICAgICAgIGluc3RhbmNlLnRyYWNpbmdFbmFibGVkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gSW5pdGlhbGl6ZSBleHBlcmltZW50cyBjbGllbnQgKGlmIGVuYWJsZWQsIGRlZmF1bHQ6IHRydWUpXG4gICAgICBpZiAoY29uZmlnLmV4cGVyaW1lbnRzICE9PSBmYWxzZSkge1xuICAgICAgICBpbnN0YW5jZS5jbGllbnQgPSBuZXcgTGFpa2FUZXN0KGNvbmZpZy5hcGlLZXksIHtcbiAgICAgICAgICBiYXNlVXJsOiBjb25maWcuYmFzZVVybCxcbiAgICAgICAgICB0aW1lb3V0OiBjb25maWcudGltZW91dCxcbiAgICAgICAgICBjYWNoZUVuYWJsZWQ6IGNvbmZpZy5jYWNoZUVuYWJsZWQsXG4gICAgICAgICAgY2FjaGVUVEw6IGNvbmZpZy5jYWNoZVRUTCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gQ2xlYW51cCBhbnkgcGFydGlhbCBpbml0aWFsaXphdGlvblxuICAgICAgaWYgKGluc3RhbmNlLnRyYWNpbmdFbmFibGVkKSB7XG4gICAgICAgIHNodXRkb3duKCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIHByb21wdCBjb250ZW50IGJ5IG5hbWUuXG4gICAqIFJlcXVpcmVzIGV4cGVyaW1lbnRzIHRvIGJlIGVuYWJsZWQuXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBleHBlcmltZW50cyBhcmUgbm90IGVuYWJsZWRcbiAgICogQHRocm93cyB7VmFsaWRhdGlvbkVycm9yfSBJZiBwcm9tcHQgbmFtZSBpcyBpbnZhbGlkXG4gICAqIEB0aHJvd3Mge0F1dGhlbnRpY2F0aW9uRXJyb3J9IElmIEFQSSBrZXkgaXMgaW52YWxpZFxuICAgKiBAdGhyb3dzIHtMYWlrYVNlcnZpY2VFcnJvcn0gSWYgQVBJIHJldHVybnMgYW4gZXJyb3JcbiAgICogQHRocm93cyB7TmV0d29ya0Vycm9yfSBJZiBuZXR3b3JrIHJlcXVlc3QgZmFpbHNcbiAgICovXG4gIGFzeW5jIGdldFByb21wdDxDID0gdW5rbm93bj4oXG4gICAgcHJvbXB0TmFtZTogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBHZXRQcm9tcHRPcHRpb25zXG4gICk6IFByb21pc2U8UHJvbXB0PEM+PiB7XG4gICAgdGhpcy5lbnN1cmVDbGllbnQoKTtcbiAgICByZXR1cm4gdGhpcy5jbGllbnQhLmdldFByb21wdDxDPihwcm9tcHROYW1lLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZXhwZXJpbWVudCBwcm9tcHQgd2l0aCBhdXRvbWF0aWMgYnVja2V0aW5nLlxuICAgKiBSZXF1aXJlcyBleHBlcmltZW50cyB0byBiZSBlbmFibGVkLlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgZXhwZXJpbWVudHMgYXJlIG5vdCBlbmFibGVkXG4gICAqIEB0aHJvd3Mge1ZhbGlkYXRpb25FcnJvcn0gSWYgZXhwZXJpbWVudCB0aXRsZSBvciBjb250ZXh0IGlzIGludmFsaWRcbiAgICogQHRocm93cyB7QXV0aGVudGljYXRpb25FcnJvcn0gSWYgQVBJIGtleSBpcyBpbnZhbGlkXG4gICAqIEB0aHJvd3Mge0xhaWthU2VydmljZUVycm9yfSBJZiBBUEkgcmV0dXJucyBhbiBlcnJvclxuICAgKiBAdGhyb3dzIHtOZXR3b3JrRXJyb3J9IElmIG5ldHdvcmsgcmVxdWVzdCBmYWlsc1xuICAgKi9cbiAgYXN5bmMgZ2V0RXhwZXJpbWVudFByb21wdDxDID0gdW5rbm93bj4oXG4gICAgZXhwZXJpbWVudFRpdGxlOiBzdHJpbmcsXG4gICAgY29udGV4dD86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICk6IFByb21pc2U8UHJvbXB0PEM+PiB7XG4gICAgdGhpcy5lbnN1cmVDbGllbnQoKTtcbiAgICByZXR1cm4gdGhpcy5jbGllbnQhLmdldEV4cGVyaW1lbnRQcm9tcHQ8Qz4oZXhwZXJpbWVudFRpdGxlLCBjb250ZXh0KTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRydWUgaWYgdHJhY2luZyBpcyBlbmFibGVkLiAqL1xuICBpc1RyYWNpbmdFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnRyYWNpbmdFbmFibGVkO1xuICB9XG5cbiAgLyoqIFJldHVybnMgdHJ1ZSBpZiBleHBlcmltZW50cyBjbGllbnQgaXMgZW5hYmxlZC4gKi9cbiAgaXNFeHBlcmltZW50c0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50ICE9PSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNodXRkb3duIGJvdGggdHJhY2luZyBhbmQgY2xpZW50IHJlc291cmNlcy5cbiAgICogQ2FsbCB0aGlzIGJlZm9yZSBwcm9jZXNzIGV4aXQgZm9yIGNsZWFuIHNodXRkb3duLlxuICAgKi9cbiAgYXN5bmMgc2h1dGRvd24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZXJyb3JzOiBFcnJvcltdID0gW107XG5cbiAgICBpZiAodGhpcy50cmFjaW5nRW5hYmxlZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2h1dGRvd24oKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKGVycm9yIGFzIEVycm9yKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5jbGllbnQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuY2xpZW50LmRlc3Ryb3koKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKGVycm9yIGFzIEVycm9yKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tMYWlrYV0gRXJyb3JzIGR1cmluZyBzaHV0ZG93bjonLCBlcnJvcnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBUaHJvd3MgaWYgZXhwZXJpbWVudHMgbm90IGVuYWJsZWQuICovXG4gIHByaXZhdGUgZW5zdXJlQ2xpZW50KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jbGllbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0V4cGVyaW1lbnRzIG5vdCBlbmFibGVkLiBTZXQgZXhwZXJpbWVudHM6IHRydWUgaW4gY29uZmlnLidcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG4iXX0=
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Unified configuration for LaikaTest SDK.
3
+ * Combines tracing (observability) and experimentation (A/B testing) config.
4
+ */
5
+ export interface LaikaConfig {
6
+ /** API key for Laika authentication (required) */
7
+ apiKey: string;
8
+ /** Service name for resource identification (required) */
9
+ serviceName: string;
10
+ /** Enable OpenTelemetry tracing. Default: true */
11
+ tracing?: boolean;
12
+ /** Enable A/B testing client. Default: true */
13
+ experiments?: boolean;
14
+ /** OTLP endpoint URL. Default: https://api.laikatest.com/otel/v1/traces */
15
+ endpoint?: string;
16
+ /** Capture prompt/response content. Default: false (privacy-first) */
17
+ captureContent?: boolean;
18
+ /** Enable debug logging. Default: false */
19
+ debug?: boolean;
20
+ /** Static session ID for grouping related traces */
21
+ sessionId?: string;
22
+ /** Dynamic session ID getter function */
23
+ getSessionId?: () => string;
24
+ /** Static user ID for per-user analytics */
25
+ userId?: string;
26
+ /** Dynamic user ID getter function */
27
+ getUserId?: () => string;
28
+ /** Default properties to attach to all spans */
29
+ defaultProperties?: Record<string, string | number | boolean>;
30
+ /** API base URL. Default: https://api.laikatest.com */
31
+ baseUrl?: string;
32
+ /** Request timeout in milliseconds. Default: 10000 */
33
+ timeout?: number;
34
+ /** Enable prompt caching. Default: true */
35
+ cacheEnabled?: boolean;
36
+ /** Cache TTL in milliseconds. Default: 30 * 60 * 1000 (30 minutes) */
37
+ cacheTTL?: number;
38
+ }
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVW5pZmllZCBjb25maWd1cmF0aW9uIGZvciBMYWlrYVRlc3QgU0RLLlxuICogQ29tYmluZXMgdHJhY2luZyAob2JzZXJ2YWJpbGl0eSkgYW5kIGV4cGVyaW1lbnRhdGlvbiAoQS9CIHRlc3RpbmcpIGNvbmZpZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYWlrYUNvbmZpZyB7XG4gIC8qKiBBUEkga2V5IGZvciBMYWlrYSBhdXRoZW50aWNhdGlvbiAocmVxdWlyZWQpICovXG4gIGFwaUtleTogc3RyaW5nO1xuXG4gIC8qKiBTZXJ2aWNlIG5hbWUgZm9yIHJlc291cmNlIGlkZW50aWZpY2F0aW9uIChyZXF1aXJlZCkgKi9cbiAgc2VydmljZU5hbWU6IHN0cmluZztcblxuICAvLyBGZWF0dXJlIHRvZ2dsZXNcbiAgLyoqIEVuYWJsZSBPcGVuVGVsZW1ldHJ5IHRyYWNpbmcuIERlZmF1bHQ6IHRydWUgKi9cbiAgdHJhY2luZz86IGJvb2xlYW47XG5cbiAgLyoqIEVuYWJsZSBBL0IgdGVzdGluZyBjbGllbnQuIERlZmF1bHQ6IHRydWUgKi9cbiAgZXhwZXJpbWVudHM/OiBib29sZWFuO1xuXG4gIC8vIFRyYWNpbmcgb3B0aW9ucyAocGFzc2VkIHRvIEBsYWlrYXRlc3QvYXV0by1vdGVsKVxuICAvKiogT1RMUCBlbmRwb2ludCBVUkwuIERlZmF1bHQ6IGh0dHBzOi8vYXBpLmxhaWthdGVzdC5jb20vb3RlbC92MS90cmFjZXMgKi9cbiAgZW5kcG9pbnQ/OiBzdHJpbmc7XG5cbiAgLyoqIENhcHR1cmUgcHJvbXB0L3Jlc3BvbnNlIGNvbnRlbnQuIERlZmF1bHQ6IGZhbHNlIChwcml2YWN5LWZpcnN0KSAqL1xuICBjYXB0dXJlQ29udGVudD86IGJvb2xlYW47XG5cbiAgLyoqIEVuYWJsZSBkZWJ1ZyBsb2dnaW5nLiBEZWZhdWx0OiBmYWxzZSAqL1xuICBkZWJ1Zz86IGJvb2xlYW47XG5cbiAgLy8gU2hhcmVkIGNvbnRleHQgb3B0aW9uc1xuICAvKiogU3RhdGljIHNlc3Npb24gSUQgZm9yIGdyb3VwaW5nIHJlbGF0ZWQgdHJhY2VzICovXG4gIHNlc3Npb25JZD86IHN0cmluZztcblxuICAvKiogRHluYW1pYyBzZXNzaW9uIElEIGdldHRlciBmdW5jdGlvbiAqL1xuICBnZXRTZXNzaW9uSWQ/OiAoKSA9PiBzdHJpbmc7XG5cbiAgLyoqIFN0YXRpYyB1c2VyIElEIGZvciBwZXItdXNlciBhbmFseXRpY3MgKi9cbiAgdXNlcklkPzogc3RyaW5nO1xuXG4gIC8qKiBEeW5hbWljIHVzZXIgSUQgZ2V0dGVyIGZ1bmN0aW9uICovXG4gIGdldFVzZXJJZD86ICgpID0+IHN0cmluZztcblxuICAvKiogRGVmYXVsdCBwcm9wZXJ0aWVzIHRvIGF0dGFjaCB0byBhbGwgc3BhbnMgKi9cbiAgZGVmYXVsdFByb3BlcnRpZXM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPjtcblxuICAvLyBDbGllbnQgb3B0aW9ucyAocGFzc2VkIHRvIEBsYWlrYXRlc3QvY2xpZW50KVxuICAvKiogQVBJIGJhc2UgVVJMLiBEZWZhdWx0OiBodHRwczovL2FwaS5sYWlrYXRlc3QuY29tICovXG4gIGJhc2VVcmw/OiBzdHJpbmc7XG5cbiAgLyoqIFJlcXVlc3QgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuIERlZmF1bHQ6IDEwMDAwICovXG4gIHRpbWVvdXQ/OiBudW1iZXI7XG5cbiAgLyoqIEVuYWJsZSBwcm9tcHQgY2FjaGluZy4gRGVmYXVsdDogdHJ1ZSAqL1xuICBjYWNoZUVuYWJsZWQ/OiBib29sZWFuO1xuXG4gIC8qKiBDYWNoZSBUVEwgaW4gbWlsbGlzZWNvbmRzLiBEZWZhdWx0OiAzMCAqIDYwICogMTAwMCAoMzAgbWludXRlcykgKi9cbiAgY2FjaGVUVEw/OiBudW1iZXI7XG59XG4iXX0=
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@laikatest/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Unified LaikaTest SDK for tracing and A/B testing",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "test": "jest",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "keywords": [
16
+ "laikatest",
17
+ "opentelemetry",
18
+ "otel",
19
+ "tracing",
20
+ "observability",
21
+ "llm",
22
+ "ai",
23
+ "ab-testing",
24
+ "experiments"
25
+ ],
26
+ "author": "LaikaTest Team",
27
+ "license": "MIT",
28
+ "dependencies": {
29
+ "@laikatest/auto-otel": "*",
30
+ "@laikatest/js-client": "*"
31
+ },
32
+ "devDependencies": {
33
+ "@types/jest": "^30.0.0",
34
+ "@types/node": "^20.0.0",
35
+ "jest": "^30.0.0",
36
+ "ts-jest": "^29.0.0",
37
+ "typescript": "^5.0.0"
38
+ },
39
+ "engines": {
40
+ "node": ">=18"
41
+ },
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/ForecloseAI/laikatest_client_js.git",
45
+ "directory": "packages/sdk"
46
+ },
47
+ "bugs": {
48
+ "url": "https://github.com/ForecloseAI/laikatest_client_js/issues"
49
+ },
50
+ "homepage": "https://github.com/ForecloseAI/laikatest_client_js/tree/main/packages/sdk#readme"
51
+ }