plures 1.22.0 → 1.23.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 CHANGED
@@ -45,12 +45,12 @@ if (event.type === "task.completed" && event.data.result?.agreement === 1) {
45
45
  ## API
46
46
 
47
47
  - `plures.check(id, data, overrides?)`: run a check from your app's map, one line before the action it guards: `const check = await plures.check("refunds", { order_total, reason }); if (check.answer !== "Approve") return`. The check saved on Plures supplies the question, options, which fields people see (the rest come back in `kept_private`), who decides, how often, its conditions and what happens on a timeout, so you change them on Plures, not in code. `checked` says whether a person looked; `skipped_because` says why not. Overrides: `question`, `options`, `verifiers`, `team`, `route`, `sample`, `timeout`, `always`.
48
- - `plures.turns.log({ question, answer, intent, rerouted_to, retrieval, sources, session, channel })`: answer reviews for assistants. Send each turn after it's answered (don't await it in the user's path); Plures picks the ones that went wrong (rerouted, refused, empty, no sources, asked again) plus a few at random, and your team grades them. `plures.turns.insights(app)` and `plures.turns.export(app, "routes" | "retrieval" | "qa" | "missed")` turn the grades into routing examples and eval sets.
48
+ - `plures.turns.log({ question, answer, intent, rerouted_to, retrieval, sources, session, channel })`: answer reviews for assistants. Send each turn after it's answered (don't await it in the user's path); Plures picks the ones that went wrong (rerouted, refused, empty, no sources, asked again) plus a few at random, and your team grades them. `plures.turns.insights(app)` and `plures.turns.export(app, "routes" | "qa" | "missed")` turn the grades into routing examples and eval sets.
49
49
  - `plures.drift.list(app)`, `.fix(app, id)`: drift cases, when a rubric or an answer intent's grades fall. `npx plures drift fix <case> --app <app>` has Claude Code read the repo with the graded examples that got worse, find the cause, fix it and add eval cases; on GitHub, Plures opens the pull request and then checks the grades come back.
50
50
  - `npx plures check add <id> --app <app>`: Claude Code puts that line before the action on a new branch. On GitHub (the dashboard's **Add it to my code**) Plures then opens a pull request.
51
51
  - `plures.tasks.create(params, { idempotencyKey? })`: send a task. Params: `question`, `options` (2 to 8, strings or `{ id, label }`), `context`, `image_url`, `audio_url` or `video_url` with `media_seconds` (a clip up to 180 seconds that people play through before answering), `sensitive`, `instructions`, `verifiers` (1, 3, 5, 7 or 9), `max_verifiers`, `presence_check` (default true), `webhook_url`, `metadata`, `expires_in`, `route` (`"team"` sends it straight to your own people, $0.05 per internal vote live), `category` (matches your routing rules) and `team` (one of your named teams), `team_votes` and `team_unanimous` (internal consensus: how many of your team vote, and whether they must all agree; a split goes to the team's lead).
52
52
  - `plures.tasks.retrieve(id)`, `plures.tasks.list({ status?, limit?, starting_after?, app? })`, `plures.tasks.cancel(id)`
53
- - `new Plures(key, { app: "support-agent" })` or `PLURES_APP`: send everything to one of your apps. `plures.apps.list()`, `.create({ name, id? })`, `.retrieve(id)`, `.update(id, { name?, id?, default? })`, `.del(id)`. Each app keeps its own tasks, ledger view, map and quality.
53
+ - `new Plures(key, { app: "support-agent" })` or `PLURES_APP`: send everything to one of your apps. `plures.apps.list()`, `.create({ name, id? })`, `.retrieve(id)`, `.update(id, { name?, id?, default?, archived? })`, `.archive(id)`, `.restore(id)`, `.del(id)`. An archived app keeps its history but takes no new work. Each app keeps its own tasks, ledger view, map and quality.
54
54
  - `plures.maps.guide()`, `.retrieve(app)`, `.upload(app, map, { branch? })` (a branch other than main gets its own map, compared with main and noted on its pull request), `.setCheckpoint(app, id, status)`: the agent map, where your agent needs a person. Or run `npx plures map` in your repo: your own coding agent reads the code and only the map is sent.
55
55
  - `plures.maps.createKey(app, { label? })`, `.keys(app)`, `.revokeKey(app, id)`: map keys for CI, which can only read and upload that app's map. `.workflow(app, branch?)` returns the GitHub Action that maps on every push; `npx plures map workflow` writes it to `.github/workflows/plures-map.yml`. Or use **Map with GitHub** on the app's map page and Plures opens the pull request for you, then **Turn on mapping** merges it. `plures.maps.startRun(app)` and `.runs(app)`: in CI with no Claude key, `npx plures map` starts a run where Plures runs Claude (Claude at cost, at most $5 a run). `plures.maps.estimate(app, "map" | "drift")` shows what the next map or drift fix costs before it starts: the Plures engine fee, 5¢ a step of the app's map (the first map of each app is free; branch maps are free), plus Claude at cost when Plures runs it. `npx plures map` and `npx plures drift fix` check it first and stop if your credit can't cover it. A drift fix is paid by outcome: each quality point it wins back, once people have graded the new outputs, costs 20¢ a step of the map ($3 to $15 a point), at most $500 a fix, with Claude included; no better or worse is free.
56
56
  - In your terminal, `npx plures map` opens your map page so you can watch it build (`--no-open` to skip), keeps one live line of what it's reading, and ends by drawing the map's flows with the checks Plures suggests. On GitHub and other CI it prints a plain log.
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- var VERSION = "1.22.0";
2
+ var VERSION = "1.23.0";
3
3
  var PluresError = class extends Error {
4
4
  constructor(message, status, type) {
5
5
  super(message);
@@ -84,9 +84,13 @@ var Plures = class {
84
84
  /** { name: "Support agent" }, with an optional id like "support-agent". */
85
85
  create: (params) => this.req("POST", "/api/v1/apps", params),
86
86
  retrieve: (id) => this.req("GET", `/api/v1/apps/${encodeURIComponent(id)}`),
87
- /** Rename it, change its id (its tasks move with it), or make it the default. */
87
+ /** Rename it, change its id (its tasks move with it), make it the default, or archive and restore it. */
88
88
  update: (id, params) => this.req("PATCH", `/api/v1/apps/${encodeURIComponent(id)}`, params),
89
- /** Only an app with no tasks can be deleted. */
89
+ /** Keeps its tasks, ledger, map and grades readable, but it takes no new work and doesn't count toward the 25 app limit. */
90
+ archive: (id) => this.req("PATCH", `/api/v1/apps/${encodeURIComponent(id)}`, { archived: true }),
91
+ /** Brings an archived app back into use. */
92
+ restore: (id) => this.req("PATCH", `/api/v1/apps/${encodeURIComponent(id)}`, { archived: false }),
93
+ /** Only an app with no tasks can be deleted; archive one that has them. */
90
94
  del: (id) => this.req("DELETE", `/api/v1/apps/${encodeURIComponent(id)}`)
91
95
  };
92
96
  /**
@@ -188,7 +192,7 @@ var Plures = class {
188
192
  grade: (id, g) => this.req("POST", `/api/v1/turns/${encodeURIComponent(id)}/grade`, g),
189
193
  /** What the grades say: per intent, misroutes, retrieval misses and missed asks. */
190
194
  insights: (app, opts = {}) => this.req("GET", `/api/v1/apps/${encodeURIComponent(app)}/turns/insights${opts.days ? `?days=${opts.days}` : ""}`),
191
- /** Graded turns as eval data: routes (routing examples), retrieval ({ query, doc, must_contain }), qa ({ question, fact } or { question, unanswerable }), missed. */
195
+ /** Graded turns as eval data: routes (routing examples), qa ({ question, must_cover, sources_only } or { question, unanswerable: true }), missed. */
192
196
  export: async (app, kind, opts = {}) => {
193
197
  const q = new URLSearchParams({ kind, ...opts.since ? { since: opts.since } : {} });
194
198
  const r = await fetch(`${this.base}/api/v1/apps/${encodeURIComponent(app)}/turns/export?${q}`, { headers: { authorization: `Bearer ${this.apiKey}`, "user-agent": this.ua } });
package/dist/cli.cjs CHANGED
@@ -30,7 +30,7 @@ var import_node_path = require("path");
30
30
  var import_node_fs = require("fs");
31
31
 
32
32
  // src/index.ts
33
- var VERSION = "1.22.0";
33
+ var VERSION = "1.23.0";
34
34
  var PluresError = class extends Error {
35
35
  constructor(message, status, type) {
36
36
  super(message);
@@ -115,9 +115,13 @@ var Plures = class {
115
115
  /** { name: "Support agent" }, with an optional id like "support-agent". */
116
116
  create: (params) => this.req("POST", "/api/v1/apps", params),
117
117
  retrieve: (id) => this.req("GET", `/api/v1/apps/${encodeURIComponent(id)}`),
118
- /** Rename it, change its id (its tasks move with it), or make it the default. */
118
+ /** Rename it, change its id (its tasks move with it), make it the default, or archive and restore it. */
119
119
  update: (id, params) => this.req("PATCH", `/api/v1/apps/${encodeURIComponent(id)}`, params),
120
- /** Only an app with no tasks can be deleted. */
120
+ /** Keeps its tasks, ledger, map and grades readable, but it takes no new work and doesn't count toward the 25 app limit. */
121
+ archive: (id) => this.req("PATCH", `/api/v1/apps/${encodeURIComponent(id)}`, { archived: true }),
122
+ /** Brings an archived app back into use. */
123
+ restore: (id) => this.req("PATCH", `/api/v1/apps/${encodeURIComponent(id)}`, { archived: false }),
124
+ /** Only an app with no tasks can be deleted; archive one that has them. */
121
125
  del: (id) => this.req("DELETE", `/api/v1/apps/${encodeURIComponent(id)}`)
122
126
  };
123
127
  /**
@@ -219,7 +223,7 @@ var Plures = class {
219
223
  grade: (id, g) => this.req("POST", `/api/v1/turns/${encodeURIComponent(id)}/grade`, g),
220
224
  /** What the grades say: per intent, misroutes, retrieval misses and missed asks. */
221
225
  insights: (app2, opts = {}) => this.req("GET", `/api/v1/apps/${encodeURIComponent(app2)}/turns/insights${opts.days ? `?days=${opts.days}` : ""}`),
222
- /** Graded turns as eval data: routes (routing examples), retrieval ({ query, doc, must_contain }), qa ({ question, fact } or { question, unanswerable }), missed. */
226
+ /** Graded turns as eval data: routes (routing examples), qa ({ question, must_cover, sources_only } or { question, unanswerable: true }), missed. */
223
227
  export: async (app2, kind, opts = {}) => {
224
228
  const q = new URLSearchParams({ kind, ...opts.since ? { since: opts.since } : {} });
225
229
  const r = await fetch(`${this.base}/api/v1/apps/${encodeURIComponent(app2)}/turns/export?${q}`, { headers: { authorization: `Bearer ${this.apiKey}`, "user-agent": this.ua } });
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  Plures,
4
4
  PluresError,
5
5
  VERSION
6
- } from "./chunk-3P2G67SF.js";
6
+ } from "./chunk-VATZXULP.js";
7
7
 
8
8
  // src/cli.ts
9
9
  import { spawnSync, spawn } from "child_process";
package/dist/index.cjs CHANGED
@@ -26,7 +26,7 @@ __export(index_exports, {
26
26
  default: () => index_default
27
27
  });
28
28
  module.exports = __toCommonJS(index_exports);
29
- var VERSION = "1.22.0";
29
+ var VERSION = "1.23.0";
30
30
  var PluresError = class extends Error {
31
31
  constructor(message, status, type) {
32
32
  super(message);
@@ -111,9 +111,13 @@ var Plures = class {
111
111
  /** { name: "Support agent" }, with an optional id like "support-agent". */
112
112
  create: (params) => this.req("POST", "/api/v1/apps", params),
113
113
  retrieve: (id) => this.req("GET", `/api/v1/apps/${encodeURIComponent(id)}`),
114
- /** Rename it, change its id (its tasks move with it), or make it the default. */
114
+ /** Rename it, change its id (its tasks move with it), make it the default, or archive and restore it. */
115
115
  update: (id, params) => this.req("PATCH", `/api/v1/apps/${encodeURIComponent(id)}`, params),
116
- /** Only an app with no tasks can be deleted. */
116
+ /** Keeps its tasks, ledger, map and grades readable, but it takes no new work and doesn't count toward the 25 app limit. */
117
+ archive: (id) => this.req("PATCH", `/api/v1/apps/${encodeURIComponent(id)}`, { archived: true }),
118
+ /** Brings an archived app back into use. */
119
+ restore: (id) => this.req("PATCH", `/api/v1/apps/${encodeURIComponent(id)}`, { archived: false }),
120
+ /** Only an app with no tasks can be deleted; archive one that has them. */
117
121
  del: (id) => this.req("DELETE", `/api/v1/apps/${encodeURIComponent(id)}`)
118
122
  };
119
123
  /**
@@ -215,7 +219,7 @@ var Plures = class {
215
219
  grade: (id, g) => this.req("POST", `/api/v1/turns/${encodeURIComponent(id)}/grade`, g),
216
220
  /** What the grades say: per intent, misroutes, retrieval misses and missed asks. */
217
221
  insights: (app, opts = {}) => this.req("GET", `/api/v1/apps/${encodeURIComponent(app)}/turns/insights${opts.days ? `?days=${opts.days}` : ""}`),
218
- /** Graded turns as eval data: routes (routing examples), retrieval ({ query, doc, must_contain }), qa ({ question, fact } or { question, unanswerable }), missed. */
222
+ /** Graded turns as eval data: routes (routing examples), qa ({ question, must_cover, sources_only } or { question, unanswerable: true }), missed. */
219
223
  export: async (app, kind, opts = {}) => {
220
224
  const q = new URLSearchParams({ kind, ...opts.since ? { since: opts.since } : {} });
221
225
  const r = await fetch(`${this.base}/api/v1/apps/${encodeURIComponent(app)}/turns/export?${q}`, { headers: { authorization: `Bearer ${this.apiKey}`, "user-agent": this.ua } });
package/dist/index.d.cts CHANGED
@@ -499,7 +499,8 @@ type App = {
499
499
  object: "app";
500
500
  id: string;
501
501
  name: string;
502
- default: boolean;
502
+ default: boolean; /** Keeps its history but takes no new work. */
503
+ archived: boolean;
503
504
  created_at: string;
504
505
  tasks_30d?: number;
505
506
  waiting?: number;
@@ -525,7 +526,7 @@ type WebhookEvent = {
525
526
  created_at: string;
526
527
  data: Task;
527
528
  };
528
- declare const VERSION = "1.22.0";
529
+ declare const VERSION = "1.23.0";
529
530
  type GitHubLink = {
530
531
  object: "github_link";
531
532
  app: string;
@@ -621,13 +622,18 @@ declare class Plures {
621
622
  id?: string;
622
623
  }) => Promise<App>;
623
624
  retrieve: (id: string) => Promise<App>;
624
- /** Rename it, change its id (its tasks move with it), or make it the default. */
625
+ /** Rename it, change its id (its tasks move with it), make it the default, or archive and restore it. */
625
626
  update: (id: string, params: {
626
627
  name?: string;
627
628
  id?: string;
628
629
  default?: true;
630
+ archived?: boolean;
629
631
  }) => Promise<App>;
630
- /** Only an app with no tasks can be deleted. */
632
+ /** Keeps its tasks, ledger, map and grades readable, but it takes no new work and doesn't count toward the 25 app limit. */
633
+ archive: (id: string) => Promise<App>;
634
+ /** Brings an archived app back into use. */
635
+ restore: (id: string) => Promise<App>;
636
+ /** Only an app with no tasks can be deleted; archive one that has them. */
631
637
  del: (id: string) => Promise<{
632
638
  object: "app";
633
639
  id: string;
@@ -891,8 +897,8 @@ declare class Plures {
891
897
  insights: (app: string, opts?: {
892
898
  days?: number;
893
899
  }) => Promise<Record<string, unknown>>;
894
- /** Graded turns as eval data: routes (routing examples), retrieval ({ query, doc, must_contain }), qa ({ question, fact } or { question, unanswerable }), missed. */
895
- export: (app: string, kind: "routes" | "retrieval" | "qa" | "missed", opts?: {
900
+ /** Graded turns as eval data: routes (routing examples), qa ({ question, must_cover, sources_only } or { question, unanswerable: true }), missed. */
901
+ export: (app: string, kind: "routes" | "qa" | "missed", opts?: {
896
902
  since?: string;
897
903
  }) => Promise<Record<string, unknown>[]>;
898
904
  };
package/dist/index.d.ts CHANGED
@@ -499,7 +499,8 @@ type App = {
499
499
  object: "app";
500
500
  id: string;
501
501
  name: string;
502
- default: boolean;
502
+ default: boolean; /** Keeps its history but takes no new work. */
503
+ archived: boolean;
503
504
  created_at: string;
504
505
  tasks_30d?: number;
505
506
  waiting?: number;
@@ -525,7 +526,7 @@ type WebhookEvent = {
525
526
  created_at: string;
526
527
  data: Task;
527
528
  };
528
- declare const VERSION = "1.22.0";
529
+ declare const VERSION = "1.23.0";
529
530
  type GitHubLink = {
530
531
  object: "github_link";
531
532
  app: string;
@@ -621,13 +622,18 @@ declare class Plures {
621
622
  id?: string;
622
623
  }) => Promise<App>;
623
624
  retrieve: (id: string) => Promise<App>;
624
- /** Rename it, change its id (its tasks move with it), or make it the default. */
625
+ /** Rename it, change its id (its tasks move with it), make it the default, or archive and restore it. */
625
626
  update: (id: string, params: {
626
627
  name?: string;
627
628
  id?: string;
628
629
  default?: true;
630
+ archived?: boolean;
629
631
  }) => Promise<App>;
630
- /** Only an app with no tasks can be deleted. */
632
+ /** Keeps its tasks, ledger, map and grades readable, but it takes no new work and doesn't count toward the 25 app limit. */
633
+ archive: (id: string) => Promise<App>;
634
+ /** Brings an archived app back into use. */
635
+ restore: (id: string) => Promise<App>;
636
+ /** Only an app with no tasks can be deleted; archive one that has them. */
631
637
  del: (id: string) => Promise<{
632
638
  object: "app";
633
639
  id: string;
@@ -891,8 +897,8 @@ declare class Plures {
891
897
  insights: (app: string, opts?: {
892
898
  days?: number;
893
899
  }) => Promise<Record<string, unknown>>;
894
- /** Graded turns as eval data: routes (routing examples), retrieval ({ query, doc, must_contain }), qa ({ question, fact } or { question, unanswerable }), missed. */
895
- export: (app: string, kind: "routes" | "retrieval" | "qa" | "missed", opts?: {
900
+ /** Graded turns as eval data: routes (routing examples), qa ({ question, must_cover, sources_only } or { question, unanswerable: true }), missed. */
901
+ export: (app: string, kind: "routes" | "qa" | "missed", opts?: {
896
902
  since?: string;
897
903
  }) => Promise<Record<string, unknown>[]>;
898
904
  };
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  PluresError,
4
4
  VERSION,
5
5
  index_default
6
- } from "./chunk-3P2G67SF.js";
6
+ } from "./chunk-VATZXULP.js";
7
7
  export {
8
8
  Plures,
9
9
  PluresError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plures",
3
- "version": "1.22.0",
3
+ "version": "1.23.0",
4
4
  "description": "Human judgment as an API for AI agents. Send a decision to ID verified people and get their consensus back.",
5
5
  "keywords": [
6
6
  "human-in-the-loop",