pareta 0.2.1 → 1.1.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/dist/index.mjs CHANGED
@@ -172,7 +172,7 @@ function parseSSE(reader, opts) {
172
172
  }
173
173
 
174
174
  // src/version.ts
175
- var VERSION = "0.1.0";
175
+ var VERSION = "1.1.0";
176
176
 
177
177
  // src/money.ts
178
178
  var MICRO_PER_CENT = 10000n;
@@ -278,47 +278,6 @@ var ModelList = class extends BaseModel {
278
278
  return this.data[Symbol.iterator]();
279
279
  }
280
280
  };
281
- var Endpoint = class extends BaseModel {
282
- get id() {
283
- return this.raw.id ?? this.raw.name ?? null;
284
- }
285
- get name() {
286
- return this.raw.name ?? null;
287
- }
288
- get model() {
289
- return this.raw.model ?? null;
290
- }
291
- get status() {
292
- return this.raw.status ?? null;
293
- }
294
- // Live list sends camelCase `taskName`; the detail record sends `task`.
295
- get task() {
296
- return this.raw.taskName ?? this.raw.task ?? null;
297
- }
298
- get url() {
299
- return this.raw.url ?? null;
300
- }
301
- get isLive() {
302
- return this.raw.status === "live";
303
- }
304
- /** Structured-extraction endpoints (contract / SEC / ICD …): the system prompt
305
- * the benchmark used. The proxy applies it automatically when you send no
306
- * `system` message (so quality matches the leaderboard by default); returned
307
- * here so you can read it, or override it with your own `system` message.
308
- * `null` when the task has no injectable prompt (see `promptScaffold`). */
309
- get recommendedSystemPrompt() {
310
- return this.raw.recommendedSystemPrompt ?? null;
311
- }
312
- /** Fixed-label classification endpoints: a copy-and-customize `system` prompt
313
- * template. NEVER auto-applied — the categories are yours, not the benchmark's
314
- * — so fill them in and send it as your `system` message. `null` otherwise. */
315
- get promptScaffold() {
316
- return this.raw.promptScaffold ?? null;
317
- }
318
- };
319
- function endpointList(raw) {
320
- return (raw ?? []).map((e) => new Endpoint(e));
321
- }
322
281
  var Task = class extends BaseModel {
323
282
  get id() {
324
283
  return this.raw.id ?? null;
@@ -432,47 +391,6 @@ var EvalResult = class extends BaseModel {
432
391
  return (this.raw.per_item ?? []).map((it) => new EvalItemResult(it));
433
392
  }
434
393
  };
435
- var LeaderboardEntry = class extends BaseModel {
436
- get name() {
437
- return this.raw.name ?? null;
438
- }
439
- get kind() {
440
- return this.raw.kind ?? null;
441
- }
442
- get quality() {
443
- return this.raw.quality ?? null;
444
- }
445
- // Raw integer — sub-cent unit rate, NOT floored (see money.ts).
446
- get costPerRequestMicroUsd() {
447
- return this.raw.cost_per_request_micro_usd ?? null;
448
- }
449
- get contextK() {
450
- return this.raw.context_k ?? null;
451
- }
452
- get runMode() {
453
- return this.raw.run_mode ?? null;
454
- }
455
- };
456
- var Leaderboard = class extends BaseModel {
457
- get taskId() {
458
- return this.raw.task_id ?? null;
459
- }
460
- get metric() {
461
- return this.raw.metric ?? null;
462
- }
463
- get costUnit() {
464
- return this.raw.cost_unit ?? null;
465
- }
466
- get recommended() {
467
- return this.raw.recommended ?? null;
468
- }
469
- get models() {
470
- return (this.raw.models ?? []).map((m) => new LeaderboardEntry(m));
471
- }
472
- get frontier() {
473
- return this.raw.frontier ? new LeaderboardEntry(this.raw.frontier) : null;
474
- }
475
- };
476
394
  var FrontierModel = class extends BaseModel {
477
395
  get id() {
478
396
  return this.raw.id ?? null;
@@ -483,14 +401,11 @@ var FrontierModel = class extends BaseModel {
483
401
  get vision() {
484
402
  return Boolean(this.raw.vision);
485
403
  }
486
- /** Only meaningful when a task was given: it's on that task's leaderboard. */
404
+ /** Only meaningful when a task was given: it has benchmark results on that task. */
487
405
  get benchmarked() {
488
406
  return Boolean(this.raw.benchmarked);
489
407
  }
490
408
  };
491
- function leaderboardFrom(raw) {
492
- return new Leaderboard(raw ?? {});
493
- }
494
409
  function frontierModels(raw) {
495
410
  return (raw?.frontier_models ?? []).map((m) => new FrontierModel(m));
496
411
  }
@@ -528,12 +443,53 @@ var EvalRun = class extends BaseModel {
528
443
  return (this.raw.results ?? []).map((r) => new EvalResult(r));
529
444
  }
530
445
  };
446
+ var RerankResult = class extends BaseModel {
447
+ /** Position of this document in YOUR request's documents array. */
448
+ get index() {
449
+ return Number(this.raw.index ?? -1);
450
+ }
451
+ /** Calibrated P(relevant) in (0, 1) — thresholdable, not just ordinal. */
452
+ get relevanceScore() {
453
+ return Number(this.raw.relevance_score ?? 0);
454
+ }
455
+ };
456
+ var Rerank = class extends BaseModel {
457
+ get results() {
458
+ return (this.raw.results ?? []).map((r) => new RerankResult(r));
459
+ }
460
+ get model() {
461
+ return this.raw.model ?? null;
462
+ }
463
+ get pairs() {
464
+ return this.raw.pairs ?? null;
465
+ }
466
+ /** Map the ranked indices back onto the documents you sent — best first. */
467
+ topDocuments(documents) {
468
+ return this.results.filter((r) => r.index >= 0 && r.index < documents.length).map((r) => documents[r.index]);
469
+ }
470
+ };
471
+ var Embeddings = class extends BaseModel {
472
+ get vectors() {
473
+ const rows = [...this.raw.data ?? []];
474
+ rows.sort((a, b) => Number(a.index ?? 0) - Number(b.index ?? 0));
475
+ return rows.map((r) => r.embedding ?? []);
476
+ }
477
+ get model() {
478
+ return this.raw.model ?? null;
479
+ }
480
+ get promptTokens() {
481
+ return this.raw.usage?.prompt_tokens ?? null;
482
+ }
483
+ get length() {
484
+ return (this.raw.data ?? []).length;
485
+ }
486
+ };
531
487
 
532
488
  // src/resources/chat.ts
533
489
  var PATH = "/v1/chat/completions";
534
490
  function buildBody(params) {
535
491
  const { model, messages, stream, ...extra } = params;
536
- if (!model) throw new ParetaError("model is required (an endpoint id from endpoints.deploy)");
492
+ if (!model) throw new ParetaError('model is required (use "auto")');
537
493
  if (!messages || messages.length === 0) {
538
494
  throw new ParetaError("messages is required and must be non-empty");
539
495
  }
@@ -581,99 +537,19 @@ var Models = class {
581
537
  }
582
538
  };
583
539
 
584
- // src/resources/endpoints.ts
585
- var BASE = "/v1/endpoints";
586
- function buildDeployBody(params) {
587
- const { task, model, name, wait: _wait, ...extra } = params;
588
- if (!task) throw new ParetaError("task is required");
589
- const body = { task, model: model || "recommended", ...extra };
590
- if (name !== void 0) body.name = name;
591
- return body;
592
- }
593
- function endpointFromComplete(data) {
594
- const ep = data && typeof data === "object" ? data.endpoint : null;
595
- return new Endpoint(ep ?? {});
596
- }
597
- function deployError(data) {
598
- const msg = data && typeof data === "object" ? data.message : String(data);
599
- return new ParetaError(`deploy failed: ${msg || "unknown error"}`);
600
- }
601
- var EndpointMetrics = class {
602
- constructor(client, id) {
603
- this.client = client;
604
- this.id = id;
605
- }
606
- client;
607
- id;
608
- performance(params) {
609
- return this.client.request("GET", `${BASE}/${this.id}/performance`, { params });
610
- }
611
- uptime(params) {
612
- return this.client.request("GET", `${BASE}/${this.id}/uptime`, { params });
613
- }
614
- cost(params) {
615
- return this.client.request("GET", `${BASE}/${this.id}/cost`, { params });
616
- }
617
- quality(params) {
618
- return this.client.request("GET", `${BASE}/${this.id}/quality`, { params });
619
- }
620
- activity(params) {
621
- return this.client.request("GET", `${BASE}/${this.id}/activity`, { params });
622
- }
623
- };
624
- var Endpoints = class {
625
- constructor(client) {
626
- this.client = client;
627
- }
628
- client;
629
- deploy(params) {
630
- const body = buildDeployBody(params);
631
- const stream = this.client.stream("POST", BASE, { body, events: true });
632
- if (!params.wait) return stream;
633
- return this.waitForDeploy(stream);
634
- }
635
- async waitForDeploy(stream) {
636
- for await (const ev of stream) {
637
- if (ev.event === "complete") return endpointFromComplete(ev.data);
638
- if (ev.event === "error") throw deployError(ev.data);
639
- }
640
- throw new ParetaError("deploy stream ended without a 'complete' event");
641
- }
642
- list() {
643
- return this.client.request("GET", BASE, { cast: endpointList });
644
- }
645
- retrieve(endpointId) {
646
- return this.client.request("GET", `${BASE}/${endpointId}`, {
647
- cast: (raw) => new Endpoint(raw)
648
- });
649
- }
650
- start(endpointId) {
651
- return this.client.request("POST", `${BASE}/${endpointId}/start`);
652
- }
653
- stop(endpointId) {
654
- return this.client.request("POST", `${BASE}/${endpointId}/stop`);
655
- }
656
- async delete(endpointId) {
657
- await this.client.request("DELETE", `${BASE}/${endpointId}`);
658
- }
659
- metrics(endpointId) {
660
- return new EndpointMetrics(this.client, endpointId);
661
- }
662
- };
663
-
664
540
  // src/resources/tasks.ts
665
- var BASE2 = "/v1/tasks";
541
+ var BASE = "/v1/tasks";
666
542
  var Tasks = class {
667
543
  constructor(client) {
668
544
  this.client = client;
669
545
  }
670
546
  client;
671
547
  list() {
672
- return this.client.request("GET", BASE2, { cast: taskList });
548
+ return this.client.request("GET", BASE, { cast: taskList });
673
549
  }
674
550
  retrieve(taskId, opts = {}) {
675
551
  const params = opts.examplesN !== void 0 ? { examples_n: opts.examplesN } : void 0;
676
- return this.client.request("GET", `${BASE2}/${taskId}`, {
552
+ return this.client.request("GET", `${BASE}/${taskId}`, {
677
553
  params,
678
554
  cast: (raw) => new Task(raw)
679
555
  });
@@ -681,25 +557,15 @@ var Tasks = class {
681
557
  /** Free-text intent → ranked candidate tasks (the Step-0 backend matcher). */
682
558
  match(query, opts = {}) {
683
559
  if (!query || !query.trim()) throw new ParetaError("query is required");
684
- return this.client.request("POST", `${BASE2}/match`, {
560
+ return this.client.request("POST", `${BASE}/match`, {
685
561
  body: { query, top_k: opts.topK ?? 5 },
686
562
  cast: (raw) => new TaskMatch(raw)
687
563
  });
688
564
  }
689
- /** Models ranked by quality/cost for a task (+ recommended + frontier baseline). */
690
- leaderboard(taskId) {
691
- return this.client.request("GET", `${BASE2}/${taskId}/leaderboard`, {
692
- cast: leaderboardFrom
693
- });
694
- }
695
- /** The task's recommended deployable model — what deploy(model:"recommended") resolves to. */
696
- async recommended(taskId) {
697
- return (await this.leaderboard(taskId)).recommended;
698
- }
699
565
  };
700
566
 
701
567
  // src/resources/evals.ts
702
- var BASE3 = "/v1/eval-sets";
568
+ var BASE2 = "/v1/eval-sets";
703
569
  var RUNS = "/v1/eval-runs";
704
570
  var FRONTIER = "/v1/eval/frontier-models";
705
571
  var INLINE_MAX = 5 * 1024 * 1024;
@@ -773,17 +639,17 @@ var EvalSets = class {
773
639
  client;
774
640
  create(params) {
775
641
  const { files, data } = itemsJsonl(params.task, params.items, params.name);
776
- return this.client.request("POST", BASE3, { files, data, cast: evalSetFromCreate });
642
+ return this.client.request("POST", BASE2, { files, data, cast: evalSetFromCreate });
777
643
  }
778
644
  list() {
779
- return this.client.request("GET", BASE3, { cast: evalSetList });
645
+ return this.client.request("GET", BASE2, { cast: evalSetList });
780
646
  }
781
647
  async retrieve(evalSetId) {
782
- const raw = await this.client.request("GET", `${BASE3}/${evalSetId}`);
648
+ const raw = await this.client.request("GET", `${BASE2}/${evalSetId}`);
783
649
  return new EvalSet((raw ?? {}).eval_set ?? {});
784
650
  }
785
651
  async delete(evalSetId) {
786
- await this.client.request("DELETE", `${BASE3}/${evalSetId}`);
652
+ await this.client.request("DELETE", `${BASE2}/${evalSetId}`);
787
653
  }
788
654
  /**
789
655
  * Attach a binary doc (PDF/image) to one row's blob field. Collapses the
@@ -793,14 +659,14 @@ var EvalSets = class {
793
659
  async uploadDocument(evalSetId, file, opts) {
794
660
  const { blob, filename, size, mime } = await toBlob(file, opts.mime);
795
661
  if (size < INLINE_MAX) {
796
- return this.client.request("POST", `${BASE3}/${evalSetId}/attach-blob`, {
662
+ return this.client.request("POST", `${BASE2}/${evalSetId}/attach-blob`, {
797
663
  files: { file: { filename, content: blob, contentType: mime } },
798
664
  data: { idx: String(opts.idx), field_name: opts.fieldName, mime }
799
665
  });
800
666
  }
801
667
  const minted = await this.client.request(
802
668
  "POST",
803
- `${BASE3}/${evalSetId}/blob-upload-url`,
669
+ `${BASE2}/${evalSetId}/blob-upload-url`,
804
670
  { body: { idx: opts.idx, field_name: opts.fieldName, mime, file_size: size } }
805
671
  );
806
672
  const put = await globalThis.fetch(minted.upload_url, {
@@ -812,7 +678,7 @@ var EvalSets = class {
812
678
  if (put.status !== 200 && put.status !== 201) {
813
679
  throw new ParetaError(`blob upload PUT failed: ${put.status}`);
814
680
  }
815
- return this.client.request("POST", `${BASE3}/${evalSetId}/blob-upload-complete`, {
681
+ return this.client.request("POST", `${BASE2}/${evalSetId}/blob-upload-complete`, {
816
682
  body: { idx: opts.idx, field_name: opts.fieldName, storage_uri: minted.storage_uri, mime }
817
683
  });
818
684
  }
@@ -920,9 +786,49 @@ var Auto = class {
920
786
  }
921
787
  };
922
788
 
789
+ // src/resources/retrieval.ts
790
+ function makeRerank(client) {
791
+ return (query, documents, opts = {}) => {
792
+ if (!query || !query.trim()) throw new ParetaError("query is required");
793
+ if (!Array.isArray(documents) || documents.length === 0) {
794
+ throw new ParetaError("documents must be a non-empty array of strings");
795
+ }
796
+ const body = { query, documents };
797
+ if (opts.topN !== void 0) body.top_n = opts.topN;
798
+ return client.request("POST", "/v1/rerank", {
799
+ body,
800
+ cast: (raw) => new Rerank(raw)
801
+ });
802
+ };
803
+ }
804
+ function makeEmbeddings(client) {
805
+ return (input, opts = {}) => {
806
+ const texts = typeof input === "string" ? [input] : input;
807
+ if (!Array.isArray(texts) || texts.length === 0 || texts.some((t) => typeof t !== "string" || !t.trim())) {
808
+ throw new ParetaError("input must be a non-empty string or array of non-empty strings");
809
+ }
810
+ if (opts.inputType !== void 0 && opts.inputType !== "query" && opts.inputType !== "document") {
811
+ throw new ParetaError('inputType must be "query" or "document"');
812
+ }
813
+ const body = { input: texts };
814
+ if (opts.inputType !== void 0) body.input_type = opts.inputType;
815
+ return client.request("POST", "/v1/embeddings", {
816
+ body,
817
+ cast: (raw) => new Embeddings(raw)
818
+ });
819
+ };
820
+ }
821
+
923
822
  // src/client.ts
924
823
  var DEFAULT_BASE_URL = "https://api.pareta.ai";
925
- var DEFAULT_TIMEOUT_MS = 6e4;
824
+ function randomKey() {
825
+ try {
826
+ return globalThis.crypto?.randomUUID?.().replace(/-/g, "") ?? Math.random().toString(36).slice(2) + Date.now().toString(36);
827
+ } catch {
828
+ return Math.random().toString(36).slice(2) + Date.now().toString(36);
829
+ }
830
+ }
831
+ var DEFAULT_TIMEOUT_MS = 6e5;
926
832
  var DEFAULT_MAX_RETRIES = 2;
927
833
  var RETRY_STATUSES = /* @__PURE__ */ new Set([408, 409, 429, 500, 502, 503, 504]);
928
834
  function normalizeBaseURL(url) {
@@ -937,10 +843,13 @@ var Pareta = class _Pareta {
937
843
  // Resource namespaces (assigned in the constructor; filled in slice by slice).
938
844
  chat;
939
845
  models;
940
- endpoints;
941
846
  tasks;
942
847
  evals;
943
848
  auto;
849
+ /** Document reranking (the Retrieval precision lane) — `pa.rerank(query, docs, {topN})`. */
850
+ rerank;
851
+ /** Text embeddings (the Retrieval recall lane) — `pa.embeddings(input, {inputType})`. */
852
+ embeddings;
944
853
  constructor(options = {}) {
945
854
  if (!options.apiKey) {
946
855
  throw new ParetaError(
@@ -958,10 +867,11 @@ var Pareta = class _Pareta {
958
867
  this.fetchImpl = options.fetch ? f : f.bind(globalThis);
959
868
  this.chat = new Chat(this);
960
869
  this.models = new Models(this);
961
- this.endpoints = new Endpoints(this);
962
870
  this.tasks = new Tasks(this);
963
871
  this.evals = new Evals(this);
964
872
  this.auto = new Auto(this);
873
+ this.rerank = makeRerank(this);
874
+ this.embeddings = makeEmbeddings(this);
965
875
  }
966
876
  /** Build from PARETA_API_KEY (+ optional PARETA_BASE_URL); explicit opts win. */
967
877
  static fromEnv(options = {}) {
@@ -1048,6 +958,9 @@ var Pareta = class _Pareta {
1048
958
  const url = this.buildURL(path, params);
1049
959
  const isMultipart = files != null || data != null;
1050
960
  const headers = this.headers({ jsonBody: body != null && !isMultipart });
961
+ if (method.toUpperCase() === "POST" && !headers["Idempotency-Key"]) {
962
+ headers["Idempotency-Key"] = `pareta-js-${randomKey()}`;
963
+ }
1051
964
  let payload;
1052
965
  if (isMultipart) {
1053
966
  payload = this.buildFormData(files, data);
@@ -1089,12 +1002,15 @@ var Pareta = class _Pareta {
1089
1002
  /**
1090
1003
  * Yield parsed SSE objects. Retries ONLY the initial connect/handshake — once
1091
1004
  * bytes are flowing a mid-stream drop raises (re-issuing would re-run a
1092
- * metered generation / re-trigger a deploy). `events:true` → `{event,data}`.
1005
+ * metered generation). `events:true` → `{event,data}`.
1093
1006
  */
1094
1007
  async *stream(method, path, opts = {}) {
1095
1008
  const { body, params, cast, events } = opts;
1096
1009
  const url = this.buildURL(path, params);
1097
1010
  const headers = this.headers({ stream: true, jsonBody: body != null });
1011
+ if (method.toUpperCase() === "POST" && !headers["Idempotency-Key"]) {
1012
+ headers["Idempotency-Key"] = `pareta-js-${randomKey()}`;
1013
+ }
1098
1014
  const payload = body != null ? JSON.stringify(body) : void 0;
1099
1015
  for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
1100
1016
  let started = false;
@@ -1136,6 +1052,6 @@ var Pareta = class _Pareta {
1136
1052
  }
1137
1053
  };
1138
1054
 
1139
- export { APIConnectionError, APIStatusError, APITimeoutError, AuthenticationError, BadRequestError, BaseModel, ChatCompletion, ChatCompletionChunk, Choice, ConflictError, Endpoint, EndpointMetrics, EndpointNotReadyError, EvalItemResult, EvalResult, EvalRun, EvalRuns, EvalSet, EvalSets, FrontierModel, InsufficientCreditsError, Leaderboard, LeaderboardEntry, Message, Model, ModelList, NotFoundError, Pareta, ParetaError, PermissionDeniedError, RateLimitError, Task, TaskMatch, TaskMatchCandidate, Usage, VERSION };
1055
+ export { APIConnectionError, APIStatusError, APITimeoutError, AuthenticationError, BadRequestError, BaseModel, ChatCompletion, ChatCompletionChunk, Choice, ConflictError, Embeddings, EndpointNotReadyError, EvalItemResult, EvalResult, EvalRun, EvalRuns, EvalSet, EvalSets, FrontierModel, InsufficientCreditsError, Message, Model, ModelList, NotFoundError, Pareta, ParetaError, PermissionDeniedError, RateLimitError, Rerank, RerankResult, Task, TaskMatch, TaskMatchCandidate, Usage, VERSION };
1140
1056
  //# sourceMappingURL=index.mjs.map
1141
1057
  //# sourceMappingURL=index.mjs.map