@lmnr-ai/client 0.8.53 → 0.8.55

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/dist/index.mjs CHANGED
@@ -4,17 +4,15 @@ import pino from "pino";
4
4
  import { PinoPretty } from "pino-pretty";
5
5
  import { v4 } from "uuid";
6
6
  import { errorMessage } from "@lmnr-ai/types";
7
- //#region package.json
8
- var version = "0.8.53";
9
- //#endregion
10
- //#region src/version.ts
7
+ // package.json
8
+ var version = "0.8.55";
9
+ // src/version.ts
11
10
  function getLangVersion() {
12
11
  if (typeof process !== "undefined" && process.versions && process.versions.node) return `node-${process.versions.node}`;
13
12
  if (typeof navigator !== "undefined" && navigator.userAgent) return `browser-${navigator.userAgent}`;
14
13
  return null;
15
14
  }
16
- //#endregion
17
- //#region src/resources/index.ts
15
+ // src/resources/index.ts
18
16
  var BaseResource = class {
19
17
  constructor(baseHttpUrl, auth) {
20
18
  this.baseHttpUrl = baseHttpUrl;
@@ -37,9 +35,22 @@ var BaseResource = class {
37
35
  const errorMsg = await response.text();
38
36
  throw new Error(`${response.status} ${errorMsg}`);
39
37
  }
38
+ /**
39
+ * For routes that answer errors as `{error: "<message>"}` with user-facing
40
+ * text: raise that message instead of the raw JSON body, falling back to the
41
+ * body when it isn't that shape (a proxy error page, a plain-text 413).
42
+ */
43
+ async handleErrorMessage(response) {
44
+ const body = await response.text();
45
+ let message = body;
46
+ try {
47
+ const parsed = JSON.parse(body);
48
+ if (typeof parsed?.error === "string" && parsed.error.length > 0) message = parsed.error;
49
+ } catch {}
50
+ throw new Error(`${response.status} ${message}`);
51
+ }
40
52
  };
41
- //#endregion
42
- //#region src/resources/browser-events.ts
53
+ // src/resources/browser-events.ts
43
54
  var BrowserEventsResource = class extends BaseResource {
44
55
  constructor(baseHttpUrl, auth) {
45
56
  super(baseHttpUrl, auth);
@@ -66,8 +77,7 @@ var BrowserEventsResource = class extends BaseResource {
66
77
  if (!response.ok) await this.handleError(response);
67
78
  }
68
79
  };
69
- //#endregion
70
- //#region src/resources/cli.ts
80
+ // src/resources/cli.ts
71
81
  /**
72
82
  * Locale-aware, case-insensitive comparator for the project listing. Ordering
73
83
  * lives here — the single choke point every CLI surface (the `project list`
@@ -134,8 +144,7 @@ var CliResource = class extends BaseResource {
134
144
  } : { status: "unverifiable" };
135
145
  }
136
146
  };
137
- //#endregion
138
- //#region src/utils.ts
147
+ // src/utils.ts
139
148
  function initializeLogger(options) {
140
149
  const colorize = options?.colorize ?? true;
141
150
  const level = options?.level ?? process.env.LMNR_LOG_LEVEL?.toLowerCase()?.trim() ?? "info";
@@ -193,8 +202,7 @@ const loadEnv = (options) => {
193
202
  quiet
194
203
  });
195
204
  };
196
- //#endregion
197
- //#region src/resources/datasets.ts
205
+ // src/resources/datasets.ts
198
206
  const logger$3 = initializeLogger();
199
207
  const DEFAULT_DATASET_PULL_LIMIT = 100;
200
208
  const DEFAULT_DATASET_PUSH_BATCH_SIZE = 100;
@@ -298,7 +306,8 @@ var DatasetsResource = class extends BaseResource {
298
306
  datapoints: batch.map((point) => ({
299
307
  data: point.data,
300
308
  target: point.target ?? {},
301
- metadata: point.metadata ?? {}
309
+ metadata: point.metadata ?? {},
310
+ taskId: point.taskId
302
311
  })),
303
312
  createDataset
304
313
  })
@@ -336,8 +345,7 @@ var DatasetsResource = class extends BaseResource {
336
345
  return response.json();
337
346
  }
338
347
  };
339
- //#endregion
340
- //#region src/resources/evals.ts
348
+ // src/resources/evals.ts
341
349
  const logger$2 = initializeLogger();
342
350
  const INITIAL_EVALUATION_DATAPOINT_MAX_DATA_LENGTH = 16e6;
343
351
  var EvalsResource = class extends BaseResource {
@@ -414,16 +422,18 @@ var EvalsResource = class extends BaseResource {
414
422
  * @param {T} [options.target] - The target/expected output for evaluators
415
423
  * @param {Record<string, any>} [options.metadata] - Optional metadata
416
424
  * @param {number} [options.index] - Optional index of the datapoint
425
+ * @param {string} [options.taskId] - Optional Task id shared by every Trial of the Task
417
426
  * @param {string} [options.traceId] - Optional trace ID
418
427
  * @returns {Promise<StringUUID>} The datapoint ID
419
428
  */
420
- async createDatapoint({ evalId, data, target, metadata, index, traceId }) {
429
+ async createDatapoint({ evalId, data, target, metadata, index, taskId, traceId }) {
421
430
  const datapointId = newUUID();
422
431
  const partialDatapoint = {
423
432
  id: datapointId,
424
433
  data,
425
434
  target,
426
435
  index: index ?? 0,
436
+ taskId,
427
437
  traceId: traceId ?? newUUID(),
428
438
  executorSpanId: newUUID(),
429
439
  metadata
@@ -534,8 +544,7 @@ var EvalsResource = class extends BaseResource {
534
544
  if (lastResponse && !lastResponse.ok) await this.handleError(lastResponse);
535
545
  }
536
546
  };
537
- //#endregion
538
- //#region src/resources/evaluators.ts
547
+ // src/resources/evaluators.ts
539
548
  /**
540
549
  * Resource for creating evaluator scores
541
550
  */
@@ -597,8 +606,91 @@ var EvaluatorsResource = class extends BaseResource {
597
606
  if (!response.ok) await this.handleError(response);
598
607
  }
599
608
  };
600
- //#endregion
601
- //#region src/resources/llm-profiles.ts
609
+ // src/resources/hosted-evals.ts
610
+ /**
611
+ * Hosted evals: Harbor evals with trials in Laminar-managed sandboxes.
612
+ *
613
+ * - Images: `missingLayers` / `uploadLayer` / `createImage` push an image built
614
+ * locally (layers named by their `diff_id`); trials start from it.
615
+ * - Remote runs: `upload` the `.tar.gz` of the evals folder, then `startRun`
616
+ * to orchestrate it in a Laminar sandbox. Results land in the project as
617
+ * regular evaluations; v0 returns no run status.
618
+ */
619
+ var HostedEvalsResource = class extends BaseResource {
620
+ constructor(baseHttpUrl, auth) {
621
+ super(baseHttpUrl, auth);
622
+ }
623
+ /** The image layers (by `diff_id`) the project hasn't uploaded yet. */
624
+ async missingLayers(diffIds) {
625
+ const response = await fetch(this.url("/images/layers/missing"), {
626
+ method: "POST",
627
+ headers: this.headers(),
628
+ body: JSON.stringify({ diffIds })
629
+ });
630
+ if (!response.ok) await this.handleErrorMessage(response);
631
+ return (await response.json()).missing;
632
+ }
633
+ /**
634
+ * Upload one image layer, gzip-compressed. `diffId` is the digest of its
635
+ * uncompressed tar, as listed in the image config's `rootfs.diff_ids`.
636
+ */
637
+ async uploadLayer(diffId, gzipped) {
638
+ const response = await fetch(this.url(`/images/layers/${diffId}`), {
639
+ method: "PUT",
640
+ headers: {
641
+ ...this.headers(),
642
+ "Content-Type": "application/gzip"
643
+ },
644
+ body: gzipped,
645
+ duplex: "half"
646
+ });
647
+ if (!response.ok) await this.handleErrorMessage(response);
648
+ return await response.json();
649
+ }
650
+ /**
651
+ * Push the image described by `config` (its config JSON, byte for byte) once
652
+ * its layers are uploaded. Returns the manifest digest trials start from.
653
+ */
654
+ async createImage(config) {
655
+ const response = await fetch(this.url("/images"), {
656
+ method: "POST",
657
+ headers: this.headers(),
658
+ body: JSON.stringify({ config })
659
+ });
660
+ if (!response.ok) await this.handleErrorMessage(response);
661
+ return await response.json();
662
+ }
663
+ /**
664
+ * Upload a `.tar.gz` of the `evals/` folder's contents (suites at the archive
665
+ * root). Sent as the raw request body; the server caps it at 1 GiB.
666
+ */
667
+ async upload(archive) {
668
+ const response = await fetch(this.url("/uploads"), {
669
+ method: "POST",
670
+ headers: {
671
+ ...this.headers(),
672
+ "Content-Type": "application/gzip"
673
+ },
674
+ body: archive
675
+ });
676
+ if (!response.ok) await this.handleErrorMessage(response);
677
+ return await response.json();
678
+ }
679
+ /** Start a remote run. Returns once its orchestrator sandbox has started. */
680
+ async startRun(options) {
681
+ const response = await fetch(this.url("/runs"), {
682
+ method: "POST",
683
+ headers: this.headers(),
684
+ body: JSON.stringify(options)
685
+ });
686
+ if (!response.ok) await this.handleErrorMessage(response);
687
+ return await response.json();
688
+ }
689
+ url(path) {
690
+ return `${this.baseHttpUrl}${this.apiPrefix}/hosted-evals${path}`;
691
+ }
692
+ };
693
+ // src/resources/llm-profiles.ts
602
694
  /**
603
695
  * Workspace LLM profile CRUD over the CLI user-token surface
604
696
  * (`/v1/cli/llm-profiles`). Validation is entirely server-side; error messages
@@ -609,27 +701,13 @@ var LlmProfilesResource = class extends BaseResource {
609
701
  constructor(baseHttpUrl, auth) {
610
702
  super(baseHttpUrl, auth);
611
703
  }
612
- /**
613
- * Errors come back as `{error: string}` (matches the signals surface) with
614
- * user-facing text, so unwrap the envelope before raising rather than
615
- * showing the raw JSON body.
616
- */
617
- async raiseLlmProfileError(response) {
618
- const body = await response.text();
619
- let message = body;
620
- try {
621
- const parsed = JSON.parse(body);
622
- if (typeof parsed?.error === "string" && parsed.error.length > 0) message = parsed.error;
623
- } catch {}
624
- throw new Error(`${response.status} ${message}`);
625
- }
626
704
  async request(method, path, body) {
627
705
  const response = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/llm-profiles${path}`, {
628
706
  method,
629
707
  headers: this.headers(),
630
708
  ...body !== void 0 ? { body: JSON.stringify(body) } : {}
631
709
  });
632
- if (!response.ok) await this.raiseLlmProfileError(response);
710
+ if (!response.ok) await this.handleErrorMessage(response);
633
711
  return response;
634
712
  }
635
713
  /**
@@ -657,8 +735,7 @@ var LlmProfilesResource = class extends BaseResource {
657
735
  return (await this.request("DELETE", `/${profileId}`)).json();
658
736
  }
659
737
  };
660
- //#endregion
661
- //#region src/resources/rollout-sessions.ts
738
+ // src/resources/rollout-sessions.ts
662
739
  const logger$1 = initializeLogger();
663
740
  /**
664
741
  * Map the opaque HIT `response` payload onto a {@link CachedSpan} the provider
@@ -847,36 +924,23 @@ var RolloutSessionsResource = class extends BaseResource {
847
924
  if (!response.ok) await this.handleError(response);
848
925
  }
849
926
  };
850
- //#endregion
851
- //#region src/resources/signals.ts
852
- /** Signals CRUD over the CLI user-token surface (`/v1/cli/signals`). */
927
+ // src/resources/signals.ts
928
+ /**
929
+ * Signals CRUD over the CLI user-token surface (`/v1/cli/signals`). Errors come
930
+ * back as `{error}` with user-facing text (e.g. "A signal named X already
931
+ * exists in this project"), raised verbatim by `handleErrorMessage`.
932
+ */
853
933
  var SignalsResource = class extends BaseResource {
854
934
  constructor(baseHttpUrl, auth) {
855
935
  super(baseHttpUrl, auth);
856
936
  }
857
- /**
858
- * Every signal route answers errors as `{ error: "<message>" }`, and those
859
- * messages are written to be shown to the user verbatim (e.g. "A signal named
860
- * X already exists in this project"). The shared `handleError` would surface
861
- * the raw JSON body, so unwrap the envelope here and fall back to it when the
862
- * body isn't the expected shape.
863
- */
864
- async raiseSignalError(response) {
865
- const body = await response.text();
866
- let message = body;
867
- try {
868
- const parsed = JSON.parse(body);
869
- if (typeof parsed?.error === "string" && parsed.error.length > 0) message = parsed.error;
870
- } catch {}
871
- throw new Error(`${response.status} ${message}`);
872
- }
873
937
  async list(name) {
874
938
  const query = name ? `?${new URLSearchParams({ name }).toString()}` : "";
875
939
  const response = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/signals${query}`, {
876
940
  method: "GET",
877
941
  headers: this.headers()
878
942
  });
879
- if (!response.ok) await this.raiseSignalError(response);
943
+ if (!response.ok) await this.handleErrorMessage(response);
880
944
  const body = await response.json();
881
945
  return Array.isArray(body?.signals) ? body.signals : [];
882
946
  }
@@ -885,7 +949,7 @@ var SignalsResource = class extends BaseResource {
885
949
  method: "GET",
886
950
  headers: this.headers()
887
951
  });
888
- if (!response.ok) await this.raiseSignalError(response);
952
+ if (!response.ok) await this.handleErrorMessage(response);
889
953
  return response.json();
890
954
  }
