@lmnr-ai/client 0.8.54 → 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.cjs +116 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -16
- package/dist/index.d.mts +67 -16
- package/dist/index.mjs +116 -40
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -32,6 +32,12 @@ declare class BaseResource {
|
|
|
32
32
|
Accept: string;
|
|
33
33
|
};
|
|
34
34
|
protected handleError(response: Response): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* For routes that answer errors as `{error: "<message>"}` with user-facing
|
|
37
|
+
* text: raise that message instead of the raw JSON body, falling back to the
|
|
38
|
+
* body when it isn't that shape (a proxy error page, a plain-text 413).
|
|
39
|
+
*/
|
|
40
|
+
protected handleErrorMessage(response: Response): Promise<never>;
|
|
35
41
|
}
|
|
36
42
|
declare class BrowserEventsResource extends BaseResource {
|
|
37
43
|
constructor(baseHttpUrl: string, auth: LaminarAuth);
|
|
@@ -304,6 +310,59 @@ declare class EvaluatorsResource extends BaseResource {
|
|
|
304
310
|
*/
|
|
305
311
|
score(options: ScoreOptions): Promise<void>;
|
|
306
312
|
}
|
|
313
|
+
/** Starts a remote run. See {@link HostedEvalsResource.startRun}. */
|
|
314
|
+
interface StartHostedEvalRunOptions {
|
|
315
|
+
/** Id returned by {@link HostedEvalsResource.upload}. */
|
|
316
|
+
uploadId: string;
|
|
317
|
+
/** The orchestrator runs `lmnr-cli@<cliVersion>`, so the spec format matches. */
|
|
318
|
+
cliVersion: string;
|
|
319
|
+
/**
|
|
320
|
+
* Run spec written by lmnr-cli and read back by the same CLI version. Sent
|
|
321
|
+
* as JSON; the server passes it through without reading it.
|
|
322
|
+
*/
|
|
323
|
+
spec: object;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Hosted evals: Harbor evals with trials in Laminar-managed sandboxes.
|
|
327
|
+
*
|
|
328
|
+
* - Images: `missingLayers` / `uploadLayer` / `createImage` push an image built
|
|
329
|
+
* locally (layers named by their `diff_id`); trials start from it.
|
|
330
|
+
* - Remote runs: `upload` the `.tar.gz` of the evals folder, then `startRun`
|
|
331
|
+
* to orchestrate it in a Laminar sandbox. Results land in the project as
|
|
332
|
+
* regular evaluations; v0 returns no run status.
|
|
333
|
+
*/
|
|
334
|
+
declare class HostedEvalsResource extends BaseResource {
|
|
335
|
+
constructor(baseHttpUrl: string, auth: LaminarAuth);
|
|
336
|
+
/** The image layers (by `diff_id`) the project hasn't uploaded yet. */
|
|
337
|
+
missingLayers(diffIds: string[]): Promise<string[]>;
|
|
338
|
+
/**
|
|
339
|
+
* Upload one image layer, gzip-compressed. `diffId` is the digest of its
|
|
340
|
+
* uncompressed tar, as listed in the image config's `rootfs.diff_ids`.
|
|
341
|
+
*/
|
|
342
|
+
uploadLayer(diffId: string, gzipped: ReadableStream<Uint8Array>): Promise<{
|
|
343
|
+
digest: string;
|
|
344
|
+
size: number;
|
|
345
|
+
}>;
|
|
346
|
+
/**
|
|
347
|
+
* Push the image described by `config` (its config JSON, byte for byte) once
|
|
348
|
+
* its layers are uploaded. Returns the manifest digest trials start from.
|
|
349
|
+
*/
|
|
350
|
+
createImage(config: string): Promise<{
|
|
351
|
+
image: string;
|
|
352
|
+
}>;
|
|
353
|
+
/**
|
|
354
|
+
* Upload a `.tar.gz` of the `evals/` folder's contents (suites at the archive
|
|
355
|
+
* root). Sent as the raw request body; the server caps it at 1 GiB.
|
|
356
|
+
*/
|
|
357
|
+
upload(archive: Uint8Array): Promise<{
|
|
358
|
+
uploadId: string;
|
|
359
|
+
}>;
|
|
360
|
+
/** Start a remote run. Returns once its orchestrator sandbox has started. */
|
|
361
|
+
startRun(options: StartHostedEvalRunOptions): Promise<{
|
|
362
|
+
sandboxId: string;
|
|
363
|
+
}>;
|
|
364
|
+
private url;
|
|
365
|
+
}
|
|
307
366
|
/**
|
|
308
367
|
* Plaintext secrets for create/update. On update this is an OVERLAY: an
|
|
309
368
|
* omitted key keeps the stored secret, so credentials never need re-sending.
|
|
@@ -342,12 +401,6 @@ interface UpdateLlmProfileOptions {
|
|
|
342
401
|
*/
|
|
343
402
|
declare class LlmProfilesResource extends BaseResource {
|
|
344
403
|
constructor(baseHttpUrl: string, auth: LaminarAuth);
|
|
345
|
-
/**
|
|
346
|
-
* Errors come back as `{error: string}` (matches the signals surface) with
|
|
347
|
-
* user-facing text, so unwrap the envelope before raising rather than
|
|
348
|
-
* showing the raw JSON body.
|
|
349
|
-
*/
|
|
350
|
-
private raiseLlmProfileError;
|
|
351
404
|
private request;
|
|
352
405
|
/**
|
|
353
406
|
* Every workspace LLM profile visible to the caller, ordered
|
|
@@ -503,17 +556,13 @@ interface UpdateSignalOptions {
|
|
|
503
556
|
llmProfileId?: string;
|
|
504
557
|
model?: string;
|
|
505
558
|
}
|
|
506
|
-
/**
|
|
559
|
+
/**
|
|
560
|
+
* Signals CRUD over the CLI user-token surface (`/v1/cli/signals`). Errors come
|
|
561
|
+
* back as `{error}` with user-facing text (e.g. "A signal named X already
|
|
562
|
+
* exists in this project"), raised verbatim by `handleErrorMessage`.
|
|
563
|
+
*/
|
|
507
564
|
declare class SignalsResource extends BaseResource {
|
|
508
565
|
constructor(baseHttpUrl: string, auth: LaminarAuth);
|
|
509
|
-
/**
|
|
510
|
-
* Every signal route answers errors as `{ error: "<message>" }`, and those
|
|
511
|
-
* messages are written to be shown to the user verbatim (e.g. "A signal named
|
|
512
|
-
* X already exists in this project"). The shared `handleError` would surface
|
|
513
|
-
* the raw JSON body, so unwrap the envelope here and fall back to it when the
|
|
514
|
-
* body isn't the expected shape.
|
|
515
|
-
*/
|
|
516
|
-
private raiseSignalError;
|
|
517
566
|
list(name?: string): Promise<Signal[]>;
|
|
518
567
|
get(signalId: string): Promise<Signal>;
|
|
519
568
|
/**
|
|
@@ -652,6 +701,7 @@ export declare class LaminarClient {
|
|
|
652
701
|
private _datasets;
|
|
653
702
|
private _evals;
|
|
654
703
|
private _evaluators;
|
|
704
|
+
private _hostedEvals;
|
|
655
705
|
private _llmProfiles;
|
|
656
706
|
private _rolloutSessions;
|
|
657
707
|
private _signals;
|
|
@@ -719,6 +769,7 @@ export declare class LaminarClient {
|
|
|
719
769
|
get datasets(): DatasetsResource;
|
|
720
770
|
get evals(): EvalsResource;
|
|
721
771
|
get evaluators(): EvaluatorsResource;
|
|
772
|
+
get hostedEvals(): HostedEvalsResource;
|
|
722
773
|
get llmProfiles(): LlmProfilesResource;
|
|
723
774
|
get signals(): SignalsResource;
|
|
724
775
|
get rolloutSessions(): RolloutSessionsResource;
|
|
@@ -726,5 +777,5 @@ export declare class LaminarClient {
|
|
|
726
777
|
get tags(): TagsResource;
|
|
727
778
|
get traces(): TracesResource;
|
|
728
779
|
}
|
|
729
|
-
export type { CacheOutcome, CliProject, CreateLlmProfileOptions, CreateSignalOptions, LaminarAuth, LlmProfileSecretsInput, ProjectKeyProbe, UpdateLlmProfileOptions, UpdateSignalOptions };
|
|
780
|
+
export type { CacheOutcome, CliProject, CreateLlmProfileOptions, CreateSignalOptions, LaminarAuth, LlmProfileSecretsInput, ProjectKeyProbe, StartHostedEvalRunOptions, UpdateLlmProfileOptions, UpdateSignalOptions };
|
|
730
781
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { PinoPretty } from "pino-pretty";
|
|
|
5
5
|
import { v4 } from "uuid";
|
|
6
6
|
import { errorMessage } from "@lmnr-ai/types";
|
|
7
7
|
// package.json
|
|
8
|
-
var version = "0.8.
|
|
8
|
+
var version = "0.8.55";
|
|
9
9
|
// src/version.ts
|
|
10
10
|
function getLangVersion() {
|
|
11
11
|
if (typeof process !== "undefined" && process.versions && process.versions.node) return `node-${process.versions.node}`;
|
|
@@ -35,6 +35,20 @@ var BaseResource = class {
|
|
|
35
35
|
const errorMsg = await response.text();
|
|
36
36
|
throw new Error(`${response.status} ${errorMsg}`);
|
|
37
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
|
+
}
|
|
38
52
|
};
|
|
39
53
|
// src/resources/browser-events.ts
|
|
40
54
|
var BrowserEventsResource = class extends BaseResource {
|
|
@@ -592,6 +606,90 @@ var EvaluatorsResource = class extends BaseResource {
|
|
|
592
606
|
if (!response.ok) await this.handleError(response);
|
|
593
607
|
}
|
|
594
608
|
};
|
|
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
|
+
};
|
|
595
693
|
// src/resources/llm-profiles.ts
|
|
596
694
|
/**
|
|
597
695
|
* Workspace LLM profile CRUD over the CLI user-token surface
|
|
@@ -603,27 +701,13 @@ var LlmProfilesResource = class extends BaseResource {
|
|
|
603
701
|
constructor(baseHttpUrl, auth) {
|
|
604
702
|
super(baseHttpUrl, auth);
|
|
605
703
|
}
|
|
606
|
-
/**
|
|
607
|
-
* Errors come back as `{error: string}` (matches the signals surface) with
|
|
608
|
-
* user-facing text, so unwrap the envelope before raising rather than
|
|
609
|
-
* showing the raw JSON body.
|
|
610
|
-
*/
|
|
611
|
-
async raiseLlmProfileError(response) {
|
|
612
|
-
const body = await response.text();
|
|
613
|
-
let message = body;
|
|
614
|
-
try {
|
|
615
|
-
const parsed = JSON.parse(body);
|
|
616
|
-
if (typeof parsed?.error === "string" && parsed.error.length > 0) message = parsed.error;
|
|
617
|
-
} catch {}
|
|
618
|
-
throw new Error(`${response.status} ${message}`);
|
|
619
|
-
}
|
|
620
704
|
async request(method, path, body) {
|
|
621
705
|
const response = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/llm-profiles${path}`, {
|
|
622
706
|
method,
|
|
623
707
|
headers: this.headers(),
|
|
624
708
|
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
625
709
|
});
|
|
626
|
-
if (!response.ok) await this.
|
|
710
|
+
if (!response.ok) await this.handleErrorMessage(response);
|
|
627
711
|
return response;
|
|
628
712
|
}
|
|
629
713
|
/**
|
|
@@ -841,34 +925,22 @@ var RolloutSessionsResource = class extends BaseResource {
|
|
|
841
925
|
}
|
|
842
926
|
};
|
|
843
927
|
// src/resources/signals.ts
|
|
844
|
-
/**
|
|
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
|
+
*/
|
|
845
933
|
var SignalsResource = class extends BaseResource {
|
|
846
934
|
constructor(baseHttpUrl, auth) {
|
|
847
935
|
super(baseHttpUrl, auth);
|
|
848
936
|
}
|
|
849
|
-
/**
|
|
850
|
-
* Every signal route answers errors as `{ error: "<message>" }`, and those
|
|
851
|
-
* messages are written to be shown to the user verbatim (e.g. "A signal named
|
|
852
|
-
* X already exists in this project"). The shared `handleError` would surface
|
|
853
|
-
* the raw JSON body, so unwrap the envelope here and fall back to it when the
|
|
854
|
-
* body isn't the expected shape.
|
|
855
|
-
*/
|
|
856
|
-
async raiseSignalError(response) {
|
|
857
|
-
const body = await response.text();
|
|
858
|
-
let message = body;
|
|
859
|
-
try {
|
|
860
|
-
const parsed = JSON.parse(body);
|
|
861
|
-
if (typeof parsed?.error === "string" && parsed.error.length > 0) message = parsed.error;
|
|
862
|
-
} catch {}
|
|
863
|
-
throw new Error(`${response.status} ${message}`);
|
|
864
|
-
}
|
|
865
937
|
async list(name) {
|
|
866
938
|
const query = name ? `?${new URLSearchParams({ name }).toString()}` : "";
|
|
867
939
|
const response = await fetch(`${this.baseHttpUrl}${this.apiPrefix}/signals${query}`, {
|
|
868
940
|
method: "GET",
|
|
869
941
|
headers: this.headers()
|
|
870
942
|
});
|
|
871
|
-
if (!response.ok) await this.
|
|
943
|
+
if (!response.ok) await this.handleErrorMessage(response);
|
|
872
944
|
const body = await response.json();
|
|
873
945
|
return Array.isArray(body?.signals) ? body.signals : [];
|
|
874
946
|
}
|
|
@@ -877,7 +949,7 @@ var SignalsResource = class extends BaseResource {
|
|
|
877
949
|
method: "GET",
|
|
878
950
|
headers: this.headers()
|
|
879
951
|
});
|
|
880
|
-
if (!response.ok) await this.
|
|
952
|
+
if (!response.ok) await this.handleErrorMessage(response);
|
|
881
953
|
return response.json();
|
|
882
954
|
}
|
|
883
955
|
/**
|
|
@@ -891,7 +963,7 @@ var SignalsResource = class extends BaseResource {
|
|
|
891
963
|
method: "GET",
|
|
892
964
|
headers: this.headers()
|
|
893
965
|
});
|
|
894
|
-
if (!response.ok) await this.
|
|
966
|
+
if (!response.ok) await this.handleErrorMessage(response);
|
|
895
967
|
const body = await response.json();
|
|
896
968
|
return Array.isArray(body?.versions) ? body.versions : [];
|
|
897
969
|
}
|
|
@@ -901,7 +973,7 @@ var SignalsResource = class extends BaseResource {
|
|
|
901
973
|
headers: this.headers(),
|
|
902
974
|
body: JSON.stringify(options)
|
|
903
975
|
});
|
|
904
|
-
if (!response.ok) await this.
|
|
976
|
+
if (!response.ok) await this.handleErrorMessage(response);
|
|
905
977
|
return response.json();
|
|
906
978
|
}
|
|
907
979
|
/**
|
|
@@ -915,7 +987,7 @@ var SignalsResource = class extends BaseResource {
|
|
|
915
987
|
headers: this.headers(),
|
|
916
988
|
body: JSON.stringify(options)
|
|
917
989
|
});
|
|
918
|
-
if (!response.ok) await this.
|
|
990
|
+
if (!response.ok) await this.handleErrorMessage(response);
|
|
919
991
|
return response.json();
|
|
920
992
|
}
|
|
921
993
|
/** Deletes the signal, its triggers, its alerts, and its ClickHouse events. */
|
|
@@ -924,7 +996,7 @@ var SignalsResource = class extends BaseResource {
|
|
|
924
996
|
method: "DELETE",
|
|
925
997
|
headers: this.headers()
|
|
926
998
|
});
|
|
927
|
-
if (!response.ok) await this.
|
|
999
|
+
if (!response.ok) await this.handleErrorMessage(response);
|
|
928
1000
|
return response.json();
|
|
929
1001
|
}
|
|
930
1002
|
/**
|
|
@@ -938,7 +1010,7 @@ var SignalsResource = class extends BaseResource {
|
|
|
938
1010
|
headers: this.headers(),
|
|
939
1011
|
body: JSON.stringify({ traceIds })
|
|
940
1012
|
});
|
|
941
|
-
if (!response.ok) await this.
|
|
1013
|
+
if (!response.ok) await this.handleErrorMessage(response);
|
|
942
1014
|
return response.json();
|
|
943
1015
|
}
|
|
944
1016
|
};
|
|
@@ -1123,6 +1195,7 @@ var LaminarClient = class LaminarClient {
|
|
|
1123
1195
|
this._datasets = new DatasetsResource(this.baseUrl, this.auth);
|
|
1124
1196
|
this._evals = new EvalsResource(this.baseUrl, this.auth);
|
|
1125
1197
|
this._evaluators = new EvaluatorsResource(this.baseUrl, this.auth);
|
|
1198
|
+
this._hostedEvals = new HostedEvalsResource(this.baseUrl, this.auth);
|
|
1126
1199
|
this._llmProfiles = new LlmProfilesResource(this.baseUrl, this.auth);
|
|
1127
1200
|
this._rolloutSessions = new RolloutSessionsResource(this.baseUrl, this.auth);
|
|
1128
1201
|
this._signals = new SignalsResource(this.baseUrl, this.auth);
|
|
@@ -1194,6 +1267,9 @@ var LaminarClient = class LaminarClient {
|
|
|
1194
1267
|
get evaluators() {
|
|
1195
1268
|
return this._evaluators;
|
|
1196
1269
|
}
|
|
1270
|
+
get hostedEvals() {
|
|
1271
|
+
return this._hostedEvals;
|
|
1272
|
+
}
|
|
1197
1273
|
get llmProfiles() {
|
|
1198
1274
|
return this._llmProfiles;
|
|
1199
1275
|
}
|