@lmnr-ai/lmnr 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.json ADDED
@@ -0,0 +1,2 @@
1
+ {
2
+ }
package/README.md CHANGED
@@ -8,11 +8,85 @@ npm install @lmnr-ai/lmnr
8
8
 
9
9
  ## Features
10
10
 
11
- - Make Laminar endpoint calls from your JS code
12
- - Make Laminar endpoint calls that can run your own functions as tools from your NodeJS code
13
- - `LaminarRemoteDebugger` to execute your own functions while you test your flows in workshop
11
+ - Instrumentation of your JS/TS code
12
+ - Events and semantic events right from the code
13
+ - Make Laminar pipeline calls from your JS code
14
14
 
15
- ## Making Laminar endpoint calls
15
+ ## Prerequisite
16
+
17
+ - Laminar project created at https://lmnr.ai
18
+ - Export (or set using .env) a variable `LMNR_PROJECT_API_KEY` with the value from the project settings page
19
+
20
+ ## Code instrumentation
21
+
22
+ For manual instrumetation you will need to import the following:
23
+ - `trace` - this is a function to start a trace. It returns a `TraceContext`
24
+ - `TraceContext` - a pointer to the current trace that you can pass around functions as you want.
25
+ - `SpanContext` - a pointer to the current span that you can pass around functions as you want
26
+ - `ObservationContext` – parent class of `TraceContext` and `SpanContext`. Useful, if you don't want to import the separate context types in TS.
27
+
28
+ Both `TraceContext` and `SpanContext` expose the following interfaces:
29
+ - `span(name: string, props: CreateSpanProps)` - create a child span within the current context. Returns `SpanContext`
30
+ - `update(props)` - update the current trace or span and return it. Returns `TraceContext` or `SpanContext`. Useful when some metadata becomes known later during the program execution
31
+
32
+ In addition, `SpanContext` allows you to:
33
+ - `event(templateName: string, props: SpanEventProps)` - emit a custom event at any point
34
+ - `evaluateEvent(templateName: string, data: str, props: SpanEvaluateEventProps)` - register a possible event for automatic checking by Laminar.
35
+ - `end(props: UpdateSpanProps)` – update the current span, and terminate it
36
+
37
+ ### Example
38
+
39
+ ```javascript
40
+ // `trace()` is the main entrypoint into the observation of your app
41
+ // `ObservationContext` is a parent class for `SpanContext` and `TraceContext`
42
+ import { trace, ObservationContext } from '@lmnr-ai/lmnr';
43
+
44
+ import OpenAI from 'openai';
45
+
46
+ const openai = new OpenAI({apiKey: process.env.OPENAI_API_KEY});
47
+
48
+ const getRandomCountry = (s: ObservationContext): string => {
49
+ // create the span without registering the input
50
+ const span = s.span('getRandomCountry');
51
+ const countries = ['United States', 'Canada', 'Australia', 'Germany', 'Japan'];
52
+ const country = countries[Math.floor(Math.random() * countries.length)];
53
+
54
+ // end the span and register the output
55
+ span.end({output: country});
56
+
57
+ return country;
58
+ }
59
+
60
+ const foo = (question: string, t: ObservationContext) => {
61
+ // create the span and register the input
62
+ const span = t.span('foo', {input: {question}});
63
+
64
+ // pass the span context down the function call if you want to trace it
65
+ const country = getRandomCountry(span);
66
+ question += country;
67
+ const result = openai.chat.completions.create({
68
+ model: 'gpt-4o-mini',
69
+ messages: [{role: 'system', content: 'You are a helpful assistant.'}, {role: 'user', content: question}],
70
+ }).then((response) => {
71
+ const output = response.choices[0].message.content;
72
+
73
+ // ask Laminar to check for a pre-defined event.
74
+ // In this example correctness is pre-defined in the UI as "The data is factually correct"
75
+ span.evalueateEvent('correctness', output ?? '');
76
+ // end the span and register the output
77
+ span.end({output});
78
+ });
79
+ };
80
+
81
+ // Start the trace observation at the entry to your program
82
+ const t = trace();
83
+
84
+ // pass the trace context into the handler
85
+ foo("What is the capital of ", t);
86
+
87
+ ```
88
+
89
+ ## Making Laminar pipeline calls
16
90
 
17
91
  After you are ready to use your pipeline in your code, deploy it in Laminar by selecting the target version for the pipeline.
18
92
 