891
955
  /**
@@ -899,7 +963,7 @@ var SignalsResource = class extends BaseResource {
899
963
  method: "GET",
900
964
  headers: this.headers()
901
965
  });
902
- if (!response.ok) await this.raiseSignalError(response);
966
+ if (!response.ok) await this.handleErrorMessage(response);
903
967
  const body = await response.json();
904
968
  return Array.isArray(body?.versions) ? body.versions : [];
905
969
  }
@@ -909,7 +973,7 @@ var SignalsResource = class extends BaseResource {
909
973
  headers: this.headers(),
910
974
  body: JSON.stringify(options)
911
975
  });
912
- if (!response.ok) await this.raiseSignalError(response);
976
+ if (!response.ok) await this.handleErrorMessage(response);
913
977
  return response.json();
914
978
  }
915
979
  /**
@@ -923,7 +987,7 @@ var SignalsResource = class extends BaseResource {
923
987
  headers: this.headers(),
924
988
  body: JSON.stringify(options)
925
989
  });
926
- if (!response.ok) await this.raiseSignalError(response);
990
+ if (!response.ok) await this.handleErrorMessage(response);
927
991
  return response.json();
928
992
  }
929
993
  /** Deletes the signal, its triggers, its alerts, and its ClickHouse events. */
@@ -932,7 +996,7 @@ var SignalsResource = class extends BaseResource {
932
996
  method: "DELETE",
933
997
  headers: this.headers()
934
998
  });
