@read-frog/api-contract 0.26.0 → 0.28.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@read-frog/api-contract",
3
- "version": "0.26.0",
3
+ "version": "0.28.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@orpc/contract": "^1.16.1",
28
- "@read-frog/definitions": "0.14.0",
28
+ "@read-frog/definitions": "0.15.1",
29
29
  "zod": "^4.6.7"
30
30
  },
31
31
  "devDependencies": {
@@ -1,5 +1,8 @@
1
1
  import { oc } from "@orpc/contract";
2
+ import { z } from "zod";
2
3
  import {
4
+ speechDeleteAllAudioOutputSchema,
5
+ speechDeleteAudioInputSchema,
3
6
  speechPreferencesSchema,
4
7
  speechPreferencesUpdateInputSchema,
5
8
  speechSynthesizeInputSchema,
@@ -42,4 +45,21 @@ export const speechContract = {
42
45
  })
43
46
  .input(speechSynthesizeInputSchema)
44
47
  .output(speechSynthesizeOutputSchema),
48
+ deleteAudio: oc
49
+ .route({
50
+ method: "POST",
51
+ path: "/speech/audio/delete",
52
+ summary: "Forget the audio kept for some texts, so each is read anew next time",
53
+ tags: ["Speech"],
54
+ })
55
+ .input(speechDeleteAudioInputSchema)
56
+ .output(z.void()),
57
+ deleteAllAudio: oc
58
+ .route({
59
+ method: "DELETE",
60
+ path: "/speech/audio",
61
+ summary: "Forget all the audio kept for the authenticated user's texts",
62
+ tags: ["Speech"],
63
+ })
64
+ .output(speechDeleteAllAudioOutputSchema),
45
65
  };
@@ -280,14 +280,6 @@ export const HostedAiTierStatusSchema = z.strictObject({
280
280
  * signing in. Clients badge an option with it and offer that plan.
281
281
  */
282
282
  upgradeTo: HostedAiUpgradePlanSchema.nullable(),
283
- /**
284
- * @deprecated Read `upgradeTo`. Viewer-independent product fact: no
285
- * non-Ultra account can ever use this feature/tier. Extensions released
286
- * before `upgradeTo` badge options with it, including for Ultra accounts.
287
- *
288
- * TODO(2026-11-21): remove once those extensions have drained (#710).
289
- */
290
- requiresUltra: z.boolean(),
291
283
  modelRevision: z.string().trim().min(1),
292
284
  });
293
285
 
@@ -297,15 +289,6 @@ export const HostedAiFeatureStatusSchema = z.strictObject({
297
289
  });
298
290
 
299
291
  export const HostedAiStatusOutputSchema = z.strictObject({
300
- /**
301
- * @deprecated Read `pools`. This lists the recurring pools only, never a
302
- * one-time one: extensions released before mengxi-ream/read-frog#2395 look
303
- * up a label for every entry's `periodKind`, and one they do not know
304
- * crashes their usage page. They also throw if the field is missing.
305
- *
306
- * TODO(2026-11-07): remove once those extensions have drained (#710).
307
- */
308
- credits: z.array(HostedAiRecurringCreditStatusSchema),
309
292
  /**
310
293
  * Everything that can pay for a feature, in the order the server draws on it:
311
294
  * the plan's recurring pools first, then one-time pools by soonest expiry. A
@@ -109,6 +109,29 @@ export const speechSynthesizeInputSchema = z
109
109
  .strict();
110
110
  export type SpeechSynthesizeInput = z.infer<typeof speechSynthesizeInputSchema>;
111
111
 
112
+ /** The most texts one request forgets the audio of. */
113
+ export const SPEECH_DELETE_AUDIO_MAX_TEXTS = 50;
114
+
115
+ /**
116
+ * Texts whose kept audio to forget, each as it is asked to be read aloud
117
+ * (`speech.synthesize`): the next time one is, it is read anew. Audio for a
118
+ * text that has none kept is no error.
119
+ */
120
+ export const speechDeleteAudioInputSchema = z
121
+ .object({
122
+ texts: z.array(speechSynthesizeInputSchema).min(1).max(SPEECH_DELETE_AUDIO_MAX_TEXTS),
123
+ })
124
+ .strict();
125
+ export type SpeechDeleteAudioInput = z.infer<typeof speechDeleteAudioInputSchema>;
126
+
127
+ export const speechDeleteAllAudioOutputSchema = z
128
+ .object({
129
+ // How many audio files there were.
130
+ deleted: z.number().int().nonnegative(),
131
+ })
132
+ .strict();
133
+ export type SpeechDeleteAllAudioOutput = z.infer<typeof speechDeleteAllAudioOutputSchema>;
134
+
112
135
  /**
113
136
  * Where to download the audio, an MP3: a link to fetch at once, which stops
114
137
  * working at `expiresAt`.