@ggui-ai/protocol 0.12.0 → 0.14.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/gadgets/stdlib-gadgets.d.ts +1 -1
- package/dist/gadgets/stdlib-gadgets.js +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/integrations/mcp-apps.d.ts +63 -11
- package/dist/integrations/mcp-apps.d.ts.map +1 -1
- package/dist/integrations/mcp-apps.js +73 -3
- package/dist/schemas/app-theme.d.ts +5 -0
- package/dist/schemas/app-theme.d.ts.map +1 -1
- package/dist/schemas/app-theme.js +23 -0
- package/dist/schemas/data-contract.d.ts +3 -1
- package/dist/schemas/data-contract.d.ts.map +1 -1
- package/dist/schemas/data-contract.js +2 -0
- package/dist/schemas/invoke.d.ts +2 -2
- package/dist/schemas/mcp.d.ts +482 -24
- package/dist/schemas/mcp.d.ts.map +1 -1
- package/dist/schemas/mcp.js +455 -26
- package/dist/schemas/render-input-envelope.d.ts +20 -0
- package/dist/schemas/render-input-envelope.d.ts.map +1 -0
- package/dist/schemas/render-input-envelope.js +56 -0
- package/dist/types/ggui-session-event.d.ts +4 -5
- package/dist/types/ggui-session-event.d.ts.map +1 -1
- package/dist/types/ggui-session-event.js +0 -37
- package/dist/types/host-context.d.ts +17 -16
- package/dist/types/host-context.d.ts.map +1 -1
- package/dist/types/host-context.js +7 -0
- package/dist/types/llm-route.d.ts +2 -2
- package/dist/types/llm-route.d.ts.map +1 -1
- package/dist/types/llm-route.js +11 -3
- package/dist/types/llm.d.ts +397 -7
- package/dist/types/llm.d.ts.map +1 -1
- package/dist/types/llm.js +111 -10
- package/dist/types/mcp.d.ts +16 -53
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/types/readonly.d.ts +11 -0
- package/dist/types/readonly.d.ts.map +1 -0
- package/dist/types/readonly.js +1 -0
- package/dist/types/refusal-codes.d.ts +319 -0
- package/dist/types/refusal-codes.d.ts.map +1 -0
- package/dist/types/refusal-codes.js +329 -0
- package/dist/version.d.ts +79 -5
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +78 -4
- package/package.json +7 -3
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `PRE_GENERATION_REFUSAL_CODES` — the closed registry of refusal codes
|
|
3
|
+
* (ggui#786).
|
|
4
|
+
*
|
|
5
|
+
* A **pre-generation refusal** is a deployment declining a call BEFORE
|
|
6
|
+
* it does any work: no state read, nothing committed, no model spend.
|
|
7
|
+
* (The call has already passed the SDK's check against the declared
|
|
8
|
+
* `inputSchema`; the claim is nothing READ, not nothing validated.)
|
|
9
|
+
* It is a third outcome, not a failure — a failure describes work
|
|
10
|
+
* that ran and did not produce a result. The wire shape
|
|
11
|
+
* of a refused render lives in `../schemas/mcp.ts`
|
|
12
|
+
* (`renderRefusalSchema`); this file owns the NAMES.
|
|
13
|
+
*
|
|
14
|
+
* ## Why one file
|
|
15
|
+
*
|
|
16
|
+
* The registry is the anti-drift mechanism: one `code` namespace across
|
|
17
|
+
* every surface a deployment can refuse on, so two names can never mean
|
|
18
|
+
* the same state and one name can never mean two. Emitters read a row
|
|
19
|
+
* from here; they never mint a code literal of their own. A code that
|
|
20
|
+
* is not in this file fails the wire enum at the transport, loudly — a
|
|
21
|
+
* bug, never a wire state.
|
|
22
|
+
*
|
|
23
|
+
* ## The rules every row obeys
|
|
24
|
+
*
|
|
25
|
+
* - **Name the STATE, not the verb.** `subscription_exists`, not
|
|
26
|
+
* `cannot_create_subscription`: the same state may refuse more than
|
|
27
|
+
* one action later, and the code must not encode which.
|
|
28
|
+
* - **One state, one code.** Two codes never share a name; one code MAY
|
|
29
|
+
* list several `surfaces` when a single state surfaces in more than
|
|
30
|
+
* one place (`billing_mode_anomaly`).
|
|
31
|
+
* - **`retry` is defined from the CALLER's side.** `after-fix` — a
|
|
32
|
+
* named party can act and the SAME call then succeeds; `next-period`
|
|
33
|
+
* — time restores it at the next period boundary; `later` —
|
|
34
|
+
* unbounded time (transient unavailability); `never` — no action by
|
|
35
|
+
* the caller restores the call under this identity.
|
|
36
|
+
* - **`fixBy` names WHO acts.** REQUIRED on every `after-fix` row;
|
|
37
|
+
* PERMITTED on a `later` row (naming the operator who restores a
|
|
38
|
+
* surface that is transiently unavailable); FORBIDDEN on
|
|
39
|
+
* `next-period` and `never` — time restores the first and nothing
|
|
40
|
+
* restores the second, so naming a party would be a lie about who
|
|
41
|
+
* can act. **An agent MUST NOT auto-retry an `after-fix` refusal
|
|
42
|
+
* whose `fixBy` is not `caller`** — otherwise "retry after fix"
|
|
43
|
+
* would mean "perform someone else's billing or policy decision on
|
|
44
|
+
* their behalf". `caller` is the only value an agent may act on
|
|
45
|
+
* itself.
|
|
46
|
+
* - **`emitter` is named.** A row whose emitter is unrecorded is the
|
|
47
|
+
* drift the registry exists to prevent.
|
|
48
|
+
*
|
|
49
|
+
* ## Reading this file as a self-hoster
|
|
50
|
+
*
|
|
51
|
+
* Every `description` here ships to npm, and the render-gate subset
|
|
52
|
+
* reaches an agent as JSON-Schema metadata through `tools/list`. The
|
|
53
|
+
* wording is therefore written from the DEPLOYMENT-POLICY perspective
|
|
54
|
+
* ("the allowance this deployment configured for the app is
|
|
55
|
+
* exhausted"), never from an operator's internal vocabulary. A
|
|
56
|
+
* deployment that configures none of these policies emits none of these
|
|
57
|
+
* codes; the registry is the vocabulary, not a mandate.
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* The surfaces a refusal code may be emitted on.
|
|
61
|
+
*
|
|
62
|
+
* - `render-gate` — the pre-generation gate on the render/mutation
|
|
63
|
+
* tools. These are the only codes that can appear in a refused
|
|
64
|
+
* tool result's `refusal.code`.
|
|
65
|
+
* - `owner-api` — an app owner's own billing mutations.
|
|
66
|
+
* - `provisioning-api` — a tenant provisioning an app on behalf of
|
|
67
|
+
* its own users.
|
|
68
|
+
*/
|
|
69
|
+
export declare const REFUSAL_SURFACES: readonly ["render-gate", "owner-api", "provisioning-api"];
|
|
70
|
+
/** One member of {@link REFUSAL_SURFACES}. */
|
|
71
|
+
export type RefusalSurface = (typeof REFUSAL_SURFACES)[number];
|
|
72
|
+
/** The closed `retry` vocabulary — see the file header for semantics. */
|
|
73
|
+
export declare const REFUSAL_RETRIES: readonly ["after-fix", "next-period", "later", "never"];
|
|
74
|
+
/** One member of {@link REFUSAL_RETRIES}. */
|
|
75
|
+
export type RefusalRetry = (typeof REFUSAL_RETRIES)[number];
|
|
76
|
+
/**
|
|
77
|
+
* Who can act on an `after-fix` refusal. Only `caller` is the agent
|
|
78
|
+
* itself — see the no-auto-retry rule in the file header.
|
|
79
|
+
*/
|
|
80
|
+
export declare const REFUSAL_FIX_BY: readonly ["caller", "owner", "tenant", "operator"];
|
|
81
|
+
/** One member of {@link REFUSAL_FIX_BY}. */
|
|
82
|
+
export type RefusalFixBy = (typeof REFUSAL_FIX_BY)[number];
|
|
83
|
+
declare const REFUSAL_ROWS: {
|
|
84
|
+
readonly unsupported_provider: {
|
|
85
|
+
readonly code: "unsupported_provider";
|
|
86
|
+
readonly surfaces: readonly ["render-gate"];
|
|
87
|
+
readonly retry: "after-fix";
|
|
88
|
+
readonly fixBy: "owner";
|
|
89
|
+
readonly emitter: "a deployment's generation gate, provider arm";
|
|
90
|
+
readonly description: "The provider behind the requested model is not one this deployment can fund for the app. The app owner picks a funded provider or configures the app with its own credentials.";
|
|
91
|
+
};
|
|
92
|
+
readonly insufficient_credit: {
|
|
93
|
+
readonly code: "insufficient_credit";
|
|
94
|
+
readonly surfaces: readonly ["render-gate"];
|
|
95
|
+
readonly retry: "after-fix";
|
|
96
|
+
readonly fixBy: "owner";
|
|
97
|
+
readonly emitter: "a deployment's generation gate, balance arm";
|
|
98
|
+
readonly description: "The balance this deployment funds the app from is exhausted. The app owner adds funds, after which the same call succeeds.";
|
|
99
|
+
};
|
|
100
|
+
readonly hard_cap_exceeded: {
|
|
101
|
+
readonly code: "hard_cap_exceeded";
|
|
102
|
+
readonly surfaces: readonly ["render-gate"];
|
|
103
|
+
readonly retry: "next-period";
|
|
104
|
+
readonly emitter: "a deployment's generation gate, cap arm";
|
|
105
|
+
readonly description: "The app reached the hard ceiling this deployment set for the current period. Nothing the caller or the owner does lifts it before the period rolls over.";
|
|
106
|
+
};
|
|
107
|
+
readonly model_not_in_tier: {
|
|
108
|
+
readonly code: "model_not_in_tier";
|
|
109
|
+
readonly surfaces: readonly ["render-gate"];
|
|
110
|
+
readonly retry: "after-fix";
|
|
111
|
+
readonly fixBy: "caller";
|
|
112
|
+
readonly emitter: "a deployment's generation gate, model arm";
|
|
113
|
+
readonly description: "The requested model is not among those the app is allowed to use. The caller picks an allowed model and retries — the one render-gate state an agent may act on itself.";
|
|
114
|
+
};
|
|
115
|
+
readonly managed_default_cap_exceeded: {
|
|
116
|
+
readonly code: "managed_default_cap_exceeded";
|
|
117
|
+
readonly surfaces: readonly ["render-gate"];
|
|
118
|
+
readonly retry: "after-fix";
|
|
119
|
+
readonly fixBy: "tenant";
|
|
120
|
+
readonly emitter: "a deployment's generation gate, delegated-policy arm";
|
|
121
|
+
readonly description: "The app is running on the default ceiling because the tenant that provisioned it has declared no policy of its own, and that ceiling is reached. The tenant declares an explicit policy for the app.";
|
|
122
|
+
};
|
|
123
|
+
readonly app_policy_missing: {
|
|
124
|
+
readonly code: "app_policy_missing";
|
|
125
|
+
readonly surfaces: readonly ["render-gate"];
|
|
126
|
+
readonly retry: "after-fix";
|
|
127
|
+
readonly fixBy: "tenant";
|
|
128
|
+
readonly emitter: "a deployment's generation gate, delegated-policy arm";
|
|
129
|
+
readonly description: "The app exists but carries no policy yet — the window between provisioning it and declaring what it may spend. The tenant declares the policy.";
|
|
130
|
+
};
|
|
131
|
+
readonly billing_mode_anomaly: {
|
|
132
|
+
readonly code: "billing_mode_anomaly";
|
|
133
|
+
readonly surfaces: readonly ["provisioning-api", "render-gate"];
|
|
134
|
+
readonly retry: "never";
|
|
135
|
+
readonly emitter: "a deployment's provisioning guard and its generation gate, reading the same record";
|
|
136
|
+
readonly description: "The app record declares a funding mode this deployment does not recognise, or declares none at all. The value is reported as read and never coerced — an unreadable record is not a policy.";
|
|
137
|
+
};
|
|
138
|
+
readonly app_canceled: {
|
|
139
|
+
readonly code: "app_canceled";
|
|
140
|
+
readonly surfaces: readonly ["render-gate"];
|
|
141
|
+
readonly retry: "after-fix";
|
|
142
|
+
readonly fixBy: "owner";
|
|
143
|
+
readonly emitter: "a deployment's generation gate, plan-state arm";
|
|
144
|
+
readonly description: "The app's plan has ended, so it renders nothing while the stored work is kept. The owner starts a new plan to restore rendering.";
|
|
145
|
+
};
|
|
146
|
+
readonly trial_exhausted: {
|
|
147
|
+
readonly code: "trial_exhausted";
|
|
148
|
+
readonly surfaces: readonly ["render-gate"];
|
|
149
|
+
readonly retry: "after-fix";
|
|
150
|
+
readonly fixBy: "owner";
|
|
151
|
+
readonly emitter: "a deployment's generation gate, trial arm";
|
|
152
|
+
readonly description: "The trial this deployment grants the app has used up its allotment. The owner starts a paid plan.";
|
|
153
|
+
};
|
|
154
|
+
readonly trial_expired: {
|
|
155
|
+
readonly code: "trial_expired";
|
|
156
|
+
readonly surfaces: readonly ["render-gate"];
|
|
157
|
+
readonly retry: "after-fix";
|
|
158
|
+
readonly fixBy: "owner";
|
|
159
|
+
readonly emitter: "a deployment's generation gate, trial arm";
|
|
160
|
+
readonly description: "The app's trial window has closed. The owner starts a paid plan.";
|
|
161
|
+
};
|
|
162
|
+
readonly issuer_rate_limited: {
|
|
163
|
+
readonly code: "issuer_rate_limited";
|
|
164
|
+
readonly surfaces: readonly ["render-gate"];
|
|
165
|
+
readonly retry: "later";
|
|
166
|
+
readonly emitter: "the per-issuer render-rate cap's denial";
|
|
167
|
+
readonly description: "Calls arriving under this issuing identity are over the rate this deployment allows. Time restores it; retry shortly.";
|
|
168
|
+
};
|
|
169
|
+
readonly app_rate_limited: {
|
|
170
|
+
readonly code: "app_rate_limited";
|
|
171
|
+
readonly surfaces: readonly ["render-gate"];
|
|
172
|
+
readonly retry: "later";
|
|
173
|
+
readonly emitter: "the per-app render-rate cap's denial";
|
|
174
|
+
readonly description: "This app is rendering faster than the rate this deployment allows it. The cap is the app’s own, not the issuing identity’s — the two are separate states with separate codes. Time restores it; retry shortly.";
|
|
175
|
+
};
|
|
176
|
+
readonly app_deprovisioned: {
|
|
177
|
+
readonly code: "app_deprovisioned";
|
|
178
|
+
readonly surfaces: readonly ["render-gate"];
|
|
179
|
+
readonly retry: "never";
|
|
180
|
+
readonly emitter: "the generation gate's owner-claim check, before any reservation or metering";
|
|
181
|
+
readonly description: "The app record has no owner claim any more — either the claim was removed, or the record names no issuing tenant at all. A record with no owner cannot be funded, so nothing renders under it and no caller action restores it.";
|
|
182
|
+
};
|
|
183
|
+
readonly billing_path_missing: {
|
|
184
|
+
readonly code: "billing_path_missing";
|
|
185
|
+
readonly surfaces: readonly ["render-gate"];
|
|
186
|
+
readonly retry: "after-fix";
|
|
187
|
+
readonly fixBy: "owner";
|
|
188
|
+
readonly emitter: "the generation gate's fall-through arm: a non-playground identity that resolves to no billing path (not a trial account, not a managed app, not a credit holder)";
|
|
189
|
+
readonly description: "The caller has no billing subject on this deployment, so nothing renders under it. The owner provisions one — a trial account, a managed policy, or credit. Unlike `billing_mode_anomaly` — an app record that exists and declares a funding mode this deployment cannot read — no record arm applies here: there is simply no subject to bill. A deployment MAY suppress this refusal by operator override; that switch is deployment policy, not a wire state.";
|
|
190
|
+
};
|
|
191
|
+
readonly subscription_exists: {
|
|
192
|
+
readonly code: "subscription_exists";
|
|
193
|
+
readonly surfaces: readonly ["owner-api"];
|
|
194
|
+
readonly retry: "after-fix";
|
|
195
|
+
readonly fixBy: "owner";
|
|
196
|
+
readonly emitter: "a deployment's owner billing mutations";
|
|
197
|
+
readonly description: "An active (non-canceled) plan exists on this app. It refuses starting another one AND deleting the app — the refusal's own `fix` names the next step for the action that was called.";
|
|
198
|
+
};
|
|
199
|
+
readonly checkout_unavailable: {
|
|
200
|
+
readonly code: "checkout_unavailable";
|
|
201
|
+
readonly surfaces: readonly ["owner-api"];
|
|
202
|
+
readonly retry: "later";
|
|
203
|
+
readonly fixBy: "operator";
|
|
204
|
+
readonly emitter: "a deployment's owner billing mutations";
|
|
205
|
+
readonly description: "The surface that starts a plan is unavailable on this deployment right now — unconfigured, or its provider is down. Only the operator can restore it.";
|
|
206
|
+
};
|
|
207
|
+
readonly card_update_unavailable: {
|
|
208
|
+
readonly code: "card_update_unavailable";
|
|
209
|
+
readonly surfaces: readonly ["owner-api"];
|
|
210
|
+
readonly retry: "later";
|
|
211
|
+
readonly fixBy: "operator";
|
|
212
|
+
readonly emitter: "a deployment's owner billing mutations";
|
|
213
|
+
readonly description: "The surface that updates a payment method is unavailable on this deployment right now. Only the operator can restore it.";
|
|
214
|
+
};
|
|
215
|
+
readonly portal_unavailable: {
|
|
216
|
+
readonly code: "portal_unavailable";
|
|
217
|
+
readonly surfaces: readonly ["owner-api"];
|
|
218
|
+
readonly retry: "later";
|
|
219
|
+
readonly fixBy: "operator";
|
|
220
|
+
readonly emitter: "a deployment's owner billing mutations";
|
|
221
|
+
readonly description: "The self-service billing surface is unavailable on this deployment right now. Only the operator can restore it.";
|
|
222
|
+
};
|
|
223
|
+
readonly no_subscription: {
|
|
224
|
+
readonly code: "no_subscription";
|
|
225
|
+
readonly surfaces: readonly ["owner-api"];
|
|
226
|
+
readonly retry: "after-fix";
|
|
227
|
+
readonly fixBy: "owner";
|
|
228
|
+
readonly emitter: "a deployment's owner billing mutations";
|
|
229
|
+
readonly description: "A plan-management action was called on an app that has no plan. The owner starts a plan first.";
|
|
230
|
+
};
|
|
231
|
+
readonly already_on_tier: {
|
|
232
|
+
readonly code: "already_on_tier";
|
|
233
|
+
readonly surfaces: readonly ["owner-api"];
|
|
234
|
+
readonly retry: "after-fix";
|
|
235
|
+
readonly fixBy: "owner";
|
|
236
|
+
readonly emitter: "a deployment's owner billing mutations";
|
|
237
|
+
readonly description: "The plan requested is the one the app is already on. The owner picks a different plan.";
|
|
238
|
+
};
|
|
239
|
+
readonly managed_app_no_checkout: {
|
|
240
|
+
readonly code: "managed_app_no_checkout";
|
|
241
|
+
readonly surfaces: readonly ["owner-api"];
|
|
242
|
+
readonly retry: "never";
|
|
243
|
+
readonly emitter: "a deployment's owner billing mutations";
|
|
244
|
+
readonly description: "This app is funded by the tenant that provisioned it, so it has no owner-facing plan surface at all. No owner action creates one.";
|
|
245
|
+
};
|
|
246
|
+
readonly managed_app_no_card_update: {
|
|
247
|
+
readonly code: "managed_app_no_card_update";
|
|
248
|
+
readonly surfaces: readonly ["owner-api"];
|
|
249
|
+
readonly retry: "never";
|
|
250
|
+
readonly emitter: "a deployment's owner billing mutations";
|
|
251
|
+
readonly description: "This app is funded by the tenant that provisioned it, so it carries no owner payment method to update.";
|
|
252
|
+
};
|
|
253
|
+
readonly managed_app_no_portal: {
|
|
254
|
+
readonly code: "managed_app_no_portal";
|
|
255
|
+
readonly surfaces: readonly ["owner-api"];
|
|
256
|
+
readonly retry: "never";
|
|
257
|
+
readonly emitter: "a deployment's owner billing mutations";
|
|
258
|
+
readonly description: "This app is funded by the tenant that provisioned it, so it has no owner self-service billing surface.";
|
|
259
|
+
};
|
|
260
|
+
readonly owner_ref_mismatch: {
|
|
261
|
+
readonly code: "owner_ref_mismatch";
|
|
262
|
+
readonly surfaces: readonly ["provisioning-api"];
|
|
263
|
+
readonly retry: "after-fix";
|
|
264
|
+
readonly fixBy: "tenant";
|
|
265
|
+
readonly emitter: "a deployment's provisioning guard";
|
|
266
|
+
readonly description: "The owner reference the caller supplied is not the one recorded on this app. The refusal names the route and the app, never the recorded reference. The tenant re-derives the reference and retries.";
|
|
267
|
+
};
|
|
268
|
+
readonly policy_version_stale: {
|
|
269
|
+
readonly code: "policy_version_stale";
|
|
270
|
+
readonly surfaces: readonly ["provisioning-api"];
|
|
271
|
+
readonly retry: "after-fix";
|
|
272
|
+
readonly fixBy: "tenant";
|
|
273
|
+
readonly emitter: "a deployment's provisioning guard, policy-write arm";
|
|
274
|
+
readonly description: "The policy write carries a version older than the one stored, so it would overwrite a newer decision. The refusal reports the stored version; the tenant re-derives from it and writes again.";
|
|
275
|
+
};
|
|
276
|
+
};
|
|
277
|
+
/** A refusal code = a registry key. Derived; never a second list. */
|
|
278
|
+
export type RefusalCode = keyof typeof REFUSAL_ROWS;
|
|
279
|
+
/**
|
|
280
|
+
* A registry row, as consumers read it. Normalized (not the literal
|
|
281
|
+
* row union) so `PRE_GENERATION_REFUSAL_CODES[code]` for any
|
|
282
|
+
* {@link RefusalCode} exposes `fixBy` as `RefusalFixBy | undefined`
|
|
283
|
+
* rather than a union in which some rows lack the property. The
|
|
284
|
+
* literal rows above still derive {@link RefusalCode}, enforce
|
|
285
|
+
* `code === key`, and enforce the retry/fixBy pairing.
|
|
286
|
+
*/
|
|
287
|
+
export interface RefusalRow {
|
|
288
|
+
readonly code: RefusalCode;
|
|
289
|
+
readonly surfaces: readonly RefusalSurface[];
|
|
290
|
+
readonly retry: RefusalRetry;
|
|
291
|
+
readonly fixBy?: RefusalFixBy;
|
|
292
|
+
readonly emitter: string;
|
|
293
|
+
readonly description: string;
|
|
294
|
+
}
|
|
295
|
+
/** The registry consumers read. */
|
|
296
|
+
export declare const PRE_GENERATION_REFUSAL_CODES: Readonly<Record<RefusalCode, RefusalRow>>;
|
|
297
|
+
/**
|
|
298
|
+
* The codes on one surface, derived type-level from the literal rows'
|
|
299
|
+
* `surfaces` tuples. A runtime `.filter()` cannot narrow a type, so the
|
|
300
|
+
* union is computed here and the tuple below is proved complete
|
|
301
|
+
* against it.
|
|
302
|
+
*/
|
|
303
|
+
type CodesOnSurface<S extends RefusalSurface> = {
|
|
304
|
+
[K in RefusalCode]: S extends (typeof REFUSAL_ROWS)[K]['surfaces'][number] ? K : never;
|
|
305
|
+
}[RefusalCode];
|
|
306
|
+
/**
|
|
307
|
+
* A code that can appear in a refused tool result's `refusal.code` —
|
|
308
|
+
* i.e. one whose `surfaces` include `render-gate`. Derived, so an
|
|
309
|
+
* owner-api or provisioning-api code is not even expressible on the
|
|
310
|
+
* render wire.
|
|
311
|
+
*/
|
|
312
|
+
export type PreGenerationRefusalCode = CodesOnSurface<'render-gate'>;
|
|
313
|
+
/**
|
|
314
|
+
* Every render-gate code, as the literal tuple the wire enum
|
|
315
|
+
* (`renderRefusalSchema.code`) is built from. Order is the registry's.
|
|
316
|
+
*/
|
|
317
|
+
export declare const RENDER_GATE_REFUSAL_CODES: readonly ["unsupported_provider", "insufficient_credit", "hard_cap_exceeded", "model_not_in_tier", "managed_default_cap_exceeded", "app_policy_missing", "billing_mode_anomaly", "billing_path_missing", "app_canceled", "trial_exhausted", "trial_expired", "issuer_rate_limited", "app_rate_limited", "app_deprovisioned"];
|
|
318
|
+
export {};
|
|
319
|
+
//# sourceMappingURL=refusal-codes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refusal-codes.d.ts","sourceRoot":"","sources":["../../src/types/refusal-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,2DAInB,CAAC;AAEX,8CAA8C;AAC9C,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,yEAAyE;AACzE,eAAO,MAAM,eAAe,yDAKlB,CAAC;AAEX,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,cAAc,oDAAqD,CAAC;AAEjF,4CAA4C;AAC5C,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAiD3D,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqOhB,CAAC;AAEH,qEAAqE;AACrE,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,YAAY,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,mCAAmC;AACnC,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CACjD,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,CACjB,CAAC;AAEjB;;;;;GAKG;AACH,KAAK,cAAc,CAAC,CAAC,SAAS,cAAc,IAAI;KAC7C,CAAC,IAAI,WAAW,GAAG,CAAC,SAAS,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GACtE,CAAC,GACD,KAAK;CACV,CAAC,WAAW,CAAC,CAAC;AAEf;;;;;GAKG;AACH,MAAM,MAAM,wBAAwB,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;AAiBrE;;;GAGG;AACH,eAAO,MAAM,yBAAyB,8TAepC,CAAC"}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `PRE_GENERATION_REFUSAL_CODES` — the closed registry of refusal codes
|
|
3
|
+
* (ggui#786).
|
|
4
|
+
*
|
|
5
|
+
* A **pre-generation refusal** is a deployment declining a call BEFORE
|
|
6
|
+
* it does any work: no state read, nothing committed, no model spend.
|
|
7
|
+
* (The call has already passed the SDK's check against the declared
|
|
8
|
+
* `inputSchema`; the claim is nothing READ, not nothing validated.)
|
|
9
|
+
* It is a third outcome, not a failure — a failure describes work
|
|
10
|
+
* that ran and did not produce a result. The wire shape
|
|
11
|
+
* of a refused render lives in `../schemas/mcp.ts`
|
|
12
|
+
* (`renderRefusalSchema`); this file owns the NAMES.
|
|
13
|
+
*
|
|
14
|
+
* ## Why one file
|
|
15
|
+
*
|
|
16
|
+
* The registry is the anti-drift mechanism: one `code` namespace across
|
|
17
|
+
* every surface a deployment can refuse on, so two names can never mean
|
|
18
|
+
* the same state and one name can never mean two. Emitters read a row
|
|
19
|
+
* from here; they never mint a code literal of their own. A code that
|
|
20
|
+
* is not in this file fails the wire enum at the transport, loudly — a
|
|
21
|
+
* bug, never a wire state.
|
|
22
|
+
*
|
|
23
|
+
* ## The rules every row obeys
|
|
24
|
+
*
|
|
25
|
+
* - **Name the STATE, not the verb.** `subscription_exists`, not
|
|
26
|
+
* `cannot_create_subscription`: the same state may refuse more than
|
|
27
|
+
* one action later, and the code must not encode which.
|
|
28
|
+
* - **One state, one code.** Two codes never share a name; one code MAY
|
|
29
|
+
* list several `surfaces` when a single state surfaces in more than
|
|
30
|
+
* one place (`billing_mode_anomaly`).
|
|
31
|
+
* - **`retry` is defined from the CALLER's side.** `after-fix` — a
|
|
32
|
+
* named party can act and the SAME call then succeeds; `next-period`
|
|
33
|
+
* — time restores it at the next period boundary; `later` —
|
|
34
|
+
* unbounded time (transient unavailability); `never` — no action by
|
|
35
|
+
* the caller restores the call under this identity.
|
|
36
|
+
* - **`fixBy` names WHO acts.** REQUIRED on every `after-fix` row;
|
|
37
|
+
* PERMITTED on a `later` row (naming the operator who restores a
|
|
38
|
+
* surface that is transiently unavailable); FORBIDDEN on
|
|
39
|
+
* `next-period` and `never` — time restores the first and nothing
|
|
40
|
+
* restores the second, so naming a party would be a lie about who
|
|
41
|
+
* can act. **An agent MUST NOT auto-retry an `after-fix` refusal
|
|
42
|
+
* whose `fixBy` is not `caller`** — otherwise "retry after fix"
|
|
43
|
+
* would mean "perform someone else's billing or policy decision on
|
|
44
|
+
* their behalf". `caller` is the only value an agent may act on
|
|
45
|
+
* itself.
|
|
46
|
+
* - **`emitter` is named.** A row whose emitter is unrecorded is the
|
|
47
|
+
* drift the registry exists to prevent.
|
|
48
|
+
*
|
|
49
|
+
* ## Reading this file as a self-hoster
|
|
50
|
+
*
|
|
51
|
+
* Every `description` here ships to npm, and the render-gate subset
|
|
52
|
+
* reaches an agent as JSON-Schema metadata through `tools/list`. The
|
|
53
|
+
* wording is therefore written from the DEPLOYMENT-POLICY perspective
|
|
54
|
+
* ("the allowance this deployment configured for the app is
|
|
55
|
+
* exhausted"), never from an operator's internal vocabulary. A
|
|
56
|
+
* deployment that configures none of these policies emits none of these
|
|
57
|
+
* codes; the registry is the vocabulary, not a mandate.
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* The surfaces a refusal code may be emitted on.
|
|
61
|
+
*
|
|
62
|
+
* - `render-gate` — the pre-generation gate on the render/mutation
|
|
63
|
+
* tools. These are the only codes that can appear in a refused
|
|
64
|
+
* tool result's `refusal.code`.
|
|
65
|
+
* - `owner-api` — an app owner's own billing mutations.
|
|
66
|
+
* - `provisioning-api` — a tenant provisioning an app on behalf of
|
|
67
|
+
* its own users.
|
|
68
|
+
*/
|
|
69
|
+
export const REFUSAL_SURFACES = [
|
|
70
|
+
'render-gate',
|
|
71
|
+
'owner-api',
|
|
72
|
+
'provisioning-api',
|
|
73
|
+
];
|
|
74
|
+
/** The closed `retry` vocabulary — see the file header for semantics. */
|
|
75
|
+
export const REFUSAL_RETRIES = [
|
|
76
|
+
'after-fix',
|
|
77
|
+
'next-period',
|
|
78
|
+
'later',
|
|
79
|
+
'never',
|
|
80
|
+
];
|
|
81
|
+
/**
|
|
82
|
+
* Who can act on an `after-fix` refusal. Only `caller` is the agent
|
|
83
|
+
* itself — see the no-auto-retry rule in the file header.
|
|
84
|
+
*/
|
|
85
|
+
export const REFUSAL_FIX_BY = ['caller', 'owner', 'tenant', 'operator'];
|
|
86
|
+
/**
|
|
87
|
+
* The registry is the ONLY list of refusal codes: {@link RefusalCode}
|
|
88
|
+
* is derived from the keys below, and this definer forces every row's
|
|
89
|
+
* `code` to equal its key at the type level. The `const` type parameter
|
|
90
|
+
* preserves each `surfaces` list as a literal tuple, which is what lets
|
|
91
|
+
* {@link PreGenerationRefusalCode} be derived per surface rather than
|
|
92
|
+
* written down a second time.
|
|
93
|
+
*
|
|
94
|
+
* Same posture as `defineModelRegistry` in `./llm.ts`.
|
|
95
|
+
*/
|
|
96
|
+
function defineRefusalRegistry(rows) {
|
|
97
|
+
return rows;
|
|
98
|
+
}
|
|
99
|
+
const REFUSAL_ROWS = /* @__PURE__ */ defineRefusalRegistry({
|
|
100
|
+
// ── render-gate ───────────────────────────────────────────────────
|
|
101
|
+
unsupported_provider: {
|
|
102
|
+
code: 'unsupported_provider',
|
|
103
|
+
surfaces: ['render-gate'],
|
|
104
|
+
retry: 'after-fix',
|
|
105
|
+
fixBy: 'owner',
|
|
106
|
+
emitter: "a deployment's generation gate, provider arm",
|
|
107
|
+
description: 'The provider behind the requested model is not one this deployment can fund for the app. The app owner picks a funded provider or configures the app with its own credentials.',
|
|
108
|
+
},
|
|
109
|
+
insufficient_credit: {
|
|
110
|
+
code: 'insufficient_credit',
|
|
111
|
+
surfaces: ['render-gate'],
|
|
112
|
+
retry: 'after-fix',
|
|
113
|
+
fixBy: 'owner',
|
|
114
|
+
emitter: "a deployment's generation gate, balance arm",
|
|
115
|
+
description: 'The balance this deployment funds the app from is exhausted. The app owner adds funds, after which the same call succeeds.',
|
|
116
|
+
},
|
|
117
|
+
hard_cap_exceeded: {
|
|
118
|
+
code: 'hard_cap_exceeded',
|
|
119
|
+
surfaces: ['render-gate'],
|
|
120
|
+
retry: 'next-period',
|
|
121
|
+
emitter: "a deployment's generation gate, cap arm",
|
|
122
|
+
description: 'The app reached the hard ceiling this deployment set for the current period. Nothing the caller or the owner does lifts it before the period rolls over.',
|
|
123
|
+
},
|
|
124
|
+
model_not_in_tier: {
|
|
125
|
+
code: 'model_not_in_tier',
|
|
126
|
+
surfaces: ['render-gate'],
|
|
127
|
+
retry: 'after-fix',
|
|
128
|
+
fixBy: 'caller',
|
|
129
|
+
emitter: "a deployment's generation gate, model arm",
|
|
130
|
+
description: 'The requested model is not among those the app is allowed to use. The caller picks an allowed model and retries — the one render-gate state an agent may act on itself.',
|
|
131
|
+
},
|
|
132
|
+
managed_default_cap_exceeded: {
|
|
133
|
+
code: 'managed_default_cap_exceeded',
|
|
134
|
+
surfaces: ['render-gate'],
|
|
135
|
+
retry: 'after-fix',
|
|
136
|
+
fixBy: 'tenant',
|
|
137
|
+
emitter: "a deployment's generation gate, delegated-policy arm",
|
|
138
|
+
description: 'The app is running on the default ceiling because the tenant that provisioned it has declared no policy of its own, and that ceiling is reached. The tenant declares an explicit policy for the app.',
|
|
139
|
+
},
|
|
140
|
+
app_policy_missing: {
|
|
141
|
+
code: 'app_policy_missing',
|
|
142
|
+
surfaces: ['render-gate'],
|
|
143
|
+
retry: 'after-fix',
|
|
144
|
+
fixBy: 'tenant',
|
|
145
|
+
emitter: "a deployment's generation gate, delegated-policy arm",
|
|
146
|
+
description: 'The app exists but carries no policy yet — the window between provisioning it and declaring what it may spend. The tenant declares the policy.',
|
|
147
|
+
},
|
|
148
|
+
billing_mode_anomaly: {
|
|
149
|
+
code: 'billing_mode_anomaly',
|
|
150
|
+
// ONE state on TWO surfaces: the same unreadable record refuses a
|
|
151
|
+
// provisioning call and a render. Two entries with one name would
|
|
152
|
+
// be the collision the namespace rule forbids; this is not one.
|
|
153
|
+
surfaces: ['provisioning-api', 'render-gate'],
|
|
154
|
+
retry: 'never',
|
|
155
|
+
emitter: "a deployment's provisioning guard and its generation gate, reading the same record",
|
|
156
|
+
description: 'The app record declares a funding mode this deployment does not recognise, or declares none at all. The value is reported as read and never coerced — an unreadable record is not a policy.',
|
|
157
|
+
},
|
|
158
|
+
app_canceled: {
|
|
159
|
+
code: 'app_canceled',
|
|
160
|
+
surfaces: ['render-gate'],
|
|
161
|
+
retry: 'after-fix',
|
|
162
|
+
fixBy: 'owner',
|
|
163
|
+
emitter: "a deployment's generation gate, plan-state arm",
|
|
164
|
+
description: "The app's plan has ended, so it renders nothing while the stored work is kept. The owner starts a new plan to restore rendering.",
|
|
165
|
+
},
|
|
166
|
+
trial_exhausted: {
|
|
167
|
+
code: 'trial_exhausted',
|
|
168
|
+
surfaces: ['render-gate'],
|
|
169
|
+
retry: 'after-fix',
|
|
170
|
+
fixBy: 'owner',
|
|
171
|
+
emitter: "a deployment's generation gate, trial arm",
|
|
172
|
+
description: 'The trial this deployment grants the app has used up its allotment. The owner starts a paid plan.',
|
|
173
|
+
},
|
|
174
|
+
trial_expired: {
|
|
175
|
+
code: 'trial_expired',
|
|
176
|
+
surfaces: ['render-gate'],
|
|
177
|
+
retry: 'after-fix',
|
|
178
|
+
fixBy: 'owner',
|
|
179
|
+
emitter: "a deployment's generation gate, trial arm",
|
|
180
|
+
description: "The app's trial window has closed. The owner starts a paid plan.",
|
|
181
|
+
},
|
|
182
|
+
issuer_rate_limited: {
|
|
183
|
+
code: 'issuer_rate_limited',
|
|
184
|
+
surfaces: ['render-gate'],
|
|
185
|
+
retry: 'later',
|
|
186
|
+
emitter: "the per-issuer render-rate cap's denial",
|
|
187
|
+
description: 'Calls arriving under this issuing identity are over the rate this deployment allows. Time restores it; retry shortly.',
|
|
188
|
+
},
|
|
189
|
+
app_rate_limited: {
|
|
190
|
+
code: 'app_rate_limited',
|
|
191
|
+
surfaces: ['render-gate'],
|
|
192
|
+
retry: 'later',
|
|
193
|
+
emitter: "the per-app render-rate cap's denial",
|
|
194
|
+
description: 'This app is rendering faster than the rate this deployment allows it. The cap is the app\u2019s own, not the issuing identity\u2019s \u2014 the two are separate states with separate codes. Time restores it; retry shortly.',
|
|
195
|
+
},
|
|
196
|
+
app_deprovisioned: {
|
|
197
|
+
code: 'app_deprovisioned',
|
|
198
|
+
surfaces: ['render-gate'],
|
|
199
|
+
retry: 'never',
|
|
200
|
+
emitter: "the generation gate's owner-claim check, before any reservation or metering",
|
|
201
|
+
description: 'The app record has no owner claim any more \u2014 either the claim was removed, or the record names no issuing tenant at all. A record with no owner cannot be funded, so nothing renders under it and no caller action restores it.',
|
|
202
|
+
},
|
|
203
|
+
billing_path_missing: {
|
|
204
|
+
code: 'billing_path_missing',
|
|
205
|
+
surfaces: ['render-gate'],
|
|
206
|
+
retry: 'after-fix',
|
|
207
|
+
fixBy: 'owner',
|
|
208
|
+
emitter: "the generation gate's fall-through arm: a non-playground identity that resolves to no billing path (not a trial account, not a managed app, not a credit holder)",
|
|
209
|
+
description: 'The caller has no billing subject on this deployment, so nothing renders under it. The owner provisions one — a trial account, a managed policy, or credit. Unlike `billing_mode_anomaly` — an app record that exists and declares a funding mode this deployment cannot read — no record arm applies here: there is simply no subject to bill. A deployment MAY suppress this refusal by operator override; that switch is deployment policy, not a wire state.',
|
|
210
|
+
},
|
|
211
|
+
// ── owner-api ─────────────────────────────────────────────────────
|
|
212
|
+
subscription_exists: {
|
|
213
|
+
code: 'subscription_exists',
|
|
214
|
+
surfaces: ['owner-api'],
|
|
215
|
+
retry: 'after-fix',
|
|
216
|
+
fixBy: 'owner',
|
|
217
|
+
emitter: "a deployment's owner billing mutations",
|
|
218
|
+
description: "An active (non-canceled) plan exists on this app. It refuses starting another one AND deleting the app — the refusal's own `fix` names the next step for the action that was called.",
|
|
219
|
+
},
|
|
220
|
+
checkout_unavailable: {
|
|
221
|
+
code: 'checkout_unavailable',
|
|
222
|
+
surfaces: ['owner-api'],
|
|
223
|
+
retry: 'later',
|
|
224
|
+
fixBy: 'operator',
|
|
225
|
+
emitter: "a deployment's owner billing mutations",
|
|
226
|
+
description: 'The surface that starts a plan is unavailable on this deployment right now — unconfigured, or its provider is down. Only the operator can restore it.',
|
|
227
|
+
},
|
|
228
|
+
card_update_unavailable: {
|
|
229
|
+
code: 'card_update_unavailable',
|
|
230
|
+
surfaces: ['owner-api'],
|
|
231
|
+
retry: 'later',
|
|
232
|
+
fixBy: 'operator',
|
|
233
|
+
emitter: "a deployment's owner billing mutations",
|
|
234
|
+
description: 'The surface that updates a payment method is unavailable on this deployment right now. Only the operator can restore it.',
|
|
235
|
+
},
|
|
236
|
+
portal_unavailable: {
|
|
237
|
+
code: 'portal_unavailable',
|
|
238
|
+
surfaces: ['owner-api'],
|
|
239
|
+
retry: 'later',
|
|
240
|
+
fixBy: 'operator',
|
|
241
|
+
emitter: "a deployment's owner billing mutations",
|
|
242
|
+
description: "The self-service billing surface is unavailable on this deployment right now. Only the operator can restore it.",
|
|
243
|
+
},
|
|
244
|
+
no_subscription: {
|
|
245
|
+
code: 'no_subscription',
|
|
246
|
+
surfaces: ['owner-api'],
|
|
247
|
+
retry: 'after-fix',
|
|
248
|
+
fixBy: 'owner',
|
|
249
|
+
emitter: "a deployment's owner billing mutations",
|
|
250
|
+
description: 'A plan-management action was called on an app that has no plan. The owner starts a plan first.',
|
|
251
|
+
},
|
|
252
|
+
already_on_tier: {
|
|
253
|
+
code: 'already_on_tier',
|
|
254
|
+
surfaces: ['owner-api'],
|
|
255
|
+
retry: 'after-fix',
|
|
256
|
+
fixBy: 'owner',
|
|
257
|
+
emitter: "a deployment's owner billing mutations",
|
|
258
|
+
description: 'The plan requested is the one the app is already on. The owner picks a different plan.',
|
|
259
|
+
},
|
|
260
|
+
managed_app_no_checkout: {
|
|
261
|
+
code: 'managed_app_no_checkout',
|
|
262
|
+
surfaces: ['owner-api'],
|
|
263
|
+
retry: 'never',
|
|
264
|
+
emitter: "a deployment's owner billing mutations",
|
|
265
|
+
description: 'This app is funded by the tenant that provisioned it, so it has no owner-facing plan surface at all. No owner action creates one.',
|
|
266
|
+
},
|
|
267
|
+
managed_app_no_card_update: {
|
|
268
|
+
code: 'managed_app_no_card_update',
|
|
269
|
+
surfaces: ['owner-api'],
|
|
270
|
+
retry: 'never',
|
|
271
|
+
emitter: "a deployment's owner billing mutations",
|
|
272
|
+
description: 'This app is funded by the tenant that provisioned it, so it carries no owner payment method to update.',
|
|
273
|
+
},
|
|
274
|
+
managed_app_no_portal: {
|
|
275
|
+
code: 'managed_app_no_portal',
|
|
276
|
+
surfaces: ['owner-api'],
|
|
277
|
+
retry: 'never',
|
|
278
|
+
emitter: "a deployment's owner billing mutations",
|
|
279
|
+
description: 'This app is funded by the tenant that provisioned it, so it has no owner self-service billing surface.',
|
|
280
|
+
},
|
|
281
|
+
// ── provisioning-api ──────────────────────────────────────────────
|
|
282
|
+
owner_ref_mismatch: {
|
|
283
|
+
code: 'owner_ref_mismatch',
|
|
284
|
+
surfaces: ['provisioning-api'],
|
|
285
|
+
retry: 'after-fix',
|
|
286
|
+
fixBy: 'tenant',
|
|
287
|
+
emitter: "a deployment's provisioning guard",
|
|
288
|
+
description: "The owner reference the caller supplied is not the one recorded on this app. The refusal names the route and the app, never the recorded reference. The tenant re-derives the reference and retries.",
|
|
289
|
+
},
|
|
290
|
+
policy_version_stale: {
|
|
291
|
+
code: 'policy_version_stale',
|
|
292
|
+
surfaces: ['provisioning-api'],
|
|
293
|
+
retry: 'after-fix',
|
|
294
|
+
fixBy: 'tenant',
|
|
295
|
+
emitter: "a deployment's provisioning guard, policy-write arm",
|
|
296
|
+
description: "The policy write carries a version older than the one stored, so it would overwrite a newer decision. The refusal reports the stored version; the tenant re-derives from it and writes again.",
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
/** The registry consumers read. */
|
|
300
|
+
export const PRE_GENERATION_REFUSAL_CODES = REFUSAL_ROWS;
|
|
301
|
+
/**
|
|
302
|
+
* Identity helper that only accepts an EXHAUSTIVE tuple of the
|
|
303
|
+
* render-gate codes: omit one and the parameter type collapses to
|
|
304
|
+
* `never`, so the call site is a compile error. A tuple is needed
|
|
305
|
+
* because the wire enum requires a literal, non-empty tuple — a
|
|
306
|
+
* runtime filter over the rows yields `string[]`, which cannot type an
|
|
307
|
+
* enum. This keeps the tuple derived-CHECKED rather than a second list.
|
|
308
|
+
*/
|
|
309
|
+
const exhaustiveRenderGateCodes = (codes) => codes;
|
|
310
|
+
/**
|
|
311
|
+
* Every render-gate code, as the literal tuple the wire enum
|
|
312
|
+
* (`renderRefusalSchema.code`) is built from. Order is the registry's.
|
|
313
|
+
*/
|
|
314
|
+
export const RENDER_GATE_REFUSAL_CODES = exhaustiveRenderGateCodes([
|
|
315
|
+
'unsupported_provider',
|
|
316
|
+
'insufficient_credit',
|
|
317
|
+
'hard_cap_exceeded',
|
|
318
|
+
'model_not_in_tier',
|
|
319
|
+
'managed_default_cap_exceeded',
|
|
320
|
+
'app_policy_missing',
|
|
321
|
+
'billing_mode_anomaly',
|
|
322
|
+
'billing_path_missing',
|
|
323
|
+
'app_canceled',
|
|
324
|
+
'trial_exhausted',
|
|
325
|
+
'trial_expired',
|
|
326
|
+
'issuer_rate_limited',
|
|
327
|
+
'app_rate_limited',
|
|
328
|
+
'app_deprovisioned',
|
|
329
|
+
]);
|