935
- if (!response.ok) await this.raiseSignalError(response);
999
+ if (!response.ok) await this.handleErrorMessage(response);
936
1000
  return response.json();
937
1001
  }
938
1002
  /**
@@ -946,12 +1010,11 @@ var SignalsResource = class extends BaseResource {
946
1010
  headers: this.headers(),
947
1011
  body: JSON.stringify({ traceIds })
948
1012
  });
949
- if (!response.ok) await this.raiseSignalError(response);
1013
+ if (!response.ok) await this.handleErrorMessage(response);
950
1014
  return response.json();
951
1015
  }
952
1016
  };
953
- //#endregion
954
- //#region src/resources/sql.ts
1017
+ // src/resources/sql.ts
955
1018
  var SqlResource = class extends BaseResource {
956
1019
  constructor(baseHttpUrl, auth) {
957
1020
  super(baseHttpUrl, auth);
@@ -982,8 +1045,7 @@ var SqlResource = class extends BaseResource {
982
1045
  return await response.json();
983
1046
  }
984
1047
  };
985
- //#endregion
986
- //#region src/resources/tags.ts
1048
+ // src/resources/tags.ts
987
1049
  /** Resource for tagging traces. */
988
1050
  var TagsResource = class extends BaseResource {
989
1051
  /** Resource for tagging traces. */
@@ -1039,8 +1101,7 @@ var TagsResource = class extends BaseResource {
1039
1101
  return response.json();
1040
1102
  }
1041
1103
  };
1042
- //#endregion
1043
- //#region src/resources/traces.ts
1104
+ // src/resources/traces.ts
1044
1105
  /** Resource for post-factum operations on existing traces. */
1045
1106
  const logger = initializeLogger();
1046
1107
  var TracesResource = class extends BaseResource {
@@ -1119,8 +1180,7 @@ var TracesResource = class extends BaseResource {
1119
1180
  if (!response.ok) await this.handleError(response);
1120
1181
  }
1121
1182
  };
1122
- //#endregion
1123
- //#region src/index.ts
1183
+ // src/index.ts
1124
1184
  var LaminarClient = class LaminarClient {
1125
1185
  constructor({ baseUrl, port, auth, projectApiKey, cliUserProjectId } = {}) {
1126
1186
  loadEnv();
@@ -1135,6 +1195,7 @@ var LaminarClient = class LaminarClient {
1135
1195
  this._datasets = new DatasetsResource(this.baseUrl, this.auth);
1136
1196
  this._evals = new EvalsResource(this.baseUrl, this.auth);
1137
1197
  this._evaluators = new EvaluatorsResource(this.baseUrl, this.auth);
1198
+ this._hostedEvals = new HostedEvalsResource(this.baseUrl, this.auth);
1138
1199
  this._llmProfiles = new LlmProfilesResource(this.baseUrl, this.auth);
1139
1200
  this._rolloutSessions = new RolloutSessionsResource(this.baseUrl, this.auth);
1140
1201
  this._signals = new SignalsResource(this.baseUrl, this.auth);
@@ -1206,6 +1267,9 @@ var LaminarClient = class LaminarClient {
1206
1267
  get evaluators() {
1207
1268
  return this._evaluators;
1208
1269
  }
1270
+ get hostedEvals() {
1271
+ return this._hostedEvals;
1272
+ }
1209
1273
  get llmProfiles() {
1210
1274
  return this._llmProfiles;
1211
1275
  }
@@ -1225,7 +1289,6 @@ var LaminarClient = class LaminarClient {
1225
1289
  return this._traces;
1226
1290
  }
1227
1291
  };
1228
- //#endregion
1229
1292
  export { LaminarClient, RolloutSessionsResource };
1230
1293
 
1231
1294
  //# sourceMappingURL=index.mjs.map