@game-infra/ai-schemas 0.3.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +149 -0
  3. package/dist/catalog.d.ts +137 -0
  4. package/dist/catalog.d.ts.map +1 -0
  5. package/dist/catalog.js +209 -0
  6. package/dist/catalog.js.map +1 -0
  7. package/dist/contracts.d.ts +1073 -0
  8. package/dist/contracts.d.ts.map +1 -0
  9. package/dist/contracts.js +243 -0
  10. package/dist/contracts.js.map +1 -0
  11. package/dist/featuredModels.d.ts +95 -0
  12. package/dist/featuredModels.d.ts.map +1 -0
  13. package/dist/featuredModels.js +189 -0
  14. package/dist/featuredModels.js.map +1 -0
  15. package/dist/index.d.ts +35 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +39 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/inference.d.ts +323 -0
  20. package/dist/inference.d.ts.map +1 -0
  21. package/dist/inference.js +162 -0
  22. package/dist/inference.js.map +1 -0
  23. package/dist/preference.d.ts +49 -0
  24. package/dist/preference.d.ts.map +1 -0
  25. package/dist/preference.js +74 -0
  26. package/dist/preference.js.map +1 -0
  27. package/dist/preset.d.ts +422 -0
  28. package/dist/preset.d.ts.map +1 -0
  29. package/dist/preset.js +212 -0
  30. package/dist/preset.js.map +1 -0
  31. package/dist/provider.d.ts +487 -0
  32. package/dist/provider.d.ts.map +1 -0
  33. package/dist/provider.js +224 -0
  34. package/dist/provider.js.map +1 -0
  35. package/dist/schemaRegistry.d.ts +71 -0
  36. package/dist/schemaRegistry.d.ts.map +1 -0
  37. package/dist/schemaRegistry.js +35 -0
  38. package/dist/schemaRegistry.js.map +1 -0
  39. package/dist/service.d.ts +143 -0
  40. package/dist/service.d.ts.map +1 -0
  41. package/dist/service.js +103 -0
  42. package/dist/service.js.map +1 -0
  43. package/dist/subscription.d.ts +275 -0
  44. package/dist/subscription.d.ts.map +1 -0
  45. package/dist/subscription.js +198 -0
  46. package/dist/subscription.js.map +1 -0
  47. package/package.json +50 -0
@@ -0,0 +1,275 @@
1
+ import { type InferOutput } from "valibot";
2
+ /**
3
+ * Coding-plan subscriptions, the credentials that are already paid for.
4
+ *
5
+ * A subscription is not an API key with a different name. It is a personal
6
+ * credential issued to one human under terms that usually forbid sharing it, it
7
+ * bills against a flat-rate quota rather than per token, and it is the route
8
+ * this service prefers first for exactly that reason. What makes it different
9
+ * everywhere in the code is the unlock: the token is sealed under a password
10
+ * only its owner knows, so a stored subscription is inert until a request
11
+ * carries that password.
12
+ */
13
+ /**
14
+ * The vendors whose coding plans this service can call.
15
+ *
16
+ * Every one but `codex` speaks the Anthropic Messages dialect: Claude Code is
17
+ * an Anthropic-API client, and Z.ai, Moonshot and DeepSeek each publish an
18
+ * Anthropic-compatible endpoint precisely so it can be pointed at them. That is
19
+ * why one dialect covers four vendors, and why a fifth Anthropic-compatible
20
+ * plan is a table row rather than an integration.
21
+ */
22
+ export declare const SUBSCRIPTION_VENDORS: readonly ["claude", "glm", "kimi", "deepseek", "codex"];
23
+ export declare const SubscriptionVendorSchema: import("valibot").PicklistSchema<readonly ["claude", "glm", "kimi", "deepseek", "codex"], undefined>;
24
+ export type SubscriptionVendor = InferOutput<typeof SubscriptionVendorSchema>;
25
+ /**
26
+ * How a plan's credential is presented to its endpoint.
27
+ *
28
+ * `bearer` puts it in `Authorization: Bearer`, which is what the Claude Code
29
+ * client does with an OAuth token and what every Anthropic-compatible coding
30
+ * plan documents for that client; `api-key` puts it in `x-api-key`, the header
31
+ * Anthropic's own platform keys use. The two are not interchangeable and
32
+ * nothing in the credential says which it is, so it is a property of the vendor
33
+ * rather than something to detect.
34
+ */
35
+ export declare const SUBSCRIPTION_AUTH_SCHEMES: readonly ["bearer", "api-key"];
36
+ export declare const SubscriptionAuthSchemeSchema: import("valibot").PicklistSchema<readonly ["bearer", "api-key"], undefined>;
37
+ export type SubscriptionAuthScheme = InferOutput<typeof SubscriptionAuthSchemeSchema>;
38
+ /** What ai-service knows about a subscription vendor before an operator configures one. */
39
+ export interface SubscriptionVendorProfile {
40
+ /** Label shown in the console. */
41
+ label: string;
42
+ /** The wire dialect its endpoint speaks. */
43
+ dialect: "anthropic" | "openai-responses";
44
+ /**
45
+ * Endpoint the plan's token authenticates against, as the SDK client for
46
+ * {@link dialect} expects it: the base the client appends its own operation
47
+ * path to. For the Anthropic dialect that is the versioned base, because
48
+ * `@ai-sdk/anthropic` appends a bare `/messages` to whatever it is given —
49
+ * a base without the version segment posts to a path the vendor answers 404
50
+ * on, and every request then falls silently through to a metered provider.
51
+ */
52
+ baseUrl: string;
53
+ /** Where the credential goes. */
54
+ authScheme: SubscriptionAuthScheme;
55
+ /**
56
+ * Headers the vendor's client sends alongside the credential. Merged under
57
+ * whatever the stored subscription sets, so an operator can correct one
58
+ * without this table having to be right forever.
59
+ */
60
+ defaultHeaders?: Readonly<Record<string, string>>;
61
+ /**
62
+ * Whether the vendor's own terms license the plan to one named individual.
63
+ * ai-service does not enforce this: it renders it, because the person storing
64
+ * the credential is the one who agreed to those terms and is entitled to know
65
+ * that this service will happily let their colleagues' requests spend it if
66
+ * they hand out the unlock password.
67
+ */
68
+ individualOnly: boolean;
69
+ }
70
+ /**
71
+ * The built-in vendor table.
72
+ *
73
+ * `baseUrl` is a default, not a constant: every field here is overridable on
74
+ * the stored subscription, because a vendor moving an endpoint should be an
75
+ * edit in the console rather than a release of this package.
76
+ *
77
+ * Every Anthropic-dialect entry carries the `/v1` segment for the reason given
78
+ * on {@link SubscriptionVendorProfile.baseUrl}: the SDK client appends only
79
+ * `/messages`, so the version belongs to the base rather than to the client.
80
+ * An operator overriding one of these on a stored subscription has to include
81
+ * it too, which is why the field documents the rule rather than the table.
82
+ */
83
+ export declare const SUBSCRIPTION_VENDOR_PROFILES: Record<SubscriptionVendor, SubscriptionVendorProfile>;
84
+ /**
85
+ * A stored subscription, as the API describes it.
86
+ *
87
+ * There is no field here that could be turned back into the credential, and
88
+ * that is structural rather than careful: the stored value is sealed under the
89
+ * owner's password, so this service could not return the token even if a route
90
+ * asked it to.
91
+ */
92
+ export declare const SubscriptionSchema: import("valibot").ObjectSchema<{
93
+ readonly id: import("valibot").StringSchema<undefined>;
94
+ readonly vendor: import("valibot").PicklistSchema<readonly ["claude", "glm", "kimi", "deepseek", "codex"], undefined>;
95
+ /** Display label, so two plans with the same vendor stay tellable apart. */
96
+ readonly label: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 120, undefined>]>;
97
+ /**
98
+ * Endpoint override. Absent means the vendor profile's own base URL.
99
+ */
100
+ readonly baseUrl: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").UrlAction<string, undefined>, import("valibot").MaxLengthAction<string, 400, undefined>]>, undefined>;
101
+ /**
102
+ * Headers sent alongside the credential, layered over the vendor profile's
103
+ * defaults. This is the seam that keeps a vendor changing a required header
104
+ * from being a release of this package: correct it here and the plan works
105
+ * again. Stored in the clear, so never a place to put a credential.
106
+ */
107
+ readonly headers: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
108
+ readonly name: import("valibot").StringSchema<undefined>;
109
+ readonly value: import("valibot").StringSchema<undefined>;
110
+ }, undefined>, undefined>, undefined>;
111
+ /**
112
+ * The identity-service account that sealed this credential. Only that
113
+ * account's requests may unlock it, because the password check alone would
114
+ * otherwise let anyone who learned the password spend somebody else's quota.
115
+ */
116
+ readonly ownerUserId: import("valibot").StringSchema<undefined>;
117
+ /** Whether routing may pick this subscription. */
118
+ readonly enabled: import("valibot").BooleanSchema<undefined>;
119
+ /** Canonical models this plan serves, and their ids at the vendor. */
120
+ readonly models: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
121
+ readonly model: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 160, undefined>]>;
122
+ readonly providerModelId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 200, undefined>]>;
123
+ }, undefined>, undefined>;
124
+ readonly createdAt: import("valibot").StringSchema<undefined>;
125
+ readonly updatedAt: import("valibot").StringSchema<undefined>;
126
+ }, undefined>;
127
+ export type Subscription = InferOutput<typeof SubscriptionSchema>;
128
+ /** Fields accepted when storing a subscription. */
129
+ export declare const CreateSubscriptionRequestSchema: import("valibot").ObjectSchema<{
130
+ readonly vendor: import("valibot").PicklistSchema<readonly ["claude", "glm", "kimi", "deepseek", "codex"], undefined>;
131
+ readonly label: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 120, undefined>]>;
132
+ readonly baseUrl: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").UrlAction<string, undefined>, import("valibot").MaxLengthAction<string, 400, undefined>]>, undefined>;
133
+ readonly headers: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
134
+ readonly name: import("valibot").StringSchema<undefined>;
135
+ readonly value: import("valibot").StringSchema<undefined>;
136
+ }, undefined>, undefined>, undefined>;
137
+ /**
138
+ * The plan's own credential: a Claude Code OAuth token, a Codex session
139
+ * token, or a coding-plan key. Sealed under {@link password} before it is
140
+ * written and unreadable without it.
141
+ */
142
+ readonly credential: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 8000, undefined>]>;
143
+ /**
144
+ * The password the credential is sealed under. It is never stored, in any
145
+ * form: a wrong password is detected by the seal failing to open, not by
146
+ * comparing against something on disk, so there is nothing here for a
147
+ * database dump to attack offline beyond the sealed credential itself.
148
+ */
149
+ readonly password: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 8, undefined>, import("valibot").MaxLengthAction<string, 400, undefined>]>;
150
+ readonly enabled: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
151
+ readonly models: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
152
+ readonly model: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 160, undefined>]>;
153
+ readonly providerModelId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 200, undefined>]>;
154
+ }, undefined>, undefined>, undefined>;
155
+ }, undefined>;
156
+ export type CreateSubscriptionRequest = InferOutput<typeof CreateSubscriptionRequestSchema>;
157
+ /** Fields accepted when updating a subscription. The credential is replaced by re-creating it. */
158
+ export declare const UpdateSubscriptionRequestSchema: import("valibot").ObjectSchema<{
159
+ readonly label: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 120, undefined>]>, undefined>;
160
+ readonly baseUrl: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").UrlAction<string, undefined>, import("valibot").MaxLengthAction<string, 400, undefined>]>, undefined>;
161
+ readonly headers: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
162
+ readonly name: import("valibot").StringSchema<undefined>;
163
+ readonly value: import("valibot").StringSchema<undefined>;
164
+ }, undefined>, undefined>, undefined>;
165
+ readonly enabled: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
166
+ readonly models: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
167
+ readonly model: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 160, undefined>]>;
168
+ readonly providerModelId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 200, undefined>]>;
169
+ }, undefined>, undefined>, undefined>;
170
+ }, undefined>;
171
+ export type UpdateSubscriptionRequest = InferOutput<typeof UpdateSubscriptionRequestSchema>;
172
+ /** A password offered against a stored subscription. */
173
+ export declare const UnlockSubscriptionRequestSchema: import("valibot").ObjectSchema<{
174
+ readonly password: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 400, undefined>]>;
175
+ }, undefined>;
176
+ export type UnlockSubscriptionRequest = InferOutput<typeof UnlockSubscriptionRequestSchema>;
177
+ /**
178
+ * Whether the offered password opened the seal.
179
+ *
180
+ * The console uses this to tell somebody they typed the wrong password while
181
+ * they are still in the credential screen, rather than letting them find out
182
+ * from a run that silently fell through to a metered provider.
183
+ */
184
+ export declare const UnlockSubscriptionResponseSchema: import("valibot").ObjectSchema<{
185
+ readonly success: import("valibot").BooleanSchema<undefined>;
186
+ readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
187
+ } & {
188
+ unlocked: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
189
+ }, undefined>;
190
+ export type UnlockSubscriptionResponse = InferOutput<typeof UnlockSubscriptionResponseSchema>;
191
+ /** One subscription. */
192
+ export declare const SubscriptionResponseSchema: import("valibot").ObjectSchema<{
193
+ readonly success: import("valibot").BooleanSchema<undefined>;
194
+ readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
195
+ } & {
196
+ subscription: import("valibot").OptionalSchema<import("valibot").ObjectSchema<{
197
+ readonly id: import("valibot").StringSchema<undefined>;
198
+ readonly vendor: import("valibot").PicklistSchema<readonly ["claude", "glm", "kimi", "deepseek", "codex"], undefined>;
199
+ /** Display label, so two plans with the same vendor stay tellable apart. */
200
+ readonly label: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 120, undefined>]>;
201
+ /**
202
+ * Endpoint override. Absent means the vendor profile's own base URL.
203
+ */
204
+ readonly baseUrl: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").UrlAction<string, undefined>, import("valibot").MaxLengthAction<string, 400, undefined>]>, undefined>;
205
+ /**
206
+ * Headers sent alongside the credential, layered over the vendor profile's
207
+ * defaults. This is the seam that keeps a vendor changing a required header
208
+ * from being a release of this package: correct it here and the plan works
209
+ * again. Stored in the clear, so never a place to put a credential.
210
+ */
211
+ readonly headers: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
212
+ readonly name: import("valibot").StringSchema<undefined>;
213
+ readonly value: import("valibot").StringSchema<undefined>;
214
+ }, undefined>, undefined>, undefined>;
215
+ /**
216
+ * The identity-service account that sealed this credential. Only that
217
+ * account's requests may unlock it, because the password check alone would
218
+ * otherwise let anyone who learned the password spend somebody else's quota.
219
+ */
220
+ readonly ownerUserId: import("valibot").StringSchema<undefined>;
221
+ /** Whether routing may pick this subscription. */
222
+ readonly enabled: import("valibot").BooleanSchema<undefined>;
223
+ /** Canonical models this plan serves, and their ids at the vendor. */
224
+ readonly models: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
225
+ readonly model: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 160, undefined>]>;
226
+ readonly providerModelId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 200, undefined>]>;
227
+ }, undefined>, undefined>;
228
+ readonly createdAt: import("valibot").StringSchema<undefined>;
229
+ readonly updatedAt: import("valibot").StringSchema<undefined>;
230
+ }, undefined>, undefined>;
231
+ }, undefined>;
232
+ export type SubscriptionResponse = InferOutput<typeof SubscriptionResponseSchema>;
233
+ /** Every subscription the calling account owns. */
234
+ export declare const SubscriptionListResponseSchema: import("valibot").ObjectSchema<{
235
+ readonly success: import("valibot").BooleanSchema<undefined>;
236
+ readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
237
+ } & {
238
+ subscriptions: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
239
+ readonly id: import("valibot").StringSchema<undefined>;
240
+ readonly vendor: import("valibot").PicklistSchema<readonly ["claude", "glm", "kimi", "deepseek", "codex"], undefined>;
241
+ /** Display label, so two plans with the same vendor stay tellable apart. */
242
+ readonly label: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 120, undefined>]>;
243
+ /**
244
+ * Endpoint override. Absent means the vendor profile's own base URL.
245
+ */
246
+ readonly baseUrl: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").UrlAction<string, undefined>, import("valibot").MaxLengthAction<string, 400, undefined>]>, undefined>;
247
+ /**
248
+ * Headers sent alongside the credential, layered over the vendor profile's
249
+ * defaults. This is the seam that keeps a vendor changing a required header
250
+ * from being a release of this package: correct it here and the plan works
251
+ * again. Stored in the clear, so never a place to put a credential.
252
+ */
253
+ readonly headers: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
254
+ readonly name: import("valibot").StringSchema<undefined>;
255
+ readonly value: import("valibot").StringSchema<undefined>;
256
+ }, undefined>, undefined>, undefined>;
257
+ /**
258
+ * The identity-service account that sealed this credential. Only that
259
+ * account's requests may unlock it, because the password check alone would
260
+ * otherwise let anyone who learned the password spend somebody else's quota.
261
+ */
262
+ readonly ownerUserId: import("valibot").StringSchema<undefined>;
263
+ /** Whether routing may pick this subscription. */
264
+ readonly enabled: import("valibot").BooleanSchema<undefined>;
265
+ /** Canonical models this plan serves, and their ids at the vendor. */
266
+ readonly models: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
267
+ readonly model: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 160, undefined>]>;
268
+ readonly providerModelId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 200, undefined>]>;
269
+ }, undefined>, undefined>;
270
+ readonly createdAt: import("valibot").StringSchema<undefined>;
271
+ readonly updatedAt: import("valibot").StringSchema<undefined>;
272
+ }, undefined>, undefined>, undefined>;
273
+ }, undefined>;
274
+ export type SubscriptionListResponse = InferOutput<typeof SubscriptionListResponseSchema>;
275
+ //# sourceMappingURL=subscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../src/subscription.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAWjB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;GAUG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,YAAI,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAU,CAAC;AAC5F,eAAO,MAAM,wBAAwB,sGAAiC,CAAC;AACvE,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE9E;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,YAAI,QAAQ,EAAE,SAAS,CAAU,CAAC;AACxE,eAAO,MAAM,4BAA4B,6EAAsC,CAAC;AAChF,MAAM,MAAM,sBAAsB,GAAG,WAAW,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAEtF,2FAA2F;AAC3F,MAAM,WAAW,yBAAyB;IACxC,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,OAAO,EAAE,WAAW,GAAG,kBAAkB,CAAC;IAC1C;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,UAAU,EAAE,sBAAsB,CAAC;IACnC;;;;OAIG;IACH,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD;;;;;;OAMG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,kBAAkB,EAAE,yBAAyB,CAiD9F,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;;IAG7B,4EAA4E;;IAE5E;;OAEG;;IAEH;;;;;OAKG;;;;;IAEH;;;;OAIG;;IAEH,kDAAkD;;IAElD,sEAAsE;;;;;;;aAStE,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAElE,mDAAmD;AACnD,eAAO,MAAM,+BAA+B;;;;;;;;IAK1C;;;;OAIG;;IAEH;;;;;OAKG;;;;;;;aAWH,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,WAAW,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAE5F,kGAAkG;AAClG,eAAO,MAAM,+BAA+B;;;;;;;;;;;;aAa1C,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,WAAW,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAE5F,wDAAwD;AACxD,eAAO,MAAM,+BAA+B;;aAE1C,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,WAAW,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAE5F;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC;;;;;aAE3C,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,WAAW,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE9F,wBAAwB;AACxB,eAAO,MAAM,0BAA0B;;;;;;;QAzGrC,4EAA4E;;QAE5E;;WAEG;;QAEH;;;;;WAKG;;;;;QAEH;;;;WAIG;;QAEH,kDAAkD;;QAElD,sEAAsE;;;;;;;;aAsFtE,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,WAAW,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAElF,mDAAmD;AACnD,eAAO,MAAM,8BAA8B;;;;;;;QA/GzC,4EAA4E;;QAE5E;;WAEG;;QAEH;;;;;WAKG;;;;;QAEH;;;;WAIG;;QAEH,kDAAkD;;QAElD,sEAAsE;;;;;;;;aA4FtE,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,WAAW,CAAC,OAAO,8BAA8B,CAAC,CAAC"}
@@ -0,0 +1,198 @@
1
+ import { createSuccessResponseSchema } from "@game-infra/api-schemas-core";
2
+ import { array, boolean, maxLength, minLength, object, optional, picklist, pipe, string, url, } from "valibot";
3
+ /**
4
+ * Coding-plan subscriptions, the credentials that are already paid for.
5
+ *
6
+ * A subscription is not an API key with a different name. It is a personal
7
+ * credential issued to one human under terms that usually forbid sharing it, it
8
+ * bills against a flat-rate quota rather than per token, and it is the route
9
+ * this service prefers first for exactly that reason. What makes it different
10
+ * everywhere in the code is the unlock: the token is sealed under a password
11
+ * only its owner knows, so a stored subscription is inert until a request
12
+ * carries that password.
13
+ */
14
+ /**
15
+ * The vendors whose coding plans this service can call.
16
+ *
17
+ * Every one but `codex` speaks the Anthropic Messages dialect: Claude Code is
18
+ * an Anthropic-API client, and Z.ai, Moonshot and DeepSeek each publish an
19
+ * Anthropic-compatible endpoint precisely so it can be pointed at them. That is
20
+ * why one dialect covers four vendors, and why a fifth Anthropic-compatible
21
+ * plan is a table row rather than an integration.
22
+ */
23
+ export const SUBSCRIPTION_VENDORS = ["claude", "glm", "kimi", "deepseek", "codex"];
24
+ export const SubscriptionVendorSchema = picklist(SUBSCRIPTION_VENDORS);
25
+ /**
26
+ * How a plan's credential is presented to its endpoint.
27
+ *
28
+ * `bearer` puts it in `Authorization: Bearer`, which is what the Claude Code
29
+ * client does with an OAuth token and what every Anthropic-compatible coding
30
+ * plan documents for that client; `api-key` puts it in `x-api-key`, the header
31
+ * Anthropic's own platform keys use. The two are not interchangeable and
32
+ * nothing in the credential says which it is, so it is a property of the vendor
33
+ * rather than something to detect.
34
+ */
35
+ export const SUBSCRIPTION_AUTH_SCHEMES = ["bearer", "api-key"];
36
+ export const SubscriptionAuthSchemeSchema = picklist(SUBSCRIPTION_AUTH_SCHEMES);
37
+ /**
38
+ * The built-in vendor table.
39
+ *
40
+ * `baseUrl` is a default, not a constant: every field here is overridable on
41
+ * the stored subscription, because a vendor moving an endpoint should be an
42
+ * edit in the console rather than a release of this package.
43
+ *
44
+ * Every Anthropic-dialect entry carries the `/v1` segment for the reason given
45
+ * on {@link SubscriptionVendorProfile.baseUrl}: the SDK client appends only
46
+ * `/messages`, so the version belongs to the base rather than to the client.
47
+ * An operator overriding one of these on a stored subscription has to include
48
+ * it too, which is why the field documents the rule rather than the table.
49
+ */
50
+ export const SUBSCRIPTION_VENDOR_PROFILES = {
51
+ claude: {
52
+ label: "Claude (Anthropic)",
53
+ dialect: "anthropic",
54
+ baseUrl: "https://api.anthropic.com/v1",
55
+ authScheme: "bearer",
56
+ // The beta header the Claude Code client sends with an OAuth token. An
57
+ // Anthropic PLATFORM key needs neither this nor the bearer scheme, and is
58
+ // configured as an `anthropic` provider rather than as a subscription.
59
+ defaultHeaders: { "anthropic-beta": "oauth-2025-04-20" },
60
+ individualOnly: true,
61
+ },
62
+ glm: {
63
+ label: "GLM (Z.ai)",
64
+ dialect: "anthropic",
65
+ baseUrl: "https://api.z.ai/api/anthropic/v1",
66
+ authScheme: "bearer",
67
+ individualOnly: true,
68
+ },
69
+ kimi: {
70
+ label: "Kimi (Moonshot)",
71
+ dialect: "anthropic",
72
+ baseUrl: "https://api.moonshot.ai/anthropic/v1",
73
+ authScheme: "bearer",
74
+ individualOnly: false,
75
+ },
76
+ deepseek: {
77
+ label: "DeepSeek",
78
+ dialect: "anthropic",
79
+ baseUrl: "https://api.deepseek.com/anthropic/v1",
80
+ authScheme: "bearer",
81
+ individualOnly: false,
82
+ },
83
+ /**
84
+ * The ChatGPT plan behind Codex. It is the one vendor here that does not
85
+ * speak the Anthropic dialect: its endpoint is the OpenAI Responses shape,
86
+ * served from the ChatGPT backend rather than the platform API, and it is the
87
+ * one whose base URL an operator is most likely to have to correct, because
88
+ * OpenAI documents that host for the Codex client rather than as a public
89
+ * API. Stored as a default so a working deployment is one edit away, not as
90
+ * an assertion that it is stable.
91
+ */
92
+ codex: {
93
+ label: "ChatGPT (Codex)",
94
+ dialect: "openai-responses",
95
+ baseUrl: "https://chatgpt.com/backend-api/codex",
96
+ authScheme: "bearer",
97
+ individualOnly: true,
98
+ },
99
+ };
100
+ /**
101
+ * A stored subscription, as the API describes it.
102
+ *
103
+ * There is no field here that could be turned back into the credential, and
104
+ * that is structural rather than careful: the stored value is sealed under the
105
+ * owner's password, so this service could not return the token even if a route
106
+ * asked it to.
107
+ */
108
+ export const SubscriptionSchema = object({
109
+ id: string(),
110
+ vendor: SubscriptionVendorSchema,
111
+ /** Display label, so two plans with the same vendor stay tellable apart. */
112
+ label: pipe(string(), minLength(1), maxLength(120)),
113
+ /**
114
+ * Endpoint override. Absent means the vendor profile's own base URL.
115
+ */
116
+ baseUrl: optional(pipe(string(), url(), maxLength(400))),
117
+ /**
118
+ * Headers sent alongside the credential, layered over the vendor profile's
119
+ * defaults. This is the seam that keeps a vendor changing a required header
120
+ * from being a release of this package: correct it here and the plan works
121
+ * again. Stored in the clear, so never a place to put a credential.
122
+ */
123
+ headers: optional(array(object({ name: string(), value: string() }))),
124
+ /**
125
+ * The identity-service account that sealed this credential. Only that
126
+ * account's requests may unlock it, because the password check alone would
127
+ * otherwise let anyone who learned the password spend somebody else's quota.
128
+ */
129
+ ownerUserId: string(),
130
+ /** Whether routing may pick this subscription. */
131
+ enabled: boolean(),
132
+ /** Canonical models this plan serves, and their ids at the vendor. */
133
+ models: array(object({
134
+ model: pipe(string(), minLength(1), maxLength(160)),
135
+ providerModelId: pipe(string(), minLength(1), maxLength(200)),
136
+ })),
137
+ createdAt: string(),
138
+ updatedAt: string(),
139
+ });
140
+ /** Fields accepted when storing a subscription. */
141
+ export const CreateSubscriptionRequestSchema = object({
142
+ vendor: SubscriptionVendorSchema,
143
+ label: pipe(string(), minLength(1), maxLength(120)),
144
+ baseUrl: optional(pipe(string(), url(), maxLength(400))),
145
+ headers: optional(array(object({ name: string(), value: string() }))),
146
+ /**
147
+ * The plan's own credential: a Claude Code OAuth token, a Codex session
148
+ * token, or a coding-plan key. Sealed under {@link password} before it is
149
+ * written and unreadable without it.
150
+ */
151
+ credential: pipe(string(), minLength(1), maxLength(8000)),
152
+ /**
153
+ * The password the credential is sealed under. It is never stored, in any
154
+ * form: a wrong password is detected by the seal failing to open, not by
155
+ * comparing against something on disk, so there is nothing here for a
156
+ * database dump to attack offline beyond the sealed credential itself.
157
+ */
158
+ password: pipe(string(), minLength(8), maxLength(400)),
159
+ enabled: optional(boolean()),
160
+ models: optional(array(object({
161
+ model: pipe(string(), minLength(1), maxLength(160)),
162
+ providerModelId: pipe(string(), minLength(1), maxLength(200)),
163
+ }))),
164
+ });
165
+ /** Fields accepted when updating a subscription. The credential is replaced by re-creating it. */
166
+ export const UpdateSubscriptionRequestSchema = object({
167
+ label: optional(pipe(string(), minLength(1), maxLength(120))),
168
+ baseUrl: optional(pipe(string(), url(), maxLength(400))),
169
+ headers: optional(array(object({ name: string(), value: string() }))),
170
+ enabled: optional(boolean()),
171
+ models: optional(array(object({
172
+ model: pipe(string(), minLength(1), maxLength(160)),
173
+ providerModelId: pipe(string(), minLength(1), maxLength(200)),
174
+ }))),
175
+ });
176
+ /** A password offered against a stored subscription. */
177
+ export const UnlockSubscriptionRequestSchema = object({
178
+ password: pipe(string(), minLength(1), maxLength(400)),
179
+ });
180
+ /**
181
+ * Whether the offered password opened the seal.
182
+ *
183
+ * The console uses this to tell somebody they typed the wrong password while
184
+ * they are still in the credential screen, rather than letting them find out
185
+ * from a run that silently fell through to a metered provider.
186
+ */
187
+ export const UnlockSubscriptionResponseSchema = createSuccessResponseSchema({
188
+ unlocked: optional(boolean()),
189
+ });
190
+ /** One subscription. */
191
+ export const SubscriptionResponseSchema = createSuccessResponseSchema({
192
+ subscription: optional(SubscriptionSchema),
193
+ });
194
+ /** Every subscription the calling account owns. */
195
+ export const SubscriptionListResponseSchema = createSuccessResponseSchema({
196
+ subscriptions: optional(array(SubscriptionSchema)),
197
+ });
198
+ //# sourceMappingURL=subscription.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription.js","sourceRoot":"","sources":["../src/subscription.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@game-infra/ai-schemas",
3
+ "version": "0.3.0",
4
+ "description": "ai-service API contract: provider/credential/subscription configuration, routing presets, the named request-schema registry, and the inference endpoint definitions",
5
+ "homepage": "https://github.com/kibertoad/game-infra/tree/main/packages/schemas/ai-schemas#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/kibertoad/game-infra/issues"
8
+ },
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/kibertoad/game-infra.git",
13
+ "directory": "packages/schemas/ai-schemas"
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "type": "module",
19
+ "sideEffects": false,
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "default": "./dist/index.js"
24
+ }
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "dependencies": {
30
+ "@toad-contracts/core": "0.4.0",
31
+ "@toad-contracts/valibot": "0.5.0",
32
+ "@game-infra/api-schemas-core": "0.3.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^26.1.2",
36
+ "rimraf": "^6.1.3",
37
+ "typescript": "^7.0.2",
38
+ "valibot": "^1.4.2",
39
+ "vitest": "^4.1.10"
40
+ },
41
+ "peerDependencies": {
42
+ "valibot": "^1.4.0"
43
+ },
44
+ "scripts": {
45
+ "build": "rimraf dist && tsc --project tsconfig.build.json",
46
+ "typecheck": "tsc --noEmit",
47
+ "test": "vitest run",
48
+ "clean": "rimraf dist"
49
+ }
50
+ }