pareta 1.3.0 → 2.0.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/README.md +3 -1
- package/dist/index.cjs +177 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -16
- package/dist/index.d.ts +103 -16
- package/dist/index.mjs +176 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,9 @@ head-to-head against frontier models on your own ground truth and prices every
|
|
|
40
40
|
contender honestly:
|
|
41
41
|
|
|
42
42
|
```ts
|
|
43
|
-
const set = await pa.evals.sets.create({
|
|
43
|
+
const set = await pa.evals.sets.create({
|
|
44
|
+
items: [...], intent: "extract vendor, total and date from each invoice",
|
|
45
|
+
});
|
|
44
46
|
const run = await pa.evals.runs.create({
|
|
45
47
|
evalSet: set.id, models: ["auto"], frontier: ["claude-opus-4-7"], wait: true,
|
|
46
48
|
});
|
package/dist/index.cjs
CHANGED
|
@@ -174,7 +174,7 @@ function parseSSE(reader, opts) {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
// src/version.ts
|
|
177
|
-
var VERSION = "
|
|
177
|
+
var VERSION = "2.0.0";
|
|
178
178
|
|
|
179
179
|
// src/money.ts
|
|
180
180
|
var MICRO_PER_CENT = 10000n;
|
|
@@ -341,6 +341,11 @@ var EvalSet = class extends BaseModel {
|
|
|
341
341
|
get scoringStrategy() {
|
|
342
342
|
return this.raw.scoring_strategy ?? null;
|
|
343
343
|
}
|
|
344
|
+
/** The one-sentence success criterion this set was created with (CB1:
|
|
345
|
+
* DATA + INTENT). Required at create. */
|
|
346
|
+
get intent() {
|
|
347
|
+
return this.raw.intent ?? null;
|
|
348
|
+
}
|
|
344
349
|
};
|
|
345
350
|
function evalSetFromCreate(raw) {
|
|
346
351
|
return new EvalSet(raw?.eval_set ?? {});
|
|
@@ -348,6 +353,60 @@ function evalSetFromCreate(raw) {
|
|
|
348
353
|
function evalSetList(raw) {
|
|
349
354
|
return (raw?.eval_sets ?? []).map((e) => new EvalSet(e));
|
|
350
355
|
}
|
|
356
|
+
var ContractProposal = class extends BaseModel {
|
|
357
|
+
get taskId() {
|
|
358
|
+
return this.raw.task_id ?? null;
|
|
359
|
+
}
|
|
360
|
+
get confidence() {
|
|
361
|
+
return this.raw.confidence ?? null;
|
|
362
|
+
}
|
|
363
|
+
get evidence() {
|
|
364
|
+
return this.raw.evidence ?? {};
|
|
365
|
+
}
|
|
366
|
+
get warning() {
|
|
367
|
+
return this.raw.warning ?? null;
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
var ProposalResult = class extends BaseModel {
|
|
371
|
+
get proposals() {
|
|
372
|
+
return (this.raw.proposals ?? []).map((p) => new ContractProposal(p));
|
|
373
|
+
}
|
|
374
|
+
get homogeneous() {
|
|
375
|
+
return Boolean(this.raw.homogeneous);
|
|
376
|
+
}
|
|
377
|
+
get split() {
|
|
378
|
+
return this.raw.split ?? null;
|
|
379
|
+
}
|
|
380
|
+
get conflict() {
|
|
381
|
+
return this.raw.conflict ?? null;
|
|
382
|
+
}
|
|
383
|
+
get closestTask() {
|
|
384
|
+
return this.raw.closest_task ?? null;
|
|
385
|
+
}
|
|
386
|
+
get intent() {
|
|
387
|
+
return this.raw.intent ?? null;
|
|
388
|
+
}
|
|
389
|
+
get message() {
|
|
390
|
+
return this.raw.message ?? null;
|
|
391
|
+
}
|
|
392
|
+
/** True when the binder matched exactly ONE homogeneous SPECIFIC contract at
|
|
393
|
+
* high/medium confidence and no conflict/split — the case `create` auto-binds
|
|
394
|
+
* without a human confirming. The `custom-eval` universal FLOOR is EXCLUDED:
|
|
395
|
+
* the binder offers it only when no specific contract fits, and per the
|
|
396
|
+
* precision ladder the floor is a CHOICE — the user opts in with
|
|
397
|
+
* `task: "custom-eval"`, never a silent auto-bind. */
|
|
398
|
+
get isClean() {
|
|
399
|
+
const props = this.proposals;
|
|
400
|
+
return this.homogeneous && this.conflict == null && this.split == null && props.length === 1 && (props[0].confidence === "high" || props[0].confidence === "medium") && Boolean(props[0].taskId) && props[0].taskId !== "custom-eval";
|
|
401
|
+
}
|
|
402
|
+
/** The task `create` would auto-bind, or null if the result isn't clean. */
|
|
403
|
+
get boundTask() {
|
|
404
|
+
return this.isClean ? this.proposals[0].taskId : null;
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
function proposalResult(raw) {
|
|
408
|
+
return new ProposalResult(raw ?? {});
|
|
409
|
+
}
|
|
351
410
|
var EvalItemResult = class extends BaseModel {
|
|
352
411
|
get idx() {
|
|
353
412
|
return this.raw.idx ?? null;
|
|
@@ -641,6 +700,7 @@ var Tasks = class {
|
|
|
641
700
|
|
|
642
701
|
// src/resources/evals.ts
|
|
643
702
|
var BASE2 = "/v1/eval-sets";
|
|
703
|
+
var PROPOSE = "/v1/eval-sets/propose-contract";
|
|
644
704
|
var RUNS = "/v1/eval-runs";
|
|
645
705
|
var FRONTIER = "/v1/eval/frontier-models";
|
|
646
706
|
var INLINE_MAX = 5 * 1024 * 1024;
|
|
@@ -684,14 +744,59 @@ async function toBlob(file, mimeOverride) {
|
|
|
684
744
|
const mime = mimeOverride || "application/octet-stream";
|
|
685
745
|
return { blob: new Blob([bytes], { type: mime }), filename: "upload", size: bytes.byteLength, mime };
|
|
686
746
|
}
|
|
687
|
-
function
|
|
747
|
+
function requireIntent(intent) {
|
|
748
|
+
const s = (intent ?? "").trim();
|
|
749
|
+
if (!s) {
|
|
750
|
+
throw new ParetaError(
|
|
751
|
+
'intent is required: one sentence describing what the model should do with each item (e.g. "extract vendor, total and date from each invoice"). Pass intent to evals.create / proposeContract.'
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
return s.slice(0, 500);
|
|
755
|
+
}
|
|
756
|
+
function itemsJsonl(task, items, intent, name) {
|
|
688
757
|
if (!items || items.length === 0) throw new ParetaError("items is required and must be non-empty");
|
|
689
758
|
const jsonl = items.map((it) => JSON.stringify(it)).join("\n");
|
|
690
759
|
return {
|
|
691
760
|
files: { items: { filename: `items.${task}.jsonl`, content: jsonl, contentType: "application/jsonl" } },
|
|
692
|
-
data: { task_id: task, name: name || `sdk eval set (${items.length} items)` }
|
|
761
|
+
data: { task_id: task, intent, name: name || `sdk eval set (${items.length} items)` }
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
function proposeMultipart(items, intent) {
|
|
765
|
+
if (!items || items.length === 0) throw new ParetaError("items is required and must be non-empty");
|
|
766
|
+
const jsonl = items.map((it) => JSON.stringify(it)).join("\n");
|
|
767
|
+
return {
|
|
768
|
+
files: { items: { filename: "items.jsonl", content: jsonl, contentType: "application/jsonl" } },
|
|
769
|
+
data: { intent }
|
|
693
770
|
};
|
|
694
771
|
}
|
|
772
|
+
function bindError(result) {
|
|
773
|
+
const intent = result.intent ?? "";
|
|
774
|
+
if (result.conflict) {
|
|
775
|
+
const c = result.conflict;
|
|
776
|
+
return new ParetaError(
|
|
777
|
+
`intent '${intent}' describes a different job than the data's shape supports (reads as '${c.intended_task}': ${c.reasoning}). Pass a task to pin a contract, or revise the intent.`
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
if (result.split) {
|
|
781
|
+
const s = result.split;
|
|
782
|
+
return new ParetaError(
|
|
783
|
+
`the dataset looks MIXED \u2014 ${s.validated_n}/${s.total_n} items fit '${s.closest_task}', the rest a different shape. Split the set or pass a task.`
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
const props = result.proposals;
|
|
787
|
+
if (props.length === 1 && props[0].taskId === "custom-eval") {
|
|
788
|
+
const warn = props[0].warning ? ` (${props[0].warning})` : "";
|
|
789
|
+
return new ParetaError(
|
|
790
|
+
`no specific grading contract fits this data for intent '${intent}'. The custom-eval universal floor is available \u2014 it grades by judged win-rate vs the frontier anchor.${warn} Pass task: "custom-eval" to use it, or revise the data/intent for a specific contract.`
|
|
791
|
+
);
|
|
792
|
+
}
|
|
793
|
+
const options = props.map((p) => p.taskId).filter(Boolean);
|
|
794
|
+
if (options.length === 0 && result.closestTask) options.push(result.closestTask);
|
|
795
|
+
const hint = options.length ? ` Candidates: ${options.join(", ")}.` : "";
|
|
796
|
+
return new ParetaError(
|
|
797
|
+
`could not confidently bind a grading contract for intent '${intent}'.${hint} Pass a task to pin one, or inspect evals.proposeContract({ items, intent }).`
|
|
798
|
+
);
|
|
799
|
+
}
|
|
695
800
|
function mergeCandidates(models, frontierIds) {
|
|
696
801
|
const cands = [...models ?? [], ...frontierIds ?? []];
|
|
697
802
|
if (cands.length === 0) throw new ParetaError("models is required (the open candidates to evaluate)");
|
|
@@ -712,10 +817,30 @@ var EvalSets = class {
|
|
|
712
817
|
this.client = client;
|
|
713
818
|
}
|
|
714
819
|
client;
|
|
715
|
-
|
|
716
|
-
|
|
820
|
+
/**
|
|
821
|
+
* Persist an eval set from your rows. `intent` is REQUIRED (v2): one sentence
|
|
822
|
+
* on what the model should do with each item. `task` is OPTIONAL — omit it and
|
|
823
|
+
* the binder resolves your intent + the data's shape to a grading contract
|
|
824
|
+
* (auto-binds a clean single match; throws with the proposals otherwise). Pass
|
|
825
|
+
* `task` to pin one explicitly.
|
|
826
|
+
*/
|
|
827
|
+
async create(params) {
|
|
828
|
+
const intent = requireIntent(params.intent);
|
|
829
|
+
let task = params.task;
|
|
830
|
+
if (task == null) {
|
|
831
|
+
const proposal = await this.proposeContract(params.items, intent);
|
|
832
|
+
task = proposal.boundTask ?? void 0;
|
|
833
|
+
if (task == null) throw bindError(proposal);
|
|
834
|
+
}
|
|
835
|
+
const { files, data } = itemsJsonl(task, params.items, intent, params.name);
|
|
717
836
|
return this.client.request("POST", BASE2, { files, data, cast: evalSetFromCreate });
|
|
718
837
|
}
|
|
838
|
+
/** Internal: the binder call `create` uses when no task is pinned. Public on
|
|
839
|
+
* `Evals` as `proposeContract`; kept here so `sets.create` can reach it. */
|
|
840
|
+
proposeContract(items, intent) {
|
|
841
|
+
const { files, data } = proposeMultipart(items, requireIntent(intent));
|
|
842
|
+
return this.client.request("POST", PROPOSE, { files, data, cast: proposalResult });
|
|
843
|
+
}
|
|
719
844
|
list() {
|
|
720
845
|
return this.client.request("GET", BASE2, { cast: evalSetList });
|
|
721
846
|
}
|
|
@@ -783,10 +908,15 @@ var EvalRuns = class {
|
|
|
783
908
|
async create(params) {
|
|
784
909
|
let evalSet = params.evalSet;
|
|
785
910
|
if (evalSet == null) {
|
|
786
|
-
if (!
|
|
787
|
-
throw new ParetaError("pass evalSet: <id>, or
|
|
911
|
+
if (!params.items) {
|
|
912
|
+
throw new ParetaError("pass evalSet: <id>, or items (+ intent) to create one");
|
|
788
913
|
}
|
|
789
|
-
evalSet = (await this.sets.create({
|
|
914
|
+
evalSet = (await this.sets.create({
|
|
915
|
+
items: params.items,
|
|
916
|
+
intent: params.intent,
|
|
917
|
+
task: params.task,
|
|
918
|
+
name: params.name
|
|
919
|
+
})).id ?? void 0;
|
|
790
920
|
}
|
|
791
921
|
const frontierIds = await this.frontierIds(params.frontier, evalSet, params.task);
|
|
792
922
|
const candidateModelIds = mergeCandidates(params.models, frontierIds);
|
|
@@ -826,6 +956,15 @@ var Evals = class {
|
|
|
826
956
|
this.client = client;
|
|
827
957
|
}
|
|
828
958
|
client;
|
|
959
|
+
/**
|
|
960
|
+
* Which grading contract fits your data under your stated `intent`? Stateless
|
|
961
|
+
* discovery — nothing is persisted. Returns a ProposalResult (ranked
|
|
962
|
+
* proposals, the auto-bind decision, conflict/split reporting). `sets.create`
|
|
963
|
+
* calls this under the hood; use it directly to preview the binding first.
|
|
964
|
+
*/
|
|
965
|
+
proposeContract(params) {
|
|
966
|
+
return this.sets.proposeContract(params.items, params.intent);
|
|
967
|
+
}
|
|
829
968
|
/**
|
|
830
969
|
* The frontier (vendor) roster you can evaluate against. With `task`, each is
|
|
831
970
|
* annotated `benchmarked` + the roster is vision-filtered for document tasks.
|
|
@@ -917,6 +1056,21 @@ var Audio = class {
|
|
|
917
1056
|
|
|
918
1057
|
// src/resources/images.ts
|
|
919
1058
|
var PATH3 = "/v1/images/generations";
|
|
1059
|
+
var EDIT_PATH = "/v1/images/edits";
|
|
1060
|
+
async function toBase642(image) {
|
|
1061
|
+
if (typeof image === "string") {
|
|
1062
|
+
const { readFile } = await import('fs/promises');
|
|
1063
|
+
return bytesToBase64(new Uint8Array(await readFile(image)));
|
|
1064
|
+
}
|
|
1065
|
+
if (typeof image === "object" && image !== null && "base64" in image) {
|
|
1066
|
+
if (!image.base64 || !image.base64.trim()) throw new ParetaError("image.base64 is empty");
|
|
1067
|
+
return image.base64;
|
|
1068
|
+
}
|
|
1069
|
+
if (image instanceof Blob) return bytesToBase64(new Uint8Array(await image.arrayBuffer()));
|
|
1070
|
+
const bytes = image instanceof Uint8Array ? image : new Uint8Array(image);
|
|
1071
|
+
if (bytes.byteLength === 0) throw new ParetaError("image is empty");
|
|
1072
|
+
return bytesToBase64(bytes);
|
|
1073
|
+
}
|
|
920
1074
|
var Images = class {
|
|
921
1075
|
constructor(client) {
|
|
922
1076
|
this.client = client;
|
|
@@ -935,6 +1089,19 @@ var Images = class {
|
|
|
935
1089
|
cast: (raw) => new ImageGeneration(raw)
|
|
936
1090
|
});
|
|
937
1091
|
}
|
|
1092
|
+
/** Edit one reference image with a plain-language instruction (no mask).
|
|
1093
|
+
* `image` is a file path, raw bytes, a Blob, or `{ base64 }` (≤25MB
|
|
1094
|
+
* decoded). The output keeps the reference's aspect ratio. Billed flat
|
|
1095
|
+
* per edit. */
|
|
1096
|
+
async edit(image, prompt, opts = {}) {
|
|
1097
|
+
if (!prompt || !prompt.trim()) throw new ParetaError("prompt is required");
|
|
1098
|
+
const body = { prompt, image: await toBase642(image) };
|
|
1099
|
+
if (opts.seed !== void 0) body.seed = opts.seed;
|
|
1100
|
+
return this.client.request("POST", EDIT_PATH, {
|
|
1101
|
+
body,
|
|
1102
|
+
cast: (raw) => new ImageGeneration(raw)
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
938
1105
|
};
|
|
939
1106
|
|
|
940
1107
|
// src/resources/retrieval.ts
|
|
@@ -1220,6 +1387,7 @@ exports.ChatCompletion = ChatCompletion;
|
|
|
1220
1387
|
exports.ChatCompletionChunk = ChatCompletionChunk;
|
|
1221
1388
|
exports.Choice = Choice;
|
|
1222
1389
|
exports.ConflictError = ConflictError;
|
|
1390
|
+
exports.ContractProposal = ContractProposal;
|
|
1223
1391
|
exports.Embeddings = Embeddings;
|
|
1224
1392
|
exports.EndpointNotReadyError = EndpointNotReadyError;
|
|
1225
1393
|
exports.EvalItemResult = EvalItemResult;
|
|
@@ -1239,6 +1407,7 @@ exports.NotFoundError = NotFoundError;
|
|
|
1239
1407
|
exports.Pareta = Pareta;
|
|
1240
1408
|
exports.ParetaError = ParetaError;
|
|
1241
1409
|
exports.PermissionDeniedError = PermissionDeniedError;
|
|
1410
|
+
exports.ProposalResult = ProposalResult;
|
|
1242
1411
|
exports.RateLimitError = RateLimitError;
|
|
1243
1412
|
exports.Rerank = Rerank;
|
|
1244
1413
|
exports.RerankResult = RerankResult;
|