@lynxops/sdk 1.0.2 → 1.0.3
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/CHANGELOG.md +16 -0
- package/LICENSE +15 -0
- package/README.md +496 -470
- package/SECURITY.md +29 -0
- package/dist/index.cjs +34 -2
- package/dist/index.js +34 -2
- package/package.json +59 -56
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@lynxops/sdk` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## 1.0.2
|
|
6
|
+
|
|
7
|
+
- Added production-safe background delivery defaults.
|
|
8
|
+
- Added delivery timeout, queue overflow, retry, and circuit breaker controls.
|
|
9
|
+
- Added `flush()`, `shutdown()`, and `getStatus()` lifecycle APIs.
|
|
10
|
+
- Added semantic event helpers for user input, decisions, context, memory, and
|
|
11
|
+
outcomes.
|
|
12
|
+
- Added local-first `guardTool()` policy evaluation.
|
|
13
|
+
- Added `full`, `metadata-only`, and `smart` capture modes.
|
|
14
|
+
- Added sensitive payload masking before delivery.
|
|
15
|
+
- Added OpenAI, Anthropic, Google, Vercel AI SDK, LangChain, Ollama, and Cohere
|
|
16
|
+
instrumentation helpers.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Haven / Lynx
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
11
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,470 +1,496 @@
|
|
|
1
|
-
# Lynx SDK
|
|
2
|
-
|
|
3
|
-
TypeScript SDK for tracing, debugging, and governing AI agent runs with Lynx.
|
|
4
|
-
|
|
5
|
-
Lynx records what happened during an agent run: user input, agent decisions,
|
|
6
|
-
LLM calls, tool calls, context loading, policy decisions, retries, errors, and
|
|
7
|
-
the final outcome. The SDK is designed for production services, so event
|
|
8
|
-
delivery failures do not stop your application by default.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
lynx.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
reason: "The
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
channel:
|
|
255
|
-
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
|
317
|
-
|
|
|
318
|
-
| `
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
|
326
|
-
|
|
|
327
|
-
| `
|
|
328
|
-
| `
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
|
414
|
-
|
|
|
415
|
-
| `
|
|
416
|
-
| `
|
|
417
|
-
| `
|
|
418
|
-
| `
|
|
419
|
-
| `
|
|
420
|
-
| `
|
|
421
|
-
| `
|
|
422
|
-
| `
|
|
423
|
-
| `
|
|
424
|
-
| `
|
|
425
|
-
| `
|
|
426
|
-
| `
|
|
427
|
-
| `
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
|
434
|
-
|
|
|
435
|
-
| `
|
|
436
|
-
| `
|
|
437
|
-
| `
|
|
438
|
-
| `
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
|
445
|
-
|
|
|
446
|
-
| `
|
|
447
|
-
| `
|
|
448
|
-
| `
|
|
449
|
-
| `
|
|
450
|
-
| `
|
|
451
|
-
| `
|
|
452
|
-
| `
|
|
453
|
-
| `
|
|
454
|
-
| `
|
|
455
|
-
| `
|
|
456
|
-
| `
|
|
457
|
-
| `
|
|
458
|
-
| `
|
|
459
|
-
| `
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
1
|
+
# Lynx SDK
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for tracing, debugging, and governing AI agent runs with Lynx.
|
|
4
|
+
|
|
5
|
+
Lynx records what happened during an agent run: user input, agent decisions,
|
|
6
|
+
LLM calls, tool calls, context loading, policy decisions, retries, errors, and
|
|
7
|
+
the final outcome. The SDK is designed for production services, so event
|
|
8
|
+
delivery failures do not stop your application by default.
|
|
9
|
+
|
|
10
|
+
This SDK is designed for Node.js server-side runtimes. Browser and edge runtime
|
|
11
|
+
support are not guaranteed yet.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add @lynxops/sdk
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @lynxops/sdk
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
yarn add @lynxops/sdk
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { LynxTracer } from "@lynxops/sdk";
|
|
31
|
+
|
|
32
|
+
const lynx = new LynxTracer({
|
|
33
|
+
clientId: "support-api",
|
|
34
|
+
apiKey: process.env.LYNX_API_KEY,
|
|
35
|
+
workspaceId: process.env.LYNX_WORKSPACE_ID,
|
|
36
|
+
environment: "production",
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
await lynx.run("SupportAgent", async () => {
|
|
40
|
+
lynx.userInput("I want a refund", { userId: "usr_123" });
|
|
41
|
+
lynx.setAttributes({ orderId: "order_123" });
|
|
42
|
+
|
|
43
|
+
lynx.context("refund-policy", {
|
|
44
|
+
refundWindowDays: 30,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
lynx.decision({
|
|
48
|
+
name: "select_refund_workflow",
|
|
49
|
+
selected: "refund",
|
|
50
|
+
confidence: 0.82,
|
|
51
|
+
reason: "Order is inside the refund window",
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
lynx.outcome({
|
|
55
|
+
status: "COMPLETED",
|
|
56
|
+
businessStatus: "SUCCEEDED",
|
|
57
|
+
reason: "Refund request was accepted",
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
In serverless functions, CLI scripts, tests, or other short-lived processes,
|
|
63
|
+
call `shutdown()` before the process exits so queued background events can be
|
|
64
|
+
flushed.
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
await lynx.shutdown({ timeoutMs: 1000 });
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
By default, events are sent to:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
https://api.lynxops.co
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Use `endpoint` or `LYNX_ENDPOINT` for local development or self-hosted
|
|
77
|
+
deployments.
|
|
78
|
+
|
|
79
|
+
## Default Instance
|
|
80
|
+
|
|
81
|
+
The SDK exports a default `lynx` instance configured from environment
|
|
82
|
+
variables.
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { lynx } from "@lynxops/sdk";
|
|
86
|
+
|
|
87
|
+
await lynx.run("ResearchAgent", async () => {
|
|
88
|
+
lynx.userInput("Find the latest invoice policy");
|
|
89
|
+
lynx.decision("search internal docs first");
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
LYNX_CLIENT_ID=support-api
|
|
95
|
+
LYNX_API_KEY=lynx_sk_...
|
|
96
|
+
LYNX_WORKSPACE_ID=...
|
|
97
|
+
LYNX_ENVIRONMENT=production
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Production Delivery Model
|
|
101
|
+
|
|
102
|
+
The SDK prioritizes your application over event delivery.
|
|
103
|
+
|
|
104
|
+
Production-oriented defaults:
|
|
105
|
+
|
|
106
|
+
| Option | Default |
|
|
107
|
+
| --- | --- |
|
|
108
|
+
| `endpoint` | `https://api.lynxops.co` |
|
|
109
|
+
| `delivery.mode` | `BACKGROUND` |
|
|
110
|
+
| `delivery.timeoutMs` | `1000` |
|
|
111
|
+
| `delivery.flushOnRunEnd` | `false` |
|
|
112
|
+
| `delivery.flushIntervalMs` | `3000` |
|
|
113
|
+
| `delivery.batchSize` | `50` |
|
|
114
|
+
| `delivery.maxQueueSize` | `1000` |
|
|
115
|
+
| `delivery.overflowStrategy` | `DROP_OLDEST` |
|
|
116
|
+
| `circuitBreaker.enabled` | `true` |
|
|
117
|
+
| `circuitBreaker.failureThreshold` | `3` |
|
|
118
|
+
| `circuitBreaker.cooldownMs` | `30000` |
|
|
119
|
+
|
|
120
|
+
Recommended production configuration:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
const lynx = new LynxTracer({
|
|
124
|
+
clientId: "support-api",
|
|
125
|
+
apiKey: process.env.LYNX_API_KEY,
|
|
126
|
+
workspaceId: process.env.LYNX_WORKSPACE_ID,
|
|
127
|
+
|
|
128
|
+
delivery: {
|
|
129
|
+
mode: "BACKGROUND",
|
|
130
|
+
timeoutMs: 1000,
|
|
131
|
+
flushOnRunEnd: false,
|
|
132
|
+
flushIntervalMs: 5000,
|
|
133
|
+
batchSize: 50,
|
|
134
|
+
maxQueueSize: 10_000,
|
|
135
|
+
overflowStrategy: "DROP_OLDEST",
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
circuitBreaker: {
|
|
139
|
+
enabled: true,
|
|
140
|
+
failureThreshold: 3,
|
|
141
|
+
cooldownMs: 30_000,
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
If the Lynx API is unavailable, the SDK:
|
|
147
|
+
|
|
148
|
+
- catches network, timeout, and non-2xx delivery errors
|
|
149
|
+
- queues events in memory
|
|
150
|
+
- retries with backoff
|
|
151
|
+
- opens a circuit breaker after repeated failures
|
|
152
|
+
- drops events according to the configured overflow strategy when the queue is
|
|
153
|
+
full
|
|
154
|
+
|
|
155
|
+
With the default background delivery mode, `run()` does not wait for event
|
|
156
|
+
HTTP requests.
|
|
157
|
+
|
|
158
|
+
## Capturing Agent Runs
|
|
159
|
+
|
|
160
|
+
Use `run()` as the unit of work for one agent execution.
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
await lynx.run(
|
|
164
|
+
"InvoiceAgent",
|
|
165
|
+
async () => {
|
|
166
|
+
lynx.userInput("Can this invoice be paid?");
|
|
167
|
+
lynx.decision("verify vendor and payment policy");
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
workspaceId: "workspace_123",
|
|
171
|
+
agentId: "agent_invoice",
|
|
172
|
+
sessionId: "session_456",
|
|
173
|
+
},
|
|
174
|
+
);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Useful identifiers:
|
|
178
|
+
|
|
179
|
+
| Field | Purpose |
|
|
180
|
+
| --- | --- |
|
|
181
|
+
| `runId` | Unique execution id for one agent run. Generated automatically unless provided. |
|
|
182
|
+
| `sessionId` | Groups multiple runs or events into a user-visible session. |
|
|
183
|
+
| `workspaceId` | Tenant boundary for Lynx ingestion and dashboards. |
|
|
184
|
+
| `agentId` | Stable agent identifier. |
|
|
185
|
+
| `agentName` | Human-readable agent name shown in debugging views. |
|
|
186
|
+
| `environment` | Runtime environment such as `production`, `staging`, or `local`. |
|
|
187
|
+
| `appVersion` | Application release metadata. |
|
|
188
|
+
| `deploymentId` | Deployment metadata for incident correlation. |
|
|
189
|
+
| `promptVersion` | Prompt version metadata attached to LLM and reasoning events. |
|
|
190
|
+
| `policyVersion` | Guardrail or policy version metadata. |
|
|
191
|
+
|
|
192
|
+
## Semantic Events
|
|
193
|
+
|
|
194
|
+
Prefer semantic helpers over raw event logging. They make Lynx debugging views
|
|
195
|
+
more useful.
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
lynx.userInput("Book a flight to Seoul", { userId: "usr_123" });
|
|
199
|
+
|
|
200
|
+
lynx.context("calendar-availability", {
|
|
201
|
+
daysLoaded: 14,
|
|
202
|
+
source: "calendar-api",
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
lynx.decision({
|
|
206
|
+
name: "choose_booking_tool",
|
|
207
|
+
selected: "flight_search",
|
|
208
|
+
alternatives: ["email_assistant", "manual_handoff"],
|
|
209
|
+
confidence: 0.76,
|
|
210
|
+
reason: "The user requested a travel booking action",
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
lynx.log("tool.timeout", {
|
|
214
|
+
error: "Travel API timed out",
|
|
215
|
+
toolName: "travel.search",
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
lynx.outcome({
|
|
219
|
+
status: "FAILED",
|
|
220
|
+
businessStatus: "FAILED",
|
|
221
|
+
reason: "The external travel API timed out",
|
|
222
|
+
userImpact: "MEDIUM",
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Record LLM calls
|
|
227
|
+
|
|
228
|
+
Use `instrumentLLM()` to wrap a model client. The returned proxy preserves the
|
|
229
|
+
original client shape while recording supported model calls.
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
const instrumentedClient = lynx.instrumentLLM(client, {
|
|
233
|
+
modelLabel: "openai.gpt-4.1-mini",
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
await lynx.run("SupportAgent", async () => {
|
|
237
|
+
await instrumentedClient.responses.create({
|
|
238
|
+
model: "gpt-4.1-mini",
|
|
239
|
+
input: "Summarize this support ticket",
|
|
240
|
+
metadata: {
|
|
241
|
+
promptVersion: "support-summary-v3",
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Record tool calls
|
|
248
|
+
|
|
249
|
+
Use `instrumentTool()` to wrap a reusable tool function.
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
const postSlackMessage = lynx.instrumentTool(
|
|
253
|
+
"slack.postMessage",
|
|
254
|
+
async (input: { channel: string; text: string }) => {
|
|
255
|
+
return await slack.chat.postMessage(input);
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
sideEffect: true,
|
|
259
|
+
riskLevel: "MEDIUM",
|
|
260
|
+
externalTarget: "slack",
|
|
261
|
+
},
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
await postSlackMessage({
|
|
265
|
+
channel: "C123",
|
|
266
|
+
text: "Refund approved",
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Local Guardrails
|
|
271
|
+
|
|
272
|
+
`guardTool()` evaluates your policy locally before a tool runs. Lynx server
|
|
273
|
+
availability does not decide whether the tool is blocked.
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
import { LynxPolicyError } from "@lynxops/sdk";
|
|
277
|
+
|
|
278
|
+
const refund = lynx.guardTool(
|
|
279
|
+
"refund.create",
|
|
280
|
+
async ({ amount }: { amount: number }) => {
|
|
281
|
+
return { refunded: amount };
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
sideEffect: true,
|
|
285
|
+
riskLevel: "HIGH",
|
|
286
|
+
failureMode: "FAIL_CLOSED",
|
|
287
|
+
beforeCall: ({ input }) => {
|
|
288
|
+
if (input.amount > 100) {
|
|
289
|
+
return {
|
|
290
|
+
action: "BLOCK",
|
|
291
|
+
policyId: "refund-limit",
|
|
292
|
+
reason: "Refund amount is over the approved limit",
|
|
293
|
+
severity: "HIGH",
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return {
|
|
298
|
+
action: "ALLOW",
|
|
299
|
+
policyId: "refund-limit",
|
|
300
|
+
};
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
try {
|
|
306
|
+
await lynx.run("SupportAgent", () => refund({ amount: 500 }));
|
|
307
|
+
} catch (error) {
|
|
308
|
+
if (error instanceof LynxPolicyError) {
|
|
309
|
+
console.log(error.action, error.policyId, error.reason);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Policy behavior:
|
|
315
|
+
|
|
316
|
+
| Policy result | Behavior |
|
|
317
|
+
| --- | --- |
|
|
318
|
+
| `ALLOW` | Runs the tool and records policy evaluation metadata. |
|
|
319
|
+
| `WARN` | Runs the tool and records a warning. |
|
|
320
|
+
| `BLOCK` | Blocks the tool and throws `LynxPolicyError`. |
|
|
321
|
+
| `REQUIRE_APPROVAL` | Blocks the tool and throws `LynxPolicyError`. |
|
|
322
|
+
|
|
323
|
+
If policy evaluation itself throws, `failureMode` decides the fallback:
|
|
324
|
+
|
|
325
|
+
| Failure mode | Behavior |
|
|
326
|
+
| --- | --- |
|
|
327
|
+
| `FAIL_OPEN` | Allows the tool call and records the policy error. |
|
|
328
|
+
| `FAIL_CLOSED` | Blocks the tool call. |
|
|
329
|
+
| `REQUIRE_APPROVAL` | Blocks with `action: "REQUIRE_APPROVAL"`. |
|
|
330
|
+
|
|
331
|
+
## Capture Modes
|
|
332
|
+
|
|
333
|
+
Lynx does not require you to store full payloads.
|
|
334
|
+
|
|
335
|
+
| Mode | Behavior |
|
|
336
|
+
| --- | --- |
|
|
337
|
+
| `full` | Captures input and output payloads according to `captureInput` and `captureOutput`. |
|
|
338
|
+
| `metadata-only` | Keeps structure, timing, token usage, cost, status, errors, tool names, and trace metadata without raw content. |
|
|
339
|
+
| `smart` | Captures metadata for normal events and preserves richer detail for failures, policy violations, and abnormal latency. |
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
const lynx = new LynxTracer({
|
|
343
|
+
clientId: "support-api",
|
|
344
|
+
apiKey: process.env.LYNX_API_KEY,
|
|
345
|
+
captureMode: "smart",
|
|
346
|
+
maxPayloadLength: 16_000,
|
|
347
|
+
});
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Flush, Shutdown, and Health
|
|
351
|
+
|
|
352
|
+
Use `flush()` to send the current queue while keeping the SDK active.
|
|
353
|
+
|
|
354
|
+
```ts
|
|
355
|
+
await lynx.flush();
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Use `shutdown()` when the process is about to exit, in serverless handlers, or
|
|
359
|
+
in tests.
|
|
360
|
+
|
|
361
|
+
```ts
|
|
362
|
+
await lynx.shutdown({ timeoutMs: 1000 });
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Use `getStatus()` for local diagnostics.
|
|
366
|
+
|
|
367
|
+
```ts
|
|
368
|
+
const status = lynx.getStatus();
|
|
369
|
+
|
|
370
|
+
console.log({
|
|
371
|
+
queueSize: status.queueSize,
|
|
372
|
+
droppedEvents: status.droppedEvents,
|
|
373
|
+
circuitState: status.circuitState,
|
|
374
|
+
pendingTransmissions: status.pendingTransmissions,
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## Configuration Reference
|
|
379
|
+
|
|
380
|
+
```ts
|
|
381
|
+
const lynx = new LynxTracer({
|
|
382
|
+
clientId: "support-api",
|
|
383
|
+
endpoint: "https://api.lynxops.co",
|
|
384
|
+
workspaceId: "workspace_123",
|
|
385
|
+
agentId: "agent_support",
|
|
386
|
+
apiKey: process.env.LYNX_API_KEY,
|
|
387
|
+
appVersion: "2026.06.29",
|
|
388
|
+
deploymentId: "deploy_123",
|
|
389
|
+
environment: "production",
|
|
390
|
+
policyVersion: "policy_2026_06",
|
|
391
|
+
sampleRate: 1,
|
|
392
|
+
captureInput: true,
|
|
393
|
+
captureOutput: true,
|
|
394
|
+
captureMode: "smart",
|
|
395
|
+
maxPayloadLength: 16_000,
|
|
396
|
+
delivery: {
|
|
397
|
+
mode: "BACKGROUND",
|
|
398
|
+
timeoutMs: 1000,
|
|
399
|
+
flushOnRunEnd: false,
|
|
400
|
+
flushIntervalMs: 3000,
|
|
401
|
+
batchSize: 50,
|
|
402
|
+
maxQueueSize: 1000,
|
|
403
|
+
overflowStrategy: "DROP_OLDEST",
|
|
404
|
+
},
|
|
405
|
+
circuitBreaker: {
|
|
406
|
+
enabled: true,
|
|
407
|
+
failureThreshold: 3,
|
|
408
|
+
cooldownMs: 30_000,
|
|
409
|
+
},
|
|
410
|
+
});
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
| Option | Description |
|
|
414
|
+
| --- | --- |
|
|
415
|
+
| `clientId` | Required service or client identifier. |
|
|
416
|
+
| `endpoint` | Lynx API endpoint. Defaults to `https://api.lynxops.co`. |
|
|
417
|
+
| `workspaceId` | Default workspace id attached to events. |
|
|
418
|
+
| `agentId` | Default agent id attached to events. |
|
|
419
|
+
| `apiKey` | Lynx ingestion API key. Sent as a bearer token. |
|
|
420
|
+
| `appVersion` | Application version metadata. |
|
|
421
|
+
| `deploymentId` | Deployment id metadata. |
|
|
422
|
+
| `environment` | Runtime environment metadata. |
|
|
423
|
+
| `policyVersion` | Default policy version metadata. |
|
|
424
|
+
| `sampleRate` | Trace sampling ratio from `0` to `1`. |
|
|
425
|
+
| `captureInput` | Whether input payloads can be captured. |
|
|
426
|
+
| `captureOutput` | Whether output payloads can be captured. |
|
|
427
|
+
| `captureMode` | `full`, `metadata-only`, or `smart`. |
|
|
428
|
+
| `maxPayloadLength` | Maximum serialized payload length per event. |
|
|
429
|
+
| `delivery.mode` | `BACKGROUND` or `BLOCKING`. |
|
|
430
|
+
| `delivery.timeoutMs` | Timeout for one event delivery request. |
|
|
431
|
+
| `delivery.flushOnRunEnd` | Whether `run()` tries to flush after the wrapped work finishes. |
|
|
432
|
+
| `delivery.flushIntervalMs` | Background flush interval. |
|
|
433
|
+
| `delivery.batchSize` | Batch size for delivery. |
|
|
434
|
+
| `delivery.maxQueueSize` | Maximum queued events in memory. |
|
|
435
|
+
| `delivery.overflowStrategy` | `DROP_OLDEST` or `DROP_NEWEST`. |
|
|
436
|
+
| `circuitBreaker.enabled` | Enables delivery circuit breaker protection. |
|
|
437
|
+
| `circuitBreaker.failureThreshold` | Consecutive delivery failures before opening the breaker. |
|
|
438
|
+
| `circuitBreaker.cooldownMs` | Cooldown before retrying after the breaker opens. |
|
|
439
|
+
|
|
440
|
+
## Environment Variables
|
|
441
|
+
|
|
442
|
+
The default `lynx` export reads these variables:
|
|
443
|
+
|
|
444
|
+
| Variable | Description |
|
|
445
|
+
| --- | --- |
|
|
446
|
+
| `LYNX_CLIENT_ID` | Client or service identifier. Defaults to `local_dev_env`. |
|
|
447
|
+
| `LYNX_ENDPOINT` | Optional Lynx API endpoint override. |
|
|
448
|
+
| `LYNX_API_KEY` | Lynx ingestion API key. |
|
|
449
|
+
| `LYNX_WORKSPACE_ID` | Default workspace id. |
|
|
450
|
+
| `LYNX_AGENT_ID` | Default agent id. |
|
|
451
|
+
| `LYNX_SESSION_ID` | Default session id when `run()` does not receive one. |
|
|
452
|
+
| `LYNX_SAMPLE_RATE` | Sampling rate from `0` to `1`. |
|
|
453
|
+
| `LYNX_CAPTURE_INPUT` | `true` or `false`. |
|
|
454
|
+
| `LYNX_CAPTURE_OUTPUT` | `true` or `false`. |
|
|
455
|
+
| `LYNX_CAPTURE_MODE` | `full`, `metadata-only`, or `smart`. |
|
|
456
|
+
| `LYNX_MAX_PAYLOAD_LENGTH` | Maximum payload string length. |
|
|
457
|
+
| `LYNX_APP_VERSION` | Application version metadata. |
|
|
458
|
+
| `LYNX_DEPLOYMENT_ID` | Deployment id metadata. |
|
|
459
|
+
| `LYNX_ENVIRONMENT` | Runtime environment metadata. Falls back to `NODE_ENV`. |
|
|
460
|
+
| `LYNX_POLICY_VERSION` | Default policy version metadata. |
|
|
461
|
+
| `LYNX_DELIVERY_MODE` | `BACKGROUND` or `BLOCKING`. |
|
|
462
|
+
| `LYNX_DELIVERY_TIMEOUT_MS` | Delivery timeout in milliseconds. |
|
|
463
|
+
| `LYNX_DELIVERY_FLUSH_ON_RUN_END` | `true` or `false`. |
|
|
464
|
+
| `LYNX_DELIVERY_FLUSH_INTERVAL_MS` | Flush interval in milliseconds. |
|
|
465
|
+
| `LYNX_DELIVERY_BATCH_SIZE` | Batch size. |
|
|
466
|
+
| `LYNX_DELIVERY_MAX_QUEUE_SIZE` | Maximum queued event count. |
|
|
467
|
+
| `LYNX_DELIVERY_OVERFLOW_STRATEGY` | `DROP_OLDEST` or `DROP_NEWEST`. |
|
|
468
|
+
| `LYNX_CIRCUIT_BREAKER_ENABLED` | `true` or `false`. |
|
|
469
|
+
| `LYNX_CIRCUIT_BREAKER_FAILURE_THRESHOLD` | Consecutive failure count before opening the breaker. |
|
|
470
|
+
| `LYNX_CIRCUIT_BREAKER_COOLDOWN_MS` | Circuit breaker cooldown in milliseconds. |
|
|
471
|
+
|
|
472
|
+
## Development
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
pnpm install
|
|
476
|
+
pnpm build
|
|
477
|
+
pnpm test
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
The SDK is ESM-first and also publishes a CommonJS build through package
|
|
481
|
+
exports.
|
|
482
|
+
|
|
483
|
+
## Runtime Support
|
|
484
|
+
|
|
485
|
+
`@lynxops/sdk` supports Node.js 18 and newer. It uses Node runtime APIs such as
|
|
486
|
+
`AsyncLocalStorage`, global `fetch`, `AbortSignal.timeout`, and process
|
|
487
|
+
lifecycle hooks.
|
|
488
|
+
|
|
489
|
+
## Security
|
|
490
|
+
|
|
491
|
+
Please report security issues privately to `security@lynxops.co`. See
|
|
492
|
+
`SECURITY.md` for details.
|
|
493
|
+
|
|
494
|
+
## License
|
|
495
|
+
|
|
496
|
+
ISC
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
Lynx SDK runs inside customer applications, so we treat security reports with
|
|
4
|
+
high priority.
|
|
5
|
+
|
|
6
|
+
## Supported Versions
|
|
7
|
+
|
|
8
|
+
Security fixes are provided for the latest published version of `@lynxops/sdk`.
|
|
9
|
+
|
|
10
|
+
## Reporting a Vulnerability
|
|
11
|
+
|
|
12
|
+
Please do not open a public GitHub issue for sensitive security reports.
|
|
13
|
+
|
|
14
|
+
Send vulnerability details to:
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
security@lynxops.co
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Include:
|
|
21
|
+
|
|
22
|
+
- affected package version
|
|
23
|
+
- runtime and framework details
|
|
24
|
+
- reproduction steps or proof of concept
|
|
25
|
+
- potential impact
|
|
26
|
+
- any relevant logs or traces with secrets removed
|
|
27
|
+
|
|
28
|
+
We will acknowledge reports as soon as possible and coordinate remediation
|
|
29
|
+
before public disclosure.
|
package/dist/index.cjs
CHANGED
|
@@ -123,6 +123,35 @@ var PII_RULES = patterns_default.piiRules.map((rule) => ({
|
|
|
123
123
|
replacement: rule.replacement
|
|
124
124
|
}));
|
|
125
125
|
var SENSITIVE_KEY_PATTERN = /(?:api[-_]?key|authorization|auth[-_]?token|bearer|client[-_]?secret|cookie|credential|jwt|password|private[-_]?key|refresh[-_]?token|secret|session[-_]?token|token)/i;
|
|
126
|
+
var SAFE_TOKEN_METRIC_KEYS = /* @__PURE__ */ new Set([
|
|
127
|
+
"completiontokens",
|
|
128
|
+
"completiontokencount",
|
|
129
|
+
"completion_tokens",
|
|
130
|
+
"inputtokens",
|
|
131
|
+
"inputtokencount",
|
|
132
|
+
"input_tokens",
|
|
133
|
+
"maxtokens",
|
|
134
|
+
"maxoutputtokens",
|
|
135
|
+
"max_tokens",
|
|
136
|
+
"outputtokens",
|
|
137
|
+
"outputtokencount",
|
|
138
|
+
"output_tokens",
|
|
139
|
+
"prompttokens",
|
|
140
|
+
"prompttokencount",
|
|
141
|
+
"prompt_tokens",
|
|
142
|
+
"totaltokens",
|
|
143
|
+
"totaltokencount",
|
|
144
|
+
"total_tokens"
|
|
145
|
+
]);
|
|
146
|
+
function normalizeKey(key) {
|
|
147
|
+
return key.replace(/[-_]/g, "").toLowerCase();
|
|
148
|
+
}
|
|
149
|
+
function isSensitiveKey(key) {
|
|
150
|
+
if (SAFE_TOKEN_METRIC_KEYS.has(normalizeKey(key))) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
return SENSITIVE_KEY_PATTERN.test(key);
|
|
154
|
+
}
|
|
126
155
|
function maskPIIString(text) {
|
|
127
156
|
let masked = text;
|
|
128
157
|
for (const rule of PII_RULES) {
|
|
@@ -141,7 +170,7 @@ function recursiveMaskPII(obj) {
|
|
|
141
170
|
if (typeof obj === "object") {
|
|
142
171
|
const res = {};
|
|
143
172
|
for (const key of Object.keys(obj)) {
|
|
144
|
-
if (
|
|
173
|
+
if (isSensitiveKey(key)) {
|
|
145
174
|
res[key] = "[MASKED_SECRET]";
|
|
146
175
|
} else {
|
|
147
176
|
res[key] = recursiveMaskPII(obj[key]);
|
|
@@ -354,6 +383,7 @@ function instrumentLLM(tracer, instance, optionsOrLabel = "llm.inference") {
|
|
|
354
383
|
}
|
|
355
384
|
const pathStr = path.join(".");
|
|
356
385
|
return pathStr === "chat.completions.create" || // OpenAI
|
|
386
|
+
pathStr === "responses.create" || // OpenAI Responses API
|
|
357
387
|
pathStr === "messages.create" || // Anthropic (Claude)
|
|
358
388
|
pathStr === "models.generateContent" || // Google Gen AI 신규
|
|
359
389
|
pathStr === "generateContent" || // Google Generative AI 기존
|
|
@@ -498,8 +528,10 @@ function instrumentTool(tracer, toolName, fn, metadata = {}) {
|
|
|
498
528
|
});
|
|
499
529
|
}
|
|
500
530
|
|
|
531
|
+
// src/version.ts
|
|
532
|
+
var SDK_VERSION = "1.0.3";
|
|
533
|
+
|
|
501
534
|
// src/core/tracer.ts
|
|
502
|
-
var SDK_VERSION = "1.0.0";
|
|
503
535
|
var DEFAULT_ENDPOINT = "https://api.lynxops.co";
|
|
504
536
|
var DEFAULT_MAX_QUEUE_SIZE = 1e3;
|
|
505
537
|
var DEFAULT_BATCH_SIZE = 50;
|
package/dist/index.js
CHANGED
|
@@ -92,6 +92,35 @@ var PII_RULES = patterns_default.piiRules.map((rule) => ({
|
|
|
92
92
|
replacement: rule.replacement
|
|
93
93
|
}));
|
|
94
94
|
var SENSITIVE_KEY_PATTERN = /(?:api[-_]?key|authorization|auth[-_]?token|bearer|client[-_]?secret|cookie|credential|jwt|password|private[-_]?key|refresh[-_]?token|secret|session[-_]?token|token)/i;
|
|
95
|
+
var SAFE_TOKEN_METRIC_KEYS = /* @__PURE__ */ new Set([
|
|
96
|
+
"completiontokens",
|
|
97
|
+
"completiontokencount",
|
|
98
|
+
"completion_tokens",
|
|
99
|
+
"inputtokens",
|
|
100
|
+
"inputtokencount",
|
|
101
|
+
"input_tokens",
|
|
102
|
+
"maxtokens",
|
|
103
|
+
"maxoutputtokens",
|
|
104
|
+
"max_tokens",
|
|
105
|
+
"outputtokens",
|
|
106
|
+
"outputtokencount",
|
|
107
|
+
"output_tokens",
|
|
108
|
+
"prompttokens",
|
|
109
|
+
"prompttokencount",
|
|
110
|
+
"prompt_tokens",
|
|
111
|
+
"totaltokens",
|
|
112
|
+
"totaltokencount",
|
|
113
|
+
"total_tokens"
|
|
114
|
+
]);
|
|
115
|
+
function normalizeKey(key) {
|
|
116
|
+
return key.replace(/[-_]/g, "").toLowerCase();
|
|
117
|
+
}
|
|
118
|
+
function isSensitiveKey(key) {
|
|
119
|
+
if (SAFE_TOKEN_METRIC_KEYS.has(normalizeKey(key))) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
return SENSITIVE_KEY_PATTERN.test(key);
|
|
123
|
+
}
|
|
95
124
|
function maskPIIString(text) {
|
|
96
125
|
let masked = text;
|
|
97
126
|
for (const rule of PII_RULES) {
|
|
@@ -110,7 +139,7 @@ function recursiveMaskPII(obj) {
|
|
|
110
139
|
if (typeof obj === "object") {
|
|
111
140
|
const res = {};
|
|
112
141
|
for (const key of Object.keys(obj)) {
|
|
113
|
-
if (
|
|
142
|
+
if (isSensitiveKey(key)) {
|
|
114
143
|
res[key] = "[MASKED_SECRET]";
|
|
115
144
|
} else {
|
|
116
145
|
res[key] = recursiveMaskPII(obj[key]);
|
|
@@ -323,6 +352,7 @@ function instrumentLLM(tracer, instance, optionsOrLabel = "llm.inference") {
|
|
|
323
352
|
}
|
|
324
353
|
const pathStr = path.join(".");
|
|
325
354
|
return pathStr === "chat.completions.create" || // OpenAI
|
|
355
|
+
pathStr === "responses.create" || // OpenAI Responses API
|
|
326
356
|
pathStr === "messages.create" || // Anthropic (Claude)
|
|
327
357
|
pathStr === "models.generateContent" || // Google Gen AI 신규
|
|
328
358
|
pathStr === "generateContent" || // Google Generative AI 기존
|
|
@@ -467,8 +497,10 @@ function instrumentTool(tracer, toolName, fn, metadata = {}) {
|
|
|
467
497
|
});
|
|
468
498
|
}
|
|
469
499
|
|
|
500
|
+
// src/version.ts
|
|
501
|
+
var SDK_VERSION = "1.0.3";
|
|
502
|
+
|
|
470
503
|
// src/core/tracer.ts
|
|
471
|
-
var SDK_VERSION = "1.0.0";
|
|
472
504
|
var DEFAULT_ENDPOINT = "https://api.lynxops.co";
|
|
473
505
|
var DEFAULT_MAX_QUEUE_SIZE = 1e3;
|
|
474
506
|
var DEFAULT_BATCH_SIZE = 50;
|
package/package.json
CHANGED
|
@@ -1,56 +1,59 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@lynxops/sdk",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "TypeScript SDK for tracing, debugging, and governing AI agent runs with Lynx.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./dist/index.cjs",
|
|
7
|
-
"module": "./dist/index.js",
|
|
8
|
-
"types": "./dist/index.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./dist/index.d.ts",
|
|
12
|
-
"import": "./dist/index.js",
|
|
13
|
-
"require": "./dist/index.cjs"
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"url": "https://github.com/hvnn-oss/lynx-sdk
|
|
50
|
-
},
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@lynxops/sdk",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "TypeScript SDK for tracing, debugging, and governing AI agent runs with Lynx.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18"
|
|
18
|
+
},
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"CHANGELOG.md",
|
|
23
|
+
"SECURITY.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup src/index.ts --format cjs,esm --clean --dts",
|
|
27
|
+
"check-types": "tsc --noEmit",
|
|
28
|
+
"test": "pnpm build && node --test test/*.mjs"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"ai",
|
|
32
|
+
"agent",
|
|
33
|
+
"observability",
|
|
34
|
+
"tracing",
|
|
35
|
+
"debugging",
|
|
36
|
+
"guardrails",
|
|
37
|
+
"lynx"
|
|
38
|
+
],
|
|
39
|
+
"author": "Lynx",
|
|
40
|
+
"license": "ISC",
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^25.9.1",
|
|
43
|
+
"tsup": "^8.3.5",
|
|
44
|
+
"typescript": "^5.0.0"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/hvnn-oss/lynx-sdk.git"
|
|
50
|
+
},
|
|
51
|
+
"bugs": {
|
|
52
|
+
"url": "https://github.com/hvnn-oss/lynx-sdk/issues"
|
|
53
|
+
},
|
|
54
|
+
"homepage": "https://docs.lynxops.co",
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public",
|
|
57
|
+
"provenance": true
|
|
58
|
+
}
|
|
59
|
+
}
|