@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 +285 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +32 -0
- package/dist/laika.d.ts +49 -0
- package/dist/laika.js +127 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.js +3 -0
- package/package.json +51 -0
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
|
package/dist/index.d.ts
ADDED
|
@@ -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=
|
package/dist/laika.d.ts
ADDED
|
@@ -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=
|
package/dist/types.d.ts
ADDED
|
@@ -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
|
+
}
|