@@ -21,7 +95,7 @@ Once your pipeline target is set, you can call it from JS in just a few lines.
21
95
  Example use:
22
96
 
23
97
  ```typescript
24
- import { Laminar, NodeInput } from '@lmnr-ai/lmnr';
98
+ import { Laminar } from '@lmnr-ai/lmnr';
25
99
 
26
100
  const l = new Laminar('<YOUR_PROJECT_API_KEY>');
27
101
  const result = await l.run({
@@ -0,0 +1,136 @@
1
+ type ChatMessage = {
2
+ role: 'user' | 'assistant' | 'system';
3
+ content: string;
4
+ };
5
+ type NodeInput = ChatMessage[] | string;
6
+ type PipelineRunRequest = {
7
+ inputs: Record<string, NodeInput>;
8
+ pipeline: string;
9
+ env?: Record<string, string>;
10
+ metadata?: Record<string, string>;
11
+ };
12
+ type PipelineRunResponse = {
13
+ outputs: Record<string, Record<string, NodeInput>>;
14
+ runId: string;
15
+ };
16
+ type EvaluateEvent = {
17
+ name: string;
18
+ data: string;
19
+ timestamp?: Date;
20
+ };
21
+ type Event = {
22
+ id: string;
23
+ templateName: string;
24
+ timestamp: Date;
25
+ spanId: string;
26
+ value: number | string | null;
27
+ };
28
+ type SpanType = 'DEFAULT' | 'LLM';
29
+ type Span = {
30
+ version: string;
31
+ spanType: SpanType;
32
+ id: string;
33
+ parentSpanId: string | null;
34
+ traceId: string;
35
+ name: string;
36
+ startTime: Date;
37
+ endTime: Date | null;
38
+ attributes: Record<string, any>;
39
+ input: any | null;
40
+ output: any | null;
41
+ metadata: Record<string, any> | null;
42
+ evaluateEvents: EvaluateEvent[];
43
+ events: Event[];
44
+ };
45
+ type Trace = {
46
+ id: string;
47
+ version: string;
48
+ success: boolean;
49
+ startTime: Date | null;
50
+ endTime: Date | null;
51
+ userId: string | null;
52
+ sessionId: string | null;
53
+ release: string;
54
+ metadata: Record<string, any> | null;
55
+ };
56
+
57
+ declare class Collector {
58
+ private readonly flushInterval;
59
+ private readonly client;
60
+ private readonly maxQueueSize;
61
+ private queue;
62
+ private flushTimeout;
63
+ constructor();
64
+ addTask(task: Span | Trace): void;
65
+ private flush;
66
+ }
67
+
68
+ interface CreateSpanProps {
69
+ input?: any | null;
70
+ metadata?: Record<string, any> | null;
71
+ attributes?: Record<string, any>;
72
+ spanType?: SpanType;
73
+ }
74
+ declare class ObservationContext {
75
+ protected observation: Span | Trace;
76
+ parent: ObservationContext | null;
77
+ children: Record<string, SpanContext>;
78
+ protected collector: Collector;
79
+ constructor(observation: Span | Trace, parent: ObservationContext | null);
80
+ id(): string;
81
+ span(name: string, { input, metadata, attributes, spanType, }?: CreateSpanProps): SpanContext;
82
+ }
83
+ interface UpdateSpanProps {
84
+ input?: any | null;
85
+ output?: any | null;
86
+ metadata?: Record<string, any> | null;
87
+ attributes?: Record<string, any>;
88
+ evaluateEvents?: EvaluateEvent[];
89
+ override?: boolean;
90
+ }
91
+ interface SpanEventProps {
92
+ value?: string | number | boolean;
93
+ timestamp?: Date;
94
+ }
95
+ interface SpanEvaluateEventProps {
96
+ timestamp?: Date;
97
+ }
98
+ declare class SpanContext extends ObservationContext {
99
+ private inerSpan;
100
+ constructor(span: Span, parent: ObservationContext);
101
+ end({ input, output, metadata, attributes, evaluateEvents, override }?: UpdateSpanProps): SpanContext;
102
+ update({ input, output, metadata, attributes, evaluateEvents, override }: UpdateSpanProps): SpanContext;
103
+ event(templateName: string, { value, timestamp, }?: SpanEventProps): SpanContext;
104
+ evalueateEvent(templateName: string, data: string, { timestamp }?: SpanEvaluateEventProps): SpanContext;
105
+ private getParent;
106
+ private innerUpdate;
107
+ }
108
+ interface UpdateTraceProps {
109
+ success?: boolean;
110
+ userId?: string | null;
111
+ sessionId?: string | null;
112
+ release?: string;
113
+ metadata?: Record<string, any> | null;
114
+ }
115
+ declare class TraceContext extends ObservationContext {
116
+ private trace;
117
+ constructor(trace: Trace, parent: ObservationContext | null);
118
+ update({ success, userId, sessionId, release, metadata }?: UpdateTraceProps): TraceContext;
119
+ }
120
+ interface TraceProps {
121
+ userId?: string | null;
122
+ sessionId?: string | null;
123
+ release?: string;
124
+ metadata?: Record<string, any> | null;
125
+ }
126
+ declare const trace: ({ userId, sessionId, release, metadata, }?: TraceProps) => TraceContext;
127
+
128
+ declare class Laminar {
129
+ private readonly projectApiKey;
130
+ private readonly url;
131
+ private readonly response;
132
+ constructor(projectApiKey: string);
133
+ run({ pipeline, inputs, env, metadata, }: PipelineRunRequest): Promise<PipelineRunResponse>;
134
+ }
135
+
136
+ export { type ChatMessage, type EvaluateEvent, type Event, Laminar, type NodeInput, ObservationContext, type PipelineRunRequest, type PipelineRunResponse, type Span, SpanContext, type Trace, TraceContext, trace };
@@ -0,0 +1,136 @@
1
+ type ChatMessage = {
2
+ role: 'user' | 'assistant' | 'system';
3
+ content: string;
4
+ };
5
+ type NodeInput = ChatMessage[] | string;
6
+ type PipelineRunRequest = {
7
+ inputs: Record<string, NodeInput>;
8
+ pipeline: string;
9
+ env?: Record<string, string>;
10
+ metadata?: Record<string, string>;
11
+ };
12
+ type PipelineRunResponse = {
13
+ outputs: Record<string, Record<string, NodeInput>>;
14
+ runId: string;
15
+ };
16
+ type EvaluateEvent = {
17
+ name: string;
18
+ data: string;
19
+ timestamp?: Date;
20
+ };
21
+ type Event = {
22
+ id: string;
23
+ templateName: string;
24
+ timestamp: Date;
25
+ spanId: string;
26
+ value: number | string | null;
27
+ };
28
+ type SpanType = 'DEFAULT' | 'LLM';
29
+ type Span = {
30
+ version: string;
31
+ spanType: SpanType;
32
+ id: string;
33
+ parentSpanId: string | null;
34
+ traceId: string;
35
+ name: string;
36
+ startTime: Date;
37
+ endTime: Date | null;
38
+ attributes: Record<string, any>;
39
+ input: any | null;
40
+ output: any | null;
41
+ metadata: Record<string, any> | null;
42
+ evaluateEvents: EvaluateEvent[];
43
+ events: Event[];
44
+ };
45
+ type Trace = {
46
+ id: string;
47
+ version: string;
48
+ success: boolean;
49
+ startTime: Date | null;
50
+ endTime: Date | null;
51
+ userId: string | null;
52
+ sessionId: string | null;
53
+ release: string;
54
+ metadata: Record<string, any> | null;
55
+ };
56
+
57
+ declare class Collector {
58
+ private readonly flushInterval;
59
+ private readonly client;
60
+ private readonly maxQueueSize;
61
+ private queue;
62
+ private flushTimeout;
63
+ constructor();
64
+ addTask(task: Span | Trace): void;
65
+ private flush;
66
+ }
67
+
68
+ interface CreateSpanProps {
69
+ input?: any | null;
70
+ metadata?: Record<string, any> | null;
71
+ attributes?: Record<string, any>;
72
+ spanType?: SpanType;
73
+ }
74
+ declare class ObservationContext {
75
+ protected observation: Span | Trace;
76
+ parent: ObservationContext | null;
77
+ children: Record<string, SpanContext>;
78
+ protected collector: Collector;
79
+ constructor(observation: Span | Trace, parent: ObservationContext | null);
80
+ id(): string;
81
+ span(name: string, { input, metadata, attributes, spanType, }?: CreateSpanProps): SpanContext;
82
+ }
83
+ interface UpdateSpanProps {
84
+ input?: any | null;
85
+ output?: any | null;
86
+ metadata?: Record<string, any> | null;
87
+ attributes?: Record<string, any>;
88
+ evaluateEvents?: EvaluateEvent[];
89
+ override?: boolean;
90
+ }
91
+ interface SpanEventProps {
92
+ value?: string | number | boolean;
93
+ timestamp?: Date;
94
+ }
95
+ interface SpanEvaluateEventProps {
96
+ timestamp?: Date;
97
+ }
98
+ declare class SpanContext extends ObservationContext {
99
+ private inerSpan;
100
+ constructor(span: Span, parent: ObservationContext);
101
+ end({ input, output, metadata, attributes, evaluateEvents, override }?: UpdateSpanProps): SpanContext;
102
+ update({ input, output, metadata, attributes, evaluateEvents, override }: UpdateSpanProps): SpanContext;
103
+ event(templateName: string, { value, timestamp, }?: SpanEventProps): SpanContext;
104
+ evalueateEvent(templateName: string, data: string, { timestamp }?: SpanEvaluateEventProps): SpanContext;
105
+ private getParent;
106
+ private innerUpdate;
107
+ }
108
+ interface UpdateTraceProps {
109
+ success?: boolean;
110
+ userId?: string | null;
111
+ sessionId?: string | null;
112
+ release?: string;
113
+ metadata?: Record<string, any> | null;
114
+ }
115
+ declare class TraceContext extends ObservationContext {
116
+ private trace;
117
+ constructor(trace: Trace, parent: ObservationContext | null);
118
+ update({ success, userId, sessionId, release, metadata }?: UpdateTraceProps): TraceContext;
119
+ }
120
+ interface TraceProps {
121
+ userId?: string | null;
122
+ sessionId?: string | null;
123
+ release?: string;
124
+ metadata?: Record<string, any> | null;
125
+ }
126
+ declare const trace: ({ userId, sessionId, release, metadata, }?: TraceProps) => TraceContext;
127
+
128
+ declare class Laminar {
129
+ private readonly projectApiKey;
130
+ private readonly url;
131
+ private readonly response;
132
+ constructor(projectApiKey: string);
133
+ run({ pipeline, inputs, env, metadata, }: PipelineRunRequest): Promise<PipelineRunResponse>;
134
+ }
135
+
136
+ export { type ChatMessage, type EvaluateEvent, type Event, Laminar, type NodeInput, ObservationContext, type PipelineRunRequest, type PipelineRunResponse, type Span, SpanContext, type Trace, TraceContext, trace };
package/dist/index.js ADDED
@@ -0,0 +1,319 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ Laminar: () => Laminar,
24
+ ObservationContext: () => ObservationContext,
25
+ SpanContext: () => SpanContext,
26
+ TraceContext: () => TraceContext,
27
+ trace: () => trace
28
+ });
29
+ module.exports = __toCommonJS(src_exports);
30
+
31
+ // src/types.ts
32
+ var DEFAULT_SPAN_TYPE = "DEFAULT";
33
+
34
+ // src/constants.ts
35
+ var CURRENT_TRACING_VERSION = "0.1.0";
36
+
37
+ // src/tracing.ts
38
+ var Collector = class {
39
+ constructor() {
40
+ this.flushInterval = 2;
41
+ // seconds
42
+ this.client = new Client(process.env.LMNR_PROJECT_API_KEY || "");
43
+ this.maxQueueSize = 1e3;
44
+ this.queue = [];
45
+ this.flushTimeout = setTimeout(this.flush.bind(this), this.flushInterval * 1e3);
46
+ }
47
+ addTask(task) {
48
+ this.queue.push(task);
49
+ if (this.queue.length >= this.maxQueueSize) {
50
+ this.flush();
51
+ }
52
+ if (!this.flushTimeout) {
53
+ this.flushTimeout = setTimeout(this.flush.bind(this), this.flushInterval * 1e3);
54
+ }
55
+ }
56
+ flush() {
57
+ if (this.flushTimeout != null) {
58
+ clearTimeout(this.flushTimeout);
59
+ this.flushTimeout = null;
60
+ }
61
+ if (this.queue.length === 0) {
62
+ return;
63
+ }
64
+ this.client.batchPost(this.queue);
65
+ this.queue = [];
66
+ }
67
+ };
68
+ var CollectorSingleton = class {
69
+ static getInstance() {
70
+ if (this.instance === null) {
71
+ this.instance = new Collector();
72
+ }
73
+ return this.instance;
74
+ }
75
+ };
76
+ CollectorSingleton.instance = null;
77
+ var Client = class {
78
+ constructor(projectApiKey) {
79
+ this.baseUrl = "https://api.lmnr.ai";
80
+ this.projectApiKey = projectApiKey;
81
+ }
82
+ getHeaders() {
83
+ return {
84
+ "Content-Type": "application/json",
85
+ "Authorization": `Bearer ${this.projectApiKey}`
86
+ };
87
+ }
88
+ batchPost(data) {
89
+ const body = JSON.stringify({
90
+ traces: data
91
+ });
92
+ const headers = this.getHeaders();
93
+ const url = `${this.baseUrl}/v1/traces`;
94
+ fetch(url, {
95
+ method: "POST",
96
+ headers,
97
+ body
98
+ }).then((response) => {
99
+ if (!response.ok) {
100
+ console.error("Failed to send traces. Response: ");
101
+ response.text().then((text) => console.error(text));
102
+ }
103
+ }).catch((error) => {
104
+ console.error("Failed to send traces. Error: ", error);
105
+ });
106
+ }
107
+ };
108
+
109
+ // src/utils.ts
110
+ var import_uuid = require("uuid");
111
+ var newUUID = () => {
112
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
113
+ return crypto.randomUUID();
114
+ } else {
115
+ return (0, import_uuid.v4)();
116
+ }
117
+ };
118
+
119
+ // src/interface.ts
120
+ var ObservationContext = class {
121
+ constructor(observation, parent) {
122
+ this.observation = observation;
123
+ this.parent = parent;
124
+ this.children = {};
125
+ this.collector = CollectorSingleton.getInstance();
126
+ }
127
+ id() {
128
+ return this.observation.id;
129
+ }
130
+ span(name, {
131
+ input,
132
+ metadata,
133
+ attributes,
134
+ spanType
135
+ } = {}) {
136
+ const parent = this;
137
+ const parentSpanId = parent instanceof SpanContext ? parent.observation.id : null;
138
+ const traceId = parent instanceof TraceContext ? parent.observation.id : parent.observation.traceId;
139
+ const span = {
140
+ version: CURRENT_TRACING_VERSION,
141
+ spanType: spanType != null ? spanType : DEFAULT_SPAN_TYPE,
142
+ id: newUUID(),
143
+ parentSpanId,
144
+ traceId,
145
+ name,
146
+ startTime: /* @__PURE__ */ new Date(),
147
+ endTime: null,
148
+ attributes: attributes != null ? attributes : {},
149
+ input: input != null ? input : null,
150
+ output: null,
151
+ metadata: metadata != null ? metadata : null,
152
+ evaluateEvents: [],
153
+ events: []
154
+ };
155
+ const spanContext = new SpanContext(span, this);
156
+ this.children[span.id] = spanContext;
157
+ return spanContext;
158
+ }
159
+ };
160
+ var SpanContext = class extends ObservationContext {
161
+ constructor(span, parent) {
162
+ super(span, parent);
163
+ this.inerSpan = span;
164
+ }
165
+ end({
166
+ input,
167
+ output,
168
+ metadata,
169
+ attributes,
170
+ evaluateEvents,
171
+ override
172
+ } = {}) {
173
+ if (this.children && Object.keys(this.children).length > 0) {
174
+ console.warn(`Ending span ${this.observation.id}, but it has children that have not been finalized. Children: ${Object.values(this.children).map((child) => child.inerSpan.name)}`);
175
+ }
176
+ delete this.getParent().children[this.inerSpan.id];
177
+ this.innerUpdate(input, output, metadata, attributes, evaluateEvents, override, true);
178
+ return this;
179
+ }
180
+ update({
181
+ input,
182
+ output,
183
+ metadata,
184
+ attributes,
185
+ evaluateEvents,
186
+ override
187
+ }) {
188
+ return this.innerUpdate(input, output, metadata, attributes, evaluateEvents, override, false);
189
+ }
190
+ event(templateName, {
191
+ value,
192
+ timestamp
193
+ } = {}) {
194
+ const event = {
195
+ id: newUUID(),
196
+ templateName,
197
+ timestamp: timestamp != null ? timestamp : /* @__PURE__ */ new Date(),
198
+ spanId: this.inerSpan.id,
199
+ value: value != null ? value : null
200
+ };
201
+ this.inerSpan.events.push(event);
202
+ return this;
203
+ }
204
+ evalueateEvent(templateName, data, {
205
+ timestamp
206
+ } = {}) {
207
+ const event = {
208
+ name: templateName,
209
+ data,
210
+ timestamp: timestamp != null ? timestamp : /* @__PURE__ */ new Date()
211
+ };
212
+ this.inerSpan.evaluateEvents.push(event);
213
+ return this;
214
+ }
215
+ getParent() {
216
+ return this.parent;
217
+ }
218
+ innerUpdate(input, output, metadata, attributes, evaluateEvents, override, finalize) {
219
+ const newMetadata = override ? metadata : { ...this.observation.metadata, ...metadata != null ? metadata : {} };
220
+ const newAttributes = override ? attributes : { ...this.inerSpan.attributes, ...attributes != null ? attributes : {} };
221
+ const newEvaluateEvents = override ? evaluateEvents : [...this.inerSpan.evaluateEvents, ...evaluateEvents != null ? evaluateEvents : []];
222
+ this.inerSpan.input = input || this.inerSpan.input;
223
+ this.inerSpan.output = output || this.inerSpan.output;
224
+ this.inerSpan.metadata = newMetadata != null ? newMetadata : null;
225
+ this.inerSpan.attributes = newAttributes != null ? newAttributes : {};
226
+ this.inerSpan.evaluateEvents = newEvaluateEvents != null ? newEvaluateEvents : [];
227
+ if (finalize) {
228
+ this.inerSpan.endTime = /* @__PURE__ */ new Date();
229
+ this.collector.addTask(this.inerSpan);
230
+ }
231
+ return this;
232
+ }
233
+ };
234
+ var TraceContext = class extends ObservationContext {
235
+ constructor(trace2, parent) {
236
+ super(trace2, parent);
237
+ this.trace = trace2;
238
+ this.collector.addTask(this.trace);
239
+ }
240
+ update({
241
+ success,
242
+ userId,
243
+ sessionId,
244
+ release,
245
+ metadata
246
+ } = {}) {
247
+ const newMetadata = metadata ? { ...this.observation.metadata, ...metadata } : this.observation.metadata;
248
+ this.trace.success = success != null ? success : this.trace.success;
249
+ this.trace.userId = userId != null ? userId : this.trace.userId;
250
+ this.trace.sessionId = sessionId != null ? sessionId : this.trace.sessionId;
251
+ this.trace.release = release != null ? release : this.trace.release;
252
+ this.trace.metadata = newMetadata != null ? newMetadata : null;
253
+ this.collector.addTask(this.trace);
254
+ return this;
255
+ }
256
+ };
257
+ var trace = ({
258
+ userId,
259
+ sessionId,
260
+ release,
261
+ metadata
262
+ } = {}) => {
263
+ const trace2 = {
264
+ id: newUUID(),
265
+ version: CURRENT_TRACING_VERSION,
266
+ success: true,
267
+ startTime: /* @__PURE__ */ new Date(),
268
+ endTime: null,
269
+ userId: userId != null ? userId : null,
270
+ sessionId: sessionId != null ? sessionId : newUUID(),
271
+ release: release != null ? release : "v1",
272
+ metadata: metadata != null ? metadata : null
273
+ };
274
+ return new TraceContext(trace2, null);
275
+ };
276
+
277
+ // src/index.ts
278
+ var Laminar = class {
279
+ constructor(projectApiKey) {
280
+ this.response = null;
281
+ this.projectApiKey = projectApiKey != null ? projectApiKey : process.env.LMNR_PROJECT_API_KEY;
282
+ this.url = "https://api.lmnr.ai/v1/pipeline/run";
283
+ }
284
+ async run({
285
+ pipeline,
286
+ inputs,
287
+ env = {},
288
+ metadata = {}
289
+ }) {
290
+ if (this.projectApiKey === void 0) {
291
+ throw new Error(
292
+ "Please initialize the Laminar object with your project API key or set the LMNR_PROJECT_API_KEY environment variable"
293
+ );
294
+ }
295
+ const response = await fetch(this.url, {
296
+ method: "POST",
297
+ headers: {
298
+ "Content-Type": "application/json",
299
+ "Authorization": `Bearer ${this.projectApiKey}`
300
+ },
301
+ body: JSON.stringify({
302
+ inputs,
303
+ pipeline,
304
+ env,
305
+ metadata
306
+ })
307
+ });
308
+ return await response.json();
309
+ }
310
+ };
311
+ // Annotate the CommonJS export names for ESM import in node:
312
+ 0 && (module.exports = {
313
+ Laminar,
314
+ ObservationContext,
315
+ SpanContext,
316
+ TraceContext,
317
+ trace
318
+ });
319
+ //# sourceMappingURL=index.js.map