@verdict-ai/sdk 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Verdict contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,22 @@
1
- # Temporary Holding Version
1
+ # @verdict-ai/sdk
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Typed HTTP client for the Verdict REST API.
4
+
5
+ ```bash
6
+ npm install @verdict-ai/sdk
7
+ ```
8
+
9
+ ```ts
10
+ import { Verdict } from "@verdict-ai/sdk";
11
+ const verdict = new Verdict({ baseUrl: "http://localhost:8787" });
12
+ const rubric = await verdict.rubrics.create({
13
+ name: "Presence", criteria: [{ id: "present", name: "Has text",
14
+ judge: { type: "benchmark", method: "length", min: 1 } }],
15
+ });
16
+ const evaluation = await verdict.evaluations.create({
17
+ rubric: rubric.id, inputs: [{ type: "text", text: "Hello Verdict" }],
18
+ });
19
+ console.log(evaluation.aggregate.score);
20
+ ```
21
+
22
+ Requires Node 20 or newer. [Documentation](https://verdict-docs.developerolim.workers.dev/reference/sdk). MIT licensed.
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Reads which rubric versions an environment runs, for a service that evaluates on its own machine with its own model
3
+ * keys (docs/design/control-plane.md §6). The whole environment arrives in one answer and is kept; after `refreshMs`
4
+ * the next call asks the server again — no timer runs, so this works in Workers. A check that fails or is slow never
5
+ * stops the service: it carries on with the versions it holds and says so in `source`.
6
+ */
7
+ import type { Rubric, RubricInput } from "@verdict-ai/core";
8
+ export interface EnvironmentOptions {
9
+ project: string;
10
+ environment: string;
11
+ /** How long an answer is used before the next call asks the server again. Default 60 s. */
12
+ refreshMs?: number;
13
+ /** How long a check may take before the versions already held are used instead. Default 2 s. */
14
+ timeoutMs?: number;
15
+ /** Rubrics to run, by name, while the server has given none: at a cold start it cannot answer, or before a first promotion. */
16
+ fallback?: Record<string, RubricInput>;
17
+ /** Told about every failed check. The reader carries on with what it holds. */
18
+ onError?: (error: unknown) => void;
19
+ /** Clock (tests). */
20
+ now?: () => number;
21
+ }
22
+ export interface EnvironmentRubric {
23
+ rubric: Rubric;
24
+ /** The version that will run — log it with each judgment. */
25
+ versionId: string;
26
+ /** `server`: confirmed by the last check. `stale`: the last check failed, this is what was held. `fallback`: the rubric given in code. */
27
+ source: "server" | "stale" | "fallback";
28
+ }
29
+ export interface EnvironmentReader {
30
+ /** The rubric this environment runs under `name`. Throws only when there is nothing to run: no answer yet and no fallback. */
31
+ rubric(name: string): Promise<EnvironmentRubric>;
32
+ /** Asks the server now, whatever `refreshMs` says. Resolves to whether the check succeeded. */
33
+ refresh(): Promise<boolean>;
34
+ }
35
+ /** GET `path` with these headers, giving up after `timeoutMs`. */
36
+ export type EnvironmentTransport = (path: string, headers: Record<string, string>, timeoutMs: number) => Promise<Response>;
37
+ export declare function environmentReader(send: EnvironmentTransport, options: EnvironmentOptions): EnvironmentReader;
@@ -0,0 +1,76 @@
1
+ import { VerdictError } from "./errors.js";
2
+ const DEFAULT_REFRESH_MS = 60_000;
3
+ const DEFAULT_TIMEOUT_MS = 2_000;
4
+ /** Freezes a document the way the server does; loaded on first use so clients that never read environments stay small. */
5
+ async function freeze(rubric) {
6
+ const { freezeRubric } = await import("@verdict-ai/core");
7
+ const version = await freezeRubric(rubric);
8
+ return { rubric: version.rubric, versionId: version.id };
9
+ }
10
+ /** Every document is used only if it freezes to the id the server named: a changed or cut-off answer is refused whole. */
11
+ async function verified(answer) {
12
+ const kept = new Map();
13
+ for (const pointer of answer.pointers ?? []) {
14
+ const frozen = await freeze(pointer.rubric);
15
+ if (frozen.versionId !== pointer.versionId)
16
+ throw new VerdictError(502, "integrity", `${pointer.name}: the server named ${pointer.versionId}, but the rubric it sent freezes to ${frozen.versionId}`);
17
+ kept.set(pointer.name, frozen);
18
+ }
19
+ return kept;
20
+ }
21
+ async function failure(res) {
22
+ const body = await res.json().catch(() => undefined);
23
+ return new VerdictError(res.status, body?.error?.type ?? "http", body?.error?.message ?? `HTTP ${res.status}`);
24
+ }
25
+ export function environmentReader(send, options) {
26
+ const { project, environment, refreshMs = DEFAULT_REFRESH_MS, timeoutMs = DEFAULT_TIMEOUT_MS, fallback = {}, onError, now = () => Date.now() } = options;
27
+ const path = `/v1/projects/${encodeURIComponent(project)}/environments/${encodeURIComponent(environment)}?include=rubrics`;
28
+ const spares = new Map();
29
+ let held;
30
+ let checkedAt = Number.NEGATIVE_INFINITY, confirmed = false, lastError, checking;
31
+ const check = async () => {
32
+ try {
33
+ const res = await send(path, held?.etag ? { "if-none-match": held.etag } : {}, timeoutMs);
34
+ if (!(res.status === 304 && held)) {
35
+ if (!res.ok)
36
+ throw await failure(res);
37
+ held = { etag: res.headers.get("etag"), rubrics: await verified(await res.json()) };
38
+ }
39
+ confirmed = true;
40
+ }
41
+ catch (error) {
42
+ confirmed = false;
43
+ lastError = error;
44
+ onError?.(error);
45
+ }
46
+ finally {
47
+ checkedAt = now();
48
+ }
49
+ };
50
+ // Calls that arrive during a check wait for that one check.
51
+ const checked = () => (checking ??= check().finally(() => { checking = undefined; }));
52
+ const spare = (name) => (name in fallback ? spares.get(name) ?? spares.set(name, freeze(fallback[name])).get(name) : undefined);
53
+ return {
54
+ async rubric(name) {
55
+ // With nothing to run for this name, waiting out the interval would only delay the error.
56
+ const nothingToRun = !held && !(name in fallback);
57
+ if (now() - checkedAt >= refreshMs || nothingToRun)
58
+ await checked();
59
+ const kept = held?.rubrics.get(name);
60
+ if (kept)
61
+ return { ...kept, source: confirmed ? "server" : "stale" };
62
+ const given = await spare(name);
63
+ if (given)
64
+ return { ...given, source: "fallback" };
65
+ if (held)
66
+ throw new VerdictError(404, "not_promoted", `${environment} in ${project} does not run ${name}, and no fallback rubric was given for it`);
67
+ const why = lastError instanceof Error ? lastError.message : String(lastError);
68
+ throw new VerdictError(lastError instanceof VerdictError ? lastError.status : 0, "environment_unavailable", `could not read ${environment} in ${project} and no fallback rubric was given for ${name}: ${why}`);
69
+ },
70
+ async refresh() {
71
+ await checked();
72
+ return confirmed;
73
+ },
74
+ };
75
+ }
76
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Carries transport status, error type and optional API issues for failed client requests. `details` is the API's
3
+ * whole error object: a refused promotion (`type: "pointer_conflict"`) lists where the pointers are in `details.current`.
4
+ */
5
+ export declare class VerdictError extends Error {
6
+ status: number;
7
+ type: string;
8
+ issues?: unknown | undefined;
9
+ details?: Record<string, unknown> | undefined;
10
+ constructor(status: number, type: string, message: string, issues?: unknown | undefined, details?: Record<string, unknown> | undefined);
11
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Carries transport status, error type and optional API issues for failed client requests. `details` is the API's
3
+ * whole error object: a refused promotion (`type: "pointer_conflict"`) lists where the pointers are in `details.current`.
4
+ */
5
+ export class VerdictError extends Error {
6
+ status;
7
+ type;
8
+ issues;
9
+ details;
10
+ constructor(status, type, message, issues, details) {
11
+ super(message);
12
+ this.status = status;
13
+ this.type = type;
14
+ this.issues = issues;
15
+ this.details = details;
16
+ }
17
+ }
18
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAClB;IAAuB;IAAsC;IAAyB;IAAzG,YAAmB,MAAc,EAAS,IAAY,EAAE,OAAe,EAAS,MAAgB,EAAS,OAAiC;QAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAA1I,WAAM,GAAN,MAAM,CAAQ;QAAS,SAAI,GAAJ,IAAI,CAAQ;QAA0B,WAAM,GAAN,MAAM,CAAU;QAAS,YAAO,GAAP,OAAO,CAA0B;IAAoB,CAAC;CAChK"}
@@ -0,0 +1,602 @@
1
+ /**
2
+ * Provides a typed client for Verdict REST operations and polling.
3
+ * Idempotency replay metadata is preserved; transport failures use VerdictError and Workers-safe fetch.
4
+ */
5
+ import type { CalibrationReport, Aggregation, ComparisonReport, ComparisonReportRequest, Environment, Evaluation, Input, Pointer, Project, ProjectVersion, PromotionEvent, PromotionRequest, Publication, PublicationIssue, PublicationRequest, PublicationResult, PublicListing, PublicPublication, PublicVersionEntry, RollbackRequest, Rubric, RubricInput, RubricName, RunReport, RunReportRequest, Subject, VersionUpload } from "@verdict-ai/core";
6
+ import { type EnvironmentOptions, type EnvironmentReader } from "./environment.js";
7
+ export { VerdictError } from "./errors.js";
8
+ export type { EnvironmentOptions, EnvironmentReader, EnvironmentRubric } from "./environment.js";
9
+ export interface VerdictOptions {
10
+ apiKey?: string;
11
+ baseUrl?: string;
12
+ fetch?: typeof fetch;
13
+ /** Request timeout in ms (sync evaluations can take a while). Default 10 min. */
14
+ timeoutMs?: number;
15
+ /** The organisation requests are about, on servers where one key reaches several (sent as `x-verdict-org`). Other servers ignore it. */
16
+ org?: string;
17
+ }
18
+ /** How a server signs people in from the CLI when it runs the approval itself. */
19
+ export interface BrowserSignIn {
20
+ kind: "browser";
21
+ start: string;
22
+ token: string;
23
+ }
24
+ /** Documents as the control plane returns them: without the tenant they are stored under. */
25
+ export type ProjectView = Omit<Project, "tenantId">;
26
+ export type EnvironmentView = Omit<Environment, "tenantId">;
27
+ export type PointerView = Pick<Pointer, "name" | "versionId" | "updatedAt">;
28
+ export type VersionView = Omit<ProjectVersion, "tenantId">;
29
+ export type PromotionEventView = Omit<PromotionEvent, "tenantId">;
30
+ export type RunReportView = Omit<RunReport, "tenantId">;
31
+ export type ComparisonReportView = Omit<ComparisonReport, "tenantId">;
32
+ export interface EvaluateParams {
33
+ rubric: string | RubricInput;
34
+ inputs?: Input[];
35
+ subject?: Subject;
36
+ name?: string;
37
+ metadata?: Record<string, unknown>;
38
+ webhook?: string;
39
+ includeEvidence?: boolean;
40
+ }
41
+ export type EvaluationView = Omit<Evaluation, "rubric" | "evidence"> & {
42
+ rubric: Pick<Rubric, "id" | "name" | "version" | "aggregation">;
43
+ evidence: Array<Record<string, unknown>>;
44
+ };
45
+ /**
46
+ * Verdict client — mirrors the REST API 1:1.
47
+ *
48
+ * const verdict = new Verdict({ apiKey: "sk_..." });
49
+ * const ev = await verdict.evaluations.create({ rubric: "rub_123", inputs: [{ type: "url", url: "https://..." }] });
50
+ * console.log(ev.aggregate.score, ev.aggregate.grade);
51
+ */
52
+ export declare class Verdict {
53
+ private apiKey?;
54
+ private baseUrl;
55
+ private f;
56
+ private timeoutMs;
57
+ private org;
58
+ constructor(opts?: VerdictOptions);
59
+ request<T>(method: string, path: string, body?: unknown, contentType?: string, headers?: Record<string, string>): Promise<T>;
60
+ requestWithMeta<T>(method: string, path: string, body?: unknown, contentType?: string, headers?: Record<string, string>): Promise<{
61
+ data: T;
62
+ replayed: boolean;
63
+ }>;
64
+ /**
65
+ * What an environment runs, for a service that evaluates locally: `await verdict.environment({ project, environment }).rubric("intent")`
66
+ * resolves to `{ rubric, versionId, source }`. Keep one reader per environment: it holds the versions it received and
67
+ * asks the server again only after `refreshMs`.
68
+ */
69
+ environment(options: EnvironmentOptions): EnvironmentReader;
70
+ /** A GET that gives up after `timeoutMs`, whether or not the fetch in use honours the abort signal. */
71
+ private get;
72
+ rubrics: {
73
+ calibration: (id: string, options?: {
74
+ target?: number;
75
+ buckets?: number;
76
+ limit?: number;
77
+ }) => Promise<CalibrationReport>;
78
+ create: (rubric: RubricInput | string) => Promise<{
79
+ name: string;
80
+ version: string;
81
+ scale: {
82
+ type: "numeric";
83
+ min: number;
84
+ max: number;
85
+ step?: number | undefined;
86
+ } | {
87
+ type: "binary";
88
+ labels?: [string, string] | undefined;
89
+ } | {
90
+ type: "ordinal";
91
+ labels: string[];
92
+ values?: number[] | undefined;
93
+ };
94
+ judges: Record<string, import("@verdict-ai/core").JudgeSpec>;
95
+ defaultJudge: import("@verdict-ai/core").JudgeSpec;
96
+ criteria: {
97
+ id: string;
98
+ name: string;
99
+ weight: number;
100
+ optional: boolean;
101
+ description?: string | undefined;
102
+ scale?: {
103
+ type: "numeric";
104
+ min: number;
105
+ max: number;
106
+ step?: number | undefined;
107
+ } | {
108
+ type: "binary";
109
+ labels?: [string, string] | undefined;
110
+ } | {
111
+ type: "ordinal";
112
+ labels: string[];
113
+ values?: number[] | undefined;
114
+ } | undefined;
115
+ anchors?: Record<string, string> | undefined;
116
+ choices?: Record<string, string> | undefined;
117
+ values?: Record<string, number> | undefined;
118
+ levels?: {
119
+ value: number;
120
+ description: string;
121
+ label?: string | undefined;
122
+ }[] | undefined;
123
+ threshold?: number | undefined;
124
+ judge?: import("@verdict-ai/core").JudgeSpec | import("@verdict-ai/core").JudgeSpec[] | undefined;
125
+ rater?: "min" | "max" | "mean" | "median" | "majority" | "trimmed_mean" | undefined;
126
+ inputs?: string[] | undefined;
127
+ group?: string | undefined;
128
+ }[];
129
+ aggregation: {
130
+ method: "min" | "max" | "formula" | "mean" | "median" | "weighted_mean" | "weighted_sum" | "geometric_mean";
131
+ rater: "min" | "max" | "mean" | "median" | "majority" | "trimmed_mean";
132
+ normalize: false | [number, number];
133
+ missing: "fail" | "exclude" | "zero";
134
+ gates: {
135
+ criterion: string;
136
+ min?: number | undefined;
137
+ max?: number | undefined;
138
+ message?: string | undefined;
139
+ }[];
140
+ precision: number;
141
+ formula?: string | undefined;
142
+ grades?: {
143
+ label: string;
144
+ min: number;
145
+ }[] | undefined;
146
+ passThreshold?: number | undefined;
147
+ };
148
+ id?: string | undefined;
149
+ description?: string | undefined;
150
+ context?: string | undefined;
151
+ language?: string | undefined;
152
+ checks?: {
153
+ id: string;
154
+ question: string;
155
+ expect: boolean;
156
+ threshold: number;
157
+ action: "abort" | "fail" | "flag";
158
+ criteria?: {
159
+ true: string;
160
+ false: string;
161
+ } | undefined;
162
+ message?: string | undefined;
163
+ }[] | undefined;
164
+ checksJudge?: import("@verdict-ai/core").JudgeSpec | undefined;
165
+ inputSchema?: import("@verdict-ai/core").InputSchema | undefined;
166
+ metadata?: Record<string, unknown> | undefined;
167
+ } & {
168
+ id: string;
169
+ }>;
170
+ validate: (rubric: RubricInput | string) => Promise<{
171
+ valid: boolean;
172
+ rubric?: Rubric;
173
+ error?: unknown;
174
+ }>;
175
+ get: (id: string) => Promise<{
176
+ name: string;
177
+ version: string;
178
+ scale: {
179
+ type: "numeric";
180
+ min: number;
181
+ max: number;
182
+ step?: number | undefined;
183
+ } | {
184
+ type: "binary";
185
+ labels?: [string, string] | undefined;
186
+ } | {
187
+ type: "ordinal";
188
+ labels: string[];
189
+ values?: number[] | undefined;
190
+ };
191
+ judges: Record<string, import("@verdict-ai/core").JudgeSpec>;
192
+ defaultJudge: import("@verdict-ai/core").JudgeSpec;
193
+ criteria: {
194
+ id: string;
195
+ name: string;
196
+ weight: number;
197
+ optional: boolean;
198
+ description?: string | undefined;
199
+ scale?: {
200
+ type: "numeric";
201
+ min: number;
202
+ max: number;
203
+ step?: number | undefined;
204
+ } | {
205
+ type: "binary";
206
+ labels?: [string, string] | undefined;
207
+ } | {
208
+ type: "ordinal";
209
+ labels: string[];
210
+ values?: number[] | undefined;
211
+ } | undefined;
212
+ anchors?: Record<string, string> | undefined;
213
+ choices?: Record<string, string> | undefined;
214
+ values?: Record<string, number> | undefined;
215
+ levels?: {
216
+ value: number;
217
+ description: string;
218
+ label?: string | undefined;
219
+ }[] | undefined;
220
+ threshold?: number | undefined;
221
+ judge?: import("@verdict-ai/core").JudgeSpec | import("@verdict-ai/core").JudgeSpec[] | undefined;
222
+ rater?: "min" | "max" | "mean" | "median" | "majority" | "trimmed_mean" | undefined;
223
+ inputs?: string[] | undefined;
224
+ group?: string | undefined;
225
+ }[];
226
+ aggregation: {
227
+ method: "min" | "max" | "formula" | "mean" | "median" | "weighted_mean" | "weighted_sum" | "geometric_mean";
228
+ rater: "min" | "max" | "mean" | "median" | "majority" | "trimmed_mean";
229
+ normalize: false | [number, number];
230
+ missing: "fail" | "exclude" | "zero";
231
+ gates: {
232
+ criterion: string;
233
+ min?: number | undefined;
234
+ max?: number | undefined;
235
+ message?: string | undefined;
236
+ }[];
237
+ precision: number;
238
+ formula?: string | undefined;
239
+ grades?: {
240
+ label: string;
241
+ min: number;
242
+ }[] | undefined;
243
+ passThreshold?: number | undefined;
244
+ };
245
+ id?: string | undefined;
246
+ description?: string | undefined;
247
+ context?: string | undefined;
248
+ language?: string | undefined;
249
+ checks?: {
250
+ id: string;
251
+ question: string;
252
+ expect: boolean;
253
+ threshold: number;
254
+ action: "abort" | "fail" | "flag";
255
+ criteria?: {
256
+ true: string;
257
+ false: string;
258
+ } | undefined;
259
+ message?: string | undefined;
260
+ }[] | undefined;
261
+ checksJudge?: import("@verdict-ai/core").JudgeSpec | undefined;
262
+ inputSchema?: import("@verdict-ai/core").InputSchema | undefined;
263
+ metadata?: Record<string, unknown> | undefined;
264
+ } & {
265
+ id: string;
266
+ }>;
267
+ list: () => Promise<{
268
+ data: Array<Rubric & {
269
+ id: string;
270
+ }>;
271
+ }>;
272
+ update: (id: string, rubric: RubricInput) => Promise<{
273
+ name: string;
274
+ version: string;
275
+ scale: {
276
+ type: "numeric";
277
+ min: number;
278
+ max: number;
279
+ step?: number | undefined;
280
+ } | {
281
+ type: "binary";
282
+ labels?: [string, string] | undefined;
283
+ } | {
284
+ type: "ordinal";
285
+ labels: string[];
286
+ values?: number[] | undefined;
287
+ };
288
+ judges: Record<string, import("@verdict-ai/core").JudgeSpec>;
289
+ defaultJudge: import("@verdict-ai/core").JudgeSpec;
290
+ criteria: {
291
+ id: string;
292
+ name: string;
293
+ weight: number;
294
+ optional: boolean;
295
+ description?: string | undefined;
296
+ scale?: {
297
+ type: "numeric";
298
+ min: number;
299
+ max: number;
300
+ step?: number | undefined;
301
+ } | {
302
+ type: "binary";
303
+ labels?: [string, string] | undefined;
304
+ } | {
305
+ type: "ordinal";
306
+ labels: string[];
307
+ values?: number[] | undefined;
308
+ } | undefined;
309
+ anchors?: Record<string, string> | undefined;
310
+ choices?: Record<string, string> | undefined;
311
+ values?: Record<string, number> | undefined;
312
+ levels?: {
313
+ value: number;
314
+ description: string;
315
+ label?: string | undefined;
316
+ }[] | undefined;
317
+ threshold?: number | undefined;
318
+ judge?: import("@verdict-ai/core").JudgeSpec | import("@verdict-ai/core").JudgeSpec[] | undefined;
319
+ rater?: "min" | "max" | "mean" | "median" | "majority" | "trimmed_mean" | undefined;
320
+ inputs?: string[] | undefined;
321
+ group?: string | undefined;
322
+ }[];
323
+ aggregation: {
324
+ method: "min" | "max" | "formula" | "mean" | "median" | "weighted_mean" | "weighted_sum" | "geometric_mean";
325
+ rater: "min" | "max" | "mean" | "median" | "majority" | "trimmed_mean";
326
+ normalize: false | [number, number];
327
+ missing: "fail" | "exclude" | "zero";
328
+ gates: {
329
+ criterion: string;
330
+ min?: number | undefined;
331
+ max?: number | undefined;
332
+ message?: string | undefined;
333
+ }[];
334
+ precision: number;
335
+ formula?: string | undefined;
336
+ grades?: {
337
+ label: string;
338
+ min: number;
339
+ }[] | undefined;
340
+ passThreshold?: number | undefined;
341
+ };
342
+ id?: string | undefined;
343
+ description?: string | undefined;
344
+ context?: string | undefined;
345
+ language?: string | undefined;
346
+ checks?: {
347
+ id: string;
348
+ question: string;
349
+ expect: boolean;
350
+ threshold: number;
351
+ action: "abort" | "fail" | "flag";
352
+ criteria?: {
353
+ true: string;
354
+ false: string;
355
+ } | undefined;
356
+ message?: string | undefined;
357
+ }[] | undefined;
358
+ checksJudge?: import("@verdict-ai/core").JudgeSpec | undefined;
359
+ inputSchema?: import("@verdict-ai/core").InputSchema | undefined;
360
+ metadata?: Record<string, unknown> | undefined;
361
+ } & {
362
+ id: string;
363
+ }>;
364
+ delete: (id: string) => Promise<void>;
365
+ };
366
+ evaluations: {
367
+ retry: (id: string) => Promise<{
368
+ id: string;
369
+ status: "queued";
370
+ url: string;
371
+ }>;
372
+ create: (params: EvaluateParams, opts?: {
373
+ idempotencyKey?: string;
374
+ }) => Promise<EvaluationView>;
375
+ createIdempotent: (params: EvaluateParams, key: string) => Promise<{
376
+ evaluation: EvaluationView;
377
+ replayed: boolean;
378
+ }>;
379
+ /** Returns {id,status:"queued"}; poll with `get`, or use a webhook. */
380
+ createAsync: (params: EvaluateParams, opts?: {
381
+ idempotencyKey?: string;
382
+ }) => Promise<{
383
+ id: string;
384
+ status: string;
385
+ url: string;
386
+ }>;
387
+ get: (id: string, opts?: {
388
+ evidence?: boolean;
389
+ }) => Promise<EvaluationView>;
390
+ list: (q?: {
391
+ rubric?: string;
392
+ status?: string;
393
+ limit?: number;
394
+ }) => Promise<{
395
+ data: EvaluationView[];
396
+ }>;
397
+ submitScore: (id: string, s: {
398
+ criterionId: string;
399
+ raterId: string;
400
+ score: number | string;
401
+ rationale?: string;
402
+ confidence?: number;
403
+ }) => Promise<EvaluationView>;
404
+ reaggregate: (id: string, aggregation: Partial<Aggregation>, persist?: boolean) => Promise<EvaluationView>;
405
+ /** Poll until the evaluation leaves running/queued (does not wait for humans unless `waitForHumans`). */
406
+ wait: (id: string, opts?: {
407
+ intervalMs?: number;
408
+ waitForHumans?: boolean;
409
+ timeoutMs?: number;
410
+ }) => Promise<EvaluationView>;
411
+ };
412
+ tasks: {
413
+ list: (rater?: string) => Promise<{
414
+ data: Array<{
415
+ evaluationId: string;
416
+ criterionId: string;
417
+ raterId?: string;
418
+ allowedRaters?: string[];
419
+ instructions?: string;
420
+ rubric: string;
421
+ subject?: string;
422
+ }>;
423
+ }>;
424
+ };
425
+ /** Hub sign-in: trade a GitHub token (device flow, run by the caller) for a hub API key bound to that account. */
426
+ hub: {
427
+ config: () => Promise<{
428
+ github: {
429
+ clientId: string;
430
+ } | null;
431
+ publishing: "github" | "tenant";
432
+ signIn?: BrowserSignIn;
433
+ }>;
434
+ login: (githubToken: string) => Promise<{
435
+ apiKey: string;
436
+ keyId: string;
437
+ handle: string;
438
+ tenantId: string;
439
+ }>;
440
+ me: () => Promise<{
441
+ tenantId: string | null;
442
+ handle: string | null;
443
+ github: {
444
+ id: number;
445
+ login: string;
446
+ } | null;
447
+ }>;
448
+ revokeKey: (id: string) => Promise<void>;
449
+ /** Public reads (no key): search cards, read one card at a version with its history, or one publication by id. */
450
+ search: (q?: {
451
+ q?: string;
452
+ domain?: string;
453
+ locale?: string;
454
+ type?: "score" | "noul" | "choice";
455
+ owner?: string;
456
+ limit?: number;
457
+ }) => Promise<{
458
+ data: PublicListing[];
459
+ }>;
460
+ card: (owner: string, slug: string, opts?: {
461
+ version?: string;
462
+ }) => Promise<{
463
+ publication: PublicPublication;
464
+ versions: PublicVersionEntry[];
465
+ }>;
466
+ publication: (id: string) => Promise<PublicPublication>;
467
+ };
468
+ /** Publishing to the public hub: preview shows exactly the document publish would store. */
469
+ publications: {
470
+ preview: (request: PublicationRequest) => Promise<PublicationResult>;
471
+ create: (request: PublicationRequest) => Promise<{
472
+ publication: Publication;
473
+ warnings: PublicationIssue[];
474
+ created: boolean;
475
+ }>;
476
+ list: (opts?: {
477
+ limit?: number;
478
+ }) => Promise<{
479
+ data: Publication[];
480
+ }>;
481
+ withdraw: (id: string) => Promise<void>;
482
+ };
483
+ /** Projects group environments and rubric versions (the control plane). Deleting repeats the name as confirmation. */
484
+ projects: {
485
+ create: (name: string) => Promise<ProjectView>;
486
+ list: () => Promise<{
487
+ data: ProjectView[];
488
+ }>;
489
+ delete: (name: string) => Promise<void>;
490
+ /** Pointer changes of a project, newest first. */
491
+ history: (project: string, q?: {
492
+ environment?: string;
493
+ name?: string;
494
+ limit?: number;
495
+ }) => Promise<{
496
+ data: PromotionEventView[];
497
+ }>;
498
+ };
499
+ /** Environments say which version of each rubric runs. A change names the version the caller saw (`expected`). */
500
+ environments: {
501
+ create: (project: string, name: string) => Promise<EnvironmentView>;
502
+ list: (project: string) => Promise<{
503
+ data: EnvironmentView[];
504
+ }>;
505
+ get: (project: string, name: string) => Promise<EnvironmentView & {
506
+ pointers: PointerView[];
507
+ }>;
508
+ delete: (project: string, name: string) => Promise<void>;
509
+ /** Moves pointers, all or none. `versionId: null` removes a pointer. A stale `expected` throws `pointer_conflict`. */
510
+ promote: (project: string, name: string, request: PromotionRequest) => Promise<{
511
+ events: PromotionEventView[];
512
+ }>;
513
+ /** Undoes the latest change of one pointer. */
514
+ rollback: (project: string, name: string, request: RollbackRequest) => Promise<{
515
+ event: PromotionEventView;
516
+ }>;
517
+ };
518
+ /** Immutable rubric versions kept in a project under the name services ask for. */
519
+ versions: {
520
+ names: (project: string) => Promise<{
521
+ data: RubricName[];
522
+ }>;
523
+ /** Uploads a frozen version; the server freezes the rubric again and refuses another id. */
524
+ push: (project: string, name: string, version: VersionUpload) => Promise<{
525
+ version: VersionView;
526
+ created: boolean;
527
+ }>;
528
+ list: (project: string, name: string, opts?: {
529
+ limit?: number;
530
+ }) => Promise<{
531
+ data: Array<Omit<VersionView, "rubric">>;
532
+ }>;
533
+ get: (project: string, name: string, id: string) => Promise<VersionView>;
534
+ /** Refused with `in_use` while an environment points at the version. */
535
+ delete: (project: string, name: string, id: string) => Promise<void>;
536
+ };
537
+ /** Numbers about runs made elsewhere (your CI). Build requests with `runReportRequest` / `comparisonReportRequest` from core: they copy counts only. */
538
+ reports: {
539
+ run: (project: string, request: RunReportRequest) => Promise<{
540
+ report: RunReportView;
541
+ created: boolean;
542
+ }>;
543
+ runs: (project: string, q?: {
544
+ name?: string;
545
+ versionId?: string;
546
+ dataset?: string;
547
+ limit?: number;
548
+ }) => Promise<{
549
+ data: RunReportView[];
550
+ }>;
551
+ getRun: (project: string, runId: string) => Promise<RunReportView>;
552
+ /** Both runs must have been reported first. */
553
+ comparison: (project: string, request: ComparisonReportRequest) => Promise<{
554
+ report: ComparisonReportView;
555
+ created: boolean;
556
+ }>;
557
+ comparisons: (project: string, q?: {
558
+ name?: string;
559
+ head?: string;
560
+ limit?: number;
561
+ }) => Promise<{
562
+ data: ComparisonReportView[];
563
+ }>;
564
+ };
565
+ batches: {
566
+ create: (params: BatchParams, opts?: {
567
+ idempotencyKey?: string;
568
+ }) => Promise<BatchResult>;
569
+ createIdempotent: (params: BatchParams, key: string) => Promise<{
570
+ replayed: boolean;
571
+ ranking: Array<{
572
+ rank: number;
573
+ evaluationId: string;
574
+ subject: string;
575
+ score?: number;
576
+ grade?: string;
577
+ passed?: boolean;
578
+ status: string;
579
+ }>;
580
+ evaluations: EvaluationView[];
581
+ }>;
582
+ };
583
+ }
584
+ export default Verdict;
585
+ export interface BatchParams {
586
+ rubric: string | RubricInput;
587
+ subjects: Subject[];
588
+ metadata?: Record<string, unknown>;
589
+ webhook?: string;
590
+ }
591
+ export interface BatchResult {
592
+ ranking: Array<{
593
+ rank: number;
594
+ evaluationId: string;
595
+ subject: string;
596
+ score?: number;
597
+ grade?: string;
598
+ passed?: boolean;
599
+ status: string;
600
+ }>;
601
+ evaluations: EvaluationView[];
602
+ }
package/dist/index.js ADDED
@@ -0,0 +1,215 @@
1
+ import { environmentReader } from "./environment.js";
2
+ import { VerdictError } from "./errors.js";
3
+ export { VerdictError } from "./errors.js";
4
+ // why: synchronous judging can be slow; polling uses the same ten-minute default as individual requests.
5
+ const DEFAULT_TIMEOUT_MS = 600_000;
6
+ const DEFAULT_POLL_INTERVAL_MS = 1500;
7
+ /**
8
+ * Verdict client — mirrors the REST API 1:1.
9
+ *
10
+ * const verdict = new Verdict({ apiKey: "sk_..." });
11
+ * const ev = await verdict.evaluations.create({ rubric: "rub_123", inputs: [{ type: "url", url: "https://..." }] });
12
+ * console.log(ev.aggregate.score, ev.aggregate.grade);
13
+ */
14
+ export class Verdict {
15
+ apiKey;
16
+ baseUrl;
17
+ f;
18
+ timeoutMs;
19
+ org;
20
+ constructor(opts = {}) {
21
+ this.org = opts.org ? { "x-verdict-org": opts.org } : {};
22
+ this.apiKey = opts.apiKey ?? globalThis.process?.env?.VERDICT_API_KEY;
23
+ this.baseUrl = (opts.baseUrl ?? globalThis.process?.env?.VERDICT_API_URL ?? "http://localhost:8787").replace(/\/$/, "");
24
+ this.f = opts.fetch ?? ((input, init) => globalThis.fetch(input, init)); // bound call: Workers reject a detached fetch
25
+ this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
26
+ }
27
+ async request(method, path, body, contentType = "application/json", headers) {
28
+ return (await this.requestWithMeta(method, path, body, contentType, headers)).data;
29
+ }
30
+ async requestWithMeta(method, path, body, contentType = "application/json", headers) {
31
+ const ctrl = new AbortController();
32
+ const t = setTimeout(() => ctrl.abort(), this.timeoutMs);
33
+ try {
34
+ const res = await this.f(`${this.baseUrl}${path}`, {
35
+ method,
36
+ signal: ctrl.signal,
37
+ headers: { "content-type": contentType, ...(this.apiKey ? { authorization: `Bearer ${this.apiKey}` } : {}), ...this.org, ...headers },
38
+ body: body === undefined ? undefined : typeof body === "string" ? body : JSON.stringify(body),
39
+ });
40
+ // why: successful deletes have no JSON body to decode.
41
+ if (res.status === 204)
42
+ return { data: undefined, replayed: res.headers.get("Idempotency-Replayed") === "true" };
43
+ const data = await responseBody(res);
44
+ const error = apiError(data);
45
+ // The API returns failed evaluations with 422; these documents remain readable client results.
46
+ if (!res.ok && !(res.status === 422 && !error))
47
+ throw new VerdictError(res.status, error?.type ?? "http", error?.message ?? `HTTP ${res.status}`, error?.issues, error?.details);
48
+ return { data: data, replayed: res.headers.get("Idempotency-Replayed") === "true" };
49
+ }
50
+ catch (error) {
51
+ if (error instanceof VerdictError)
52
+ throw error;
53
+ throw new VerdictError(0, "network", `Verdict request failed: ${error instanceof Error ? error.message : String(error)}`);
54
+ }
55
+ finally {
56
+ clearTimeout(t);
57
+ }
58
+ }
59
+ /**
60
+ * What an environment runs, for a service that evaluates locally: `await verdict.environment({ project, environment }).rubric("intent")`
61
+ * resolves to `{ rubric, versionId, source }`. Keep one reader per environment: it holds the versions it received and
62
+ * asks the server again only after `refreshMs`.
63
+ */
64
+ environment(options) {
65
+ return environmentReader((path, headers, timeoutMs) => this.get(path, headers, timeoutMs), options);
66
+ }
67
+ /** A GET that gives up after `timeoutMs`, whether or not the fetch in use honours the abort signal. */
68
+ async get(path, headers, timeoutMs) {
69
+ const ctrl = new AbortController();
70
+ let timer;
71
+ const late = new Promise((_, reject) => { timer = setTimeout(() => { ctrl.abort(); reject(new VerdictError(408, "timeout", `no answer from ${this.baseUrl} within ${timeoutMs} ms`)); }, timeoutMs); });
72
+ const asked = this.f(`${this.baseUrl}${path}`, { method: "GET", signal: ctrl.signal, headers: { ...(this.apiKey ? { authorization: `Bearer ${this.apiKey}` } : {}), ...this.org, ...headers } });
73
+ // An abort also rejects the fetch; that rejection has been answered by `late` already.
74
+ asked.catch(() => undefined);
75
+ try {
76
+ return await Promise.race([asked, late]);
77
+ }
78
+ catch (error) {
79
+ throw error instanceof VerdictError ? error : new VerdictError(0, "network", `Verdict request failed: ${error instanceof Error ? error.message : String(error)}`);
80
+ }
81
+ finally {
82
+ clearTimeout(timer);
83
+ }
84
+ }
85
+ rubrics = {
86
+ calibration: (id, options = {}) => this.request("GET", `/v1/rubrics/${encodeURIComponent(id)}/calibration?${new URLSearchParams(Object.entries(options).filter(([, v]) => v !== undefined).map(([k, v]) => [k, String(v)]))}`),
87
+ create: (rubric) => typeof rubric === "string" ? this.request("POST", "/v1/rubrics", rubric, "application/yaml") : this.request("POST", "/v1/rubrics", rubric),
88
+ validate: (rubric) => this.request("POST", "/v1/rubrics/validate", rubric, typeof rubric === "string" ? "application/yaml" : "application/json"),
89
+ get: (id) => this.request("GET", `/v1/rubrics/${id}`),
90
+ list: () => this.request("GET", "/v1/rubrics"),
91
+ update: (id, rubric) => this.request("PUT", `/v1/rubrics/${id}`, rubric),
92
+ delete: (id) => this.request("DELETE", `/v1/rubrics/${id}`),
93
+ };
94
+ evaluations = {
95
+ retry: (id) => this.request("POST", `/v1/evaluations/${encodeURIComponent(id)}/retry`),
96
+ create: (params, opts = {}) => this.request("POST", "/v1/evaluations", params, "application/json", keyHeaders(opts.idempotencyKey)),
97
+ createIdempotent: async (params, key) => {
98
+ const { data: evaluation, replayed } = await this.requestWithMeta("POST", "/v1/evaluations", params, "application/json", keyHeaders(key));
99
+ return { evaluation, replayed };
100
+ },
101
+ /** Returns {id,status:"queued"}; poll with `get`, or use a webhook. */
102
+ createAsync: (params, opts = {}) => this.request("POST", "/v1/evaluations", { ...params, async: true }, "application/json", keyHeaders(opts.idempotencyKey)),
103
+ get: (id, opts = {}) => this.request("GET", `/v1/evaluations/${id}${opts.evidence ? "?evidence=true" : ""}`),
104
+ list: (q = {}) => this.request("GET", `/v1/evaluations?${new URLSearchParams(Object.entries(q).filter(([, v]) => v !== undefined).map(([k, v]) => [k, String(v)]))}`),
105
+ submitScore: (id, s) => this.request("POST", `/v1/evaluations/${id}/scores`, s),
106
+ reaggregate: (id, aggregation, persist = false) => this.request("POST", `/v1/evaluations/${id}/aggregate`, { aggregation, persist }),
107
+ /** Poll until the evaluation leaves running/queued (does not wait for humans unless `waitForHumans`). */
108
+ wait: async (id, opts = {}) => {
109
+ const start = Date.now();
110
+ for (;;) {
111
+ const ev = await this.evaluations.get(id);
112
+ // why: human review can be unbounded, so polling stops at that state unless explicitly requested.
113
+ const settled = ev.status === "completed" || ev.status === "failed" || (ev.status === "pending_human" && !opts.waitForHumans);
114
+ if (settled)
115
+ return ev;
116
+ if (Date.now() - start > (opts.timeoutMs ?? DEFAULT_TIMEOUT_MS))
117
+ throw new VerdictError(408, "timeout", `evaluation ${id} still ${ev.status}`);
118
+ await new Promise((r) => setTimeout(r, opts.intervalMs ?? DEFAULT_POLL_INTERVAL_MS));
119
+ }
120
+ },
121
+ };
122
+ tasks = {
123
+ list: (rater) => this.request("GET", `/v1/tasks${rater ? `?rater=${encodeURIComponent(rater)}` : ""}`),
124
+ };
125
+ /** Hub sign-in: trade a GitHub token (device flow, run by the caller) for a hub API key bound to that account. */
126
+ hub = {
127
+ config: () => this.request("GET", "/v1/hub/config"),
128
+ login: (githubToken) => this.request("POST", "/v1/hub/login", { githubToken }),
129
+ me: () => this.request("GET", "/v1/hub/me"),
130
+ revokeKey: (id) => this.request("DELETE", `/v1/hub/keys/${encodeURIComponent(id)}`),
131
+ /** Public reads (no key): search cards, read one card at a version with its history, or one publication by id. */
132
+ search: (q = {}) => this.request("GET", `/v1/public/rubrics?${new URLSearchParams(Object.entries(q).filter(([, v]) => v !== undefined).map(([k, v]) => [k, String(v)]))}`),
133
+ card: (owner, slug, opts = {}) => this.request("GET", `/v1/public/rubrics/${encodeURIComponent(owner)}/${encodeURIComponent(slug)}${opts.version ? `?version=${encodeURIComponent(opts.version)}` : ""}`),
134
+ publication: (id) => this.request("GET", `/v1/public/publications/${encodeURIComponent(id)}`),
135
+ };
136
+ /** Publishing to the public hub: preview shows exactly the document publish would store. */
137
+ publications = {
138
+ preview: (request) => this.request("POST", "/v1/publications/preview", request),
139
+ create: (request) => this.request("POST", "/v1/publications", request),
140
+ list: (opts = {}) => this.request("GET", `/v1/publications${opts.limit ? `?limit=${opts.limit}` : ""}`),
141
+ withdraw: (id) => this.request("DELETE", `/v1/publications/${encodeURIComponent(id)}`),
142
+ };
143
+ /** Projects group environments and rubric versions (the control plane). Deleting repeats the name as confirmation. */
144
+ projects = {
145
+ create: (name) => this.request("POST", "/v1/projects", { name }),
146
+ list: () => this.request("GET", "/v1/projects"),
147
+ delete: (name) => this.request("DELETE", `/v1/projects/${seg(name)}`, { confirm: name }),
148
+ /** Pointer changes of a project, newest first. */
149
+ history: (project, q = {}) => this.request("GET", `/v1/projects/${seg(project)}/history${query(q)}`),
150
+ };
151
+ /** Environments say which version of each rubric runs. A change names the version the caller saw (`expected`). */
152
+ environments = {
153
+ create: (project, name) => this.request("POST", `/v1/projects/${seg(project)}/environments`, { name }),
154
+ list: (project) => this.request("GET", `/v1/projects/${seg(project)}/environments`),
155
+ get: (project, name) => this.request("GET", `/v1/projects/${seg(project)}/environments/${seg(name)}`),
156
+ delete: (project, name) => this.request("DELETE", `/v1/projects/${seg(project)}/environments/${seg(name)}`, { confirm: name }),
157
+ /** Moves pointers, all or none. `versionId: null` removes a pointer. A stale `expected` throws `pointer_conflict`. */
158
+ promote: (project, name, request) => this.request("POST", `/v1/projects/${seg(project)}/environments/${seg(name)}/promotions`, request),
159
+ /** Undoes the latest change of one pointer. */
160
+ rollback: (project, name, request) => this.request("POST", `/v1/projects/${seg(project)}/environments/${seg(name)}/rollbacks`, request),
161
+ };
162
+ /** Immutable rubric versions kept in a project under the name services ask for. */
163
+ versions = {
164
+ names: (project) => this.request("GET", `/v1/projects/${seg(project)}/rubrics`),
165
+ /** Uploads a frozen version; the server freezes the rubric again and refuses another id. */
166
+ push: (project, name, version) => this.request("POST", `/v1/projects/${seg(project)}/rubrics/${seg(name)}/versions`, version),
167
+ list: (project, name, opts = {}) => this.request("GET", `/v1/projects/${seg(project)}/rubrics/${seg(name)}/versions${query(opts)}`),
168
+ get: (project, name, id) => this.request("GET", `/v1/projects/${seg(project)}/rubrics/${seg(name)}/versions/${seg(id)}`),
169
+ /** Refused with `in_use` while an environment points at the version. */
170
+ delete: (project, name, id) => this.request("DELETE", `/v1/projects/${seg(project)}/rubrics/${seg(name)}/versions/${seg(id)}`),
171
+ };
172
+ /** Numbers about runs made elsewhere (your CI). Build requests with `runReportRequest` / `comparisonReportRequest` from core: they copy counts only. */
173
+ reports = {
174
+ run: (project, request) => this.request("POST", `/v1/projects/${seg(project)}/reports/runs`, request),
175
+ runs: (project, q = {}) => this.request("GET", `/v1/projects/${seg(project)}/reports/runs${query(q)}`),
176
+ getRun: (project, runId) => this.request("GET", `/v1/projects/${seg(project)}/reports/runs/${seg(runId)}`),
177
+ /** Both runs must have been reported first. */
178
+ comparison: (project, request) => this.request("POST", `/v1/projects/${seg(project)}/reports/comparisons`, request),
179
+ comparisons: (project, q = {}) => this.request("GET", `/v1/projects/${seg(project)}/reports/comparisons${query(q)}`),
180
+ };
181
+ batches = {
182
+ create: (params, opts = {}) => this.request("POST", "/v1/batches", params, "application/json", keyHeaders(opts.idempotencyKey)),
183
+ createIdempotent: async (params, key) => {
184
+ const { data, replayed } = await this.requestWithMeta("POST", "/v1/batches", params, "application/json", keyHeaders(key));
185
+ return { ...data, replayed };
186
+ },
187
+ };
188
+ }
189
+ export default Verdict;
190
+ const seg = encodeURIComponent;
191
+ function query(q) {
192
+ const entries = Object.entries(q).filter(([, v]) => v !== undefined).map(([k, v]) => [k, String(v)]);
193
+ return entries.length ? `?${new URLSearchParams(entries)}` : "";
194
+ }
195
+ function keyHeaders(key) { return key === undefined ? {} : { "Idempotency-Key": key }; }
196
+ async function responseBody(response) {
197
+ try {
198
+ return await response.json();
199
+ }
200
+ catch (cause) {
201
+ const type = response.ok ? "invalid_response" : "http";
202
+ throw new VerdictError(response.status, type, response.ok ? "Verdict returned invalid JSON" : `HTTP ${response.status}`, { cause: cause instanceof Error ? cause.message : String(cause) });
203
+ }
204
+ }
205
+ function apiError(data) {
206
+ if (!data || typeof data !== "object" || !("error" in data))
207
+ return undefined;
208
+ const error = data.error;
209
+ if (!error || typeof error !== "object" || !("type" in error) || !("message" in error))
210
+ return undefined;
211
+ if (typeof error.type !== "string" || typeof error.message !== "string")
212
+ return undefined;
213
+ return { type: error.type, message: error.message, issues: "issues" in error ? error.issues : undefined, details: { ...error } };
214
+ }
215
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,54 @@
1
1
  {
2
2
  "name": "@verdict-ai/sdk",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "Verdict TypeScript SDK — a Resend-style client for the evaluation API.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "dependencies": {
15
+ "@verdict-ai/core": "0.2.0"
16
+ },
17
+ "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/Ustay-coder/verdict.git",
21
+ "directory": "packages/sdk"
22
+ },
23
+ "homepage": "https://github.com/Ustay-coder/verdict#readme",
24
+ "bugs": {
25
+ "url": "https://github.com/Ustay-coder/verdict/issues"
26
+ },
27
+ "keywords": [
28
+ "evaluation",
29
+ "rubric",
30
+ "decision-model",
31
+ "jev",
32
+ "clef",
33
+ "scoring",
34
+ "llm-judge",
35
+ "mcp"
36
+ ],
37
+ "engines": {
38
+ "node": ">=20"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "README.md",
46
+ "LICENSE"
47
+ ],
48
+ "sideEffects": false,
49
+ "scripts": {
50
+ "build": "tsc -p tsconfig.json",
51
+ "typecheck": "tsc -p tsconfig.json --noEmit",
52
+ "test": "vitest run --passWithNoTests"
53
+ }
6
54
  }