@mccaskie-labs/workbench-ai 0.1.4 → 0.1.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @mccaskie-labs/workbench-ai
2
2
 
3
+ ## 0.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - Kept calls (`docs/spec.md` §2.9): a `keep` option on `text`, `structured`, `stream`, `countTokens`, `images.generate` and `images.search`. `keep: false` sends `X-Workbench-Keep: no`, so the Gateway keeps the call's facts but not its text; a refused call is kept whatever it says. `subject` is documented as how a person's kept calls are found: an app with signed-in users sends `user:<its own user id>`. `createFakeAi` records `keep` on each call.
8
+
3
9
  ## 0.1.4
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -26,6 +26,7 @@ await save({ text: r.text, model: r.model, requestId: r.requestId })
26
26
  | `ai.images.generate({ prompt, aspectRatio, job, model?, references? })` | One image: `{ bytes, mimeType, model, requestId, costUsd }`. `model` is `image-default` (the default), `image-pro` or `image-openai`; `references` work on the Google aliases only. Needs the `images` scope |
27
27
  | `ai.images.search({ q, job, num?, gl?, hl? })` | Serper image search: a list of `{ title, imageUrl, thumbnailUrl, width, height, source, pageUrl }` that also carries `requestId`, `costUsd` and `credits`. Needs the `search` scope |
28
28
  | `voice`, `spelling` on `text`, `structured`, `stream`, `countTokens` | `voice: 'conversational'` (or `casual`, `plain`, `formal`, `strict-formal`) has the Gateway add Workbench's house writing standards and that voice ahead of your system prompt; `spelling: 'en-AU'` (or `en-PH`, `en-GB`, `en-US`) adds one line. The text is the same bytes for every app, so it is cached and shared. `voice: { instructions }` is your own voice: it goes first in your own system prompt and no Workbench writing rule is added. A text result carries `voice: { name, spelling, version }` when one was named |
29
+ | `subject`, `keep` on every call | The Gateway keeps what each call sent and got back, for audit (`docs/spec.md` §2.9). `subject: 'user:<id>'` (your own user id, never a name or email address) is how a person's calls are found and deleted. `keep: false` keeps the call's facts but not its text; a refused call is kept whatever it says |
29
30
  | `checkWriting(text, { voice?, paragraphTarget?, exempt? })` | Checks text against the house standards with no AI call. Stops: long dashes and the banned phrases. Paragraph length is a target: no issue up to 1.25 times it, a note up to double, a stop only past double. Sentence length is never an issue. `exempt` is required wording to leave out |
30
31
  | `writingStops(issues)`, `writingNotes(issues)`, `writingFixNote(issues)` | The stops, the notes, and the text to add to a prompt when asking once more after a stop |
31
32
  | `ai.anthropic` | The official `@anthropic-ai/sdk` client pointed at the Gateway, for anything else |
package/dist/ai.js CHANGED
@@ -60,6 +60,8 @@ export function createAi(opts) {
60
60
  throw new WorkbenchAiError("invalid_request", "subject must be type:id");
61
61
  h["X-Workbench-Subject"] = req.subject;
62
62
  }
63
+ if (req.keep === false)
64
+ h["X-Workbench-Keep"] = "no";
63
65
  // Checked here too, so a wrong name fails before the network. The Gateway refuses it as well.
64
66
  if (typeof req.voice === "string") {
65
67
  if (!VOICE_NAMES.includes(req.voice))
package/dist/fake.d.ts CHANGED
@@ -28,6 +28,8 @@ export interface FakeCall {
28
28
  job: string | null;
29
29
  promptVersion: string | null;
30
30
  subject: string | null;
31
+ /** False when the call was marked do-not-keep (X-Workbench-Keep: no, docs/spec.md §2.9). */
32
+ keep: boolean;
31
33
  /** The Workbench voice and spelling named (X-Workbench-Voice, X-Workbench-Spelling). */
32
34
  voice: string | null;
33
35
  spelling: string | null;
package/dist/fake.js CHANGED
@@ -90,6 +90,7 @@ export function fakeGateway(script = {}) {
90
90
  job: req.headers.get("x-workbench-job"),
91
91
  promptVersion: req.headers.get("x-workbench-prompt-version"),
92
92
  subject: req.headers.get("x-workbench-subject"),
93
+ keep: req.headers.get("x-workbench-keep")?.toLowerCase() !== "no",
93
94
  voice: req.headers.get("x-workbench-voice"),
94
95
  spelling: req.headers.get("x-workbench-spelling"),
95
96
  body,
package/dist/images.js CHANGED
@@ -17,6 +17,8 @@ function headers(req) {
17
17
  throw new WorkbenchAiError("invalid_request", "subject must be type:id");
18
18
  h["X-Workbench-Subject"] = req.subject;
19
19
  }
20
+ if (req.keep === false)
21
+ h["X-Workbench-Keep"] = "no";
20
22
  return h;
21
23
  }
22
24
  function toBase64(bytes) {
package/dist/types.d.ts CHANGED
@@ -34,8 +34,17 @@ export interface TextRequest {
34
34
  voice?: VoiceName | OwnVoice;
35
35
  /** The spelling to write in. The Gateway adds one line for it. Separate from the voice. */
36
36
  spelling?: SpellingName;
37
- /** `type:id` of the thing the call is about. */
37
+ /**
38
+ * `type:id` of the thing the call is about. An app with signed-in users sends `user:<its own user id>`
39
+ * (never a name, email address or phone number), so a person's kept calls can be found and deleted.
40
+ */
38
41
  subject?: string;
42
+ /**
43
+ * False marks this call do-not-keep (`X-Workbench-Keep: no`): the Gateway keeps its facts but
44
+ * not its text (docs/spec.md §2.9). A refused call is kept whatever this says. Left out, the
45
+ * project's own setting decides.
46
+ */
47
+ keep?: boolean;
39
48
  }
40
49
  export interface StructuredRequest<T> extends TextRequest {
41
50
  /** A zod schema. Its JSON Schema is sent as `output_config.format`; the reply is validated against it. */
@@ -137,6 +146,12 @@ export interface ImageGenerateRequest {
137
146
  }[];
138
147
  promptVersion?: string;
139
148
  subject?: string;
149
+ /**
150
+ * False marks this call do-not-keep (`X-Workbench-Keep: no`): the Gateway keeps its facts but
151
+ * not its text (docs/spec.md §2.9). A refused call is kept whatever this says. Left out, the
152
+ * project's own setting decides.
153
+ */
154
+ keep?: boolean;
140
155
  }
141
156
  export interface GeneratedImage {
142
157
  bytes: Uint8Array;
@@ -157,6 +172,12 @@ export interface ImageSearchRequest {
157
172
  /** Language, e.g. `en`. */
158
173
  hl?: string;
159
174
  subject?: string;
175
+ /**
176
+ * False marks this call do-not-keep (`X-Workbench-Keep: no`): the Gateway keeps its facts but
177
+ * not its text (docs/spec.md §2.9). A refused call is kept whatever this says. Left out, the
178
+ * project's own setting decides.
179
+ */
180
+ keep?: boolean;
160
181
  }
161
182
  export interface ImageSearchResult {
162
183
  title: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mccaskie-labs/workbench-ai",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Claude through the Workbench Gateway: text, structured output, streaming and budget status, with no Anthropic key in the app. Refusals and truncations throw; createFakeAi for tests.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",