@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,224 @@
1
+ import { createSuccessResponseSchema } from "@game-infra/api-schemas-core";
2
+ import { array, boolean, maxLength, minLength, number, object, optional, picklist, pipe, regex, string, url, } from "valibot";
3
+ /**
4
+ * How ai-service names the ways a model can be reached.
5
+ *
6
+ * The distinction that matters is not the vendor but who pays and how, because
7
+ * that is what routing preference is expressed in: a flat-rate coding-plan
8
+ * subscription is already paid for, a direct API key is metered by the vendor
9
+ * that trained the model, an umbrella gateway resells other vendors' models at
10
+ * a markup, and a local server costs whatever the operator's hardware costs.
11
+ * Preference is declared over these tiers rather than over provider ids, so a
12
+ * deployment that adds a second gateway does not have to restate its policy.
13
+ */
14
+ export const PROVIDER_TIERS = ["subscription", "direct", "local", "umbrella"];
15
+ export const ProviderTierSchema = picklist(PROVIDER_TIERS);
16
+ /**
17
+ * The default order tiers are tried in.
18
+ *
19
+ * Subscription first because its quota is already bought and spending metered
20
+ * tokens beside it is waste; then the model's own vendor, which is the cheapest
21
+ * metered route and the one whose behaviour the model was documented against;
22
+ * then a local server, which costs nothing per token but is only as available
23
+ * as the machine it runs on; and finally an umbrella gateway, which can serve
24
+ * almost anything but at a resale price.
25
+ *
26
+ * A preset reorders this list. It never filters: a tier left out of a preset's
27
+ * preference is appended in this order rather than dropped, so a preference
28
+ * written before a tier existed cannot silently make that tier unreachable.
29
+ */
30
+ export const DEFAULT_TIER_PREFERENCE = PROVIDER_TIERS;
31
+ /**
32
+ * How a provider is authenticated, which decides what the credential routes
33
+ * expect and whether a call needs a manual unlock.
34
+ *
35
+ * - `api-key` — one key held by the deployment, sealed under `ENCRYPTION_KEY`
36
+ * and usable by any call this service serves.
37
+ * - `subscription` — a personal coding-plan credential (Claude Code, Codex, and
38
+ * the Anthropic-compatible plans) that its owner sealed under a password only
39
+ * they know. It is unusable until a request carries that password.
40
+ * - `none` — nothing to store. Either an endpoint that takes no credential at
41
+ * all, which is the normal shape of an Ollama or vLLM server on a trusted
42
+ * network, or one reached through a Worker binding, where the platform
43
+ * authorises the call and there is no key for this service to hold.
44
+ */
45
+ export const CREDENTIAL_KINDS = ["api-key", "subscription", "none"];
46
+ export const CredentialKindSchema = picklist(CREDENTIAL_KINDS);
47
+ /**
48
+ * The wire dialect a provider speaks, which is what decides the SDK client
49
+ * ai-service builds for it.
50
+ *
51
+ * Nearly everything is `openai-compatible`: the OpenAI `/chat/completions`
52
+ * shape is what the gateways, the local runners and most direct vendors expose,
53
+ * so one client covers them. `openai` and `anthropic` are the two first-party
54
+ * dialects worth using natively, because their own SDKs carry the structured
55
+ * output and prompt-caching features the compatible shape flattens away.
56
+ *
57
+ * `workers-ai` is the one that is not HTTP at all. It reaches Cloudflare's
58
+ * hosted models through the Worker's own `AI` binding, so the call never leaves
59
+ * the runtime: no account id in a URL, no API token to seal, rotate or leak,
60
+ * and no egress hop. That is why it is a dialect rather than a base URL — what
61
+ * differs is the transport, not the wire format — and why a provider on it
62
+ * needs neither `baseUrl` nor a credential.
63
+ */
64
+ export const PROVIDER_DIALECTS = [
65
+ "openai",
66
+ "anthropic",
67
+ "openai-compatible",
68
+ "workers-ai",
69
+ ];
70
+ export const ProviderDialectSchema = picklist(PROVIDER_DIALECTS);
71
+ /** Lowercase, dash-separated identifier a provider is referred to by. */
72
+ export const ProviderIdSchema = pipe(string(), minLength(1), maxLength(64), regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "must be lowercase words separated by single dashes"));
73
+ /**
74
+ * One model this provider serves, and the id it serves it under.
75
+ *
76
+ * The pair is the whole point. A caller asks for a canonical model
77
+ * (`claude-sonnet-4-5`); OpenRouter serves that same model as
78
+ * `anthropic/claude-sonnet-4.5` and a self-hosted vLLM serves it under whatever
79
+ * the operator named the weights. Nothing can derive one from the other, so the
80
+ * mapping is configuration rather than a guess, and a canonical id no
81
+ * configured provider maps is simply a model this deployment cannot route.
82
+ */
83
+ export const ProviderModelRouteSchema = object({
84
+ /** Canonical model id, the name a caller asks for. */
85
+ model: pipe(string(), minLength(1), maxLength(160)),
86
+ /** The id this provider serves that model under. */
87
+ providerModelId: pipe(string(), minLength(1), maxLength(200)),
88
+ /**
89
+ * Cost per million input tokens, in whatever currency the operator is
90
+ * budgeting in. Advisory: shown beside a route so the person ordering the
91
+ * preference can see what the fallback costs, never used to reorder anything
92
+ * on its own.
93
+ */
94
+ inputCostPerMillion: optional(number()),
95
+ /** Cost per million output tokens, on the same terms. */
96
+ outputCostPerMillion: optional(number()),
97
+ /**
98
+ * Whether this route accepts image parts. Absent means nobody has said, which
99
+ * is not the same as "no": a request carrying images skips a route declared
100
+ * `false` and reports `model_no_image_input`, and skips an undeclared one
101
+ * reporting `unknown_model_image_input`, which is the difference between
102
+ * "this cannot work" and "declare it and it will".
103
+ */
104
+ acceptsImages: optional(boolean()),
105
+ /**
106
+ * Whether this route supports provider-native structured output. Absent means
107
+ * undeclared and is treated as capable, because every dialect ai-service
108
+ * speaks has a structured-output path; set it to `false` for a local server
109
+ * whose runtime does not implement one, so `/generate/object` routes past it
110
+ * instead of failing on it.
111
+ */
112
+ supportsStructuredOutput: optional(boolean()),
113
+ });
114
+ /**
115
+ * A configured way to reach models.
116
+ *
117
+ * The record never carries the credential itself. `credentialConfigured` and
118
+ * `credentialHint` are what the console renders, and they are all the API will
119
+ * ever say about a stored key: the ciphertext is opened in memory at call time
120
+ * and nothing reads it back out over HTTP.
121
+ */
122
+ export const ProviderSchema = object({
123
+ id: string(),
124
+ /** Stable key used in preset preferences and in a request's `provider` pin. */
125
+ providerId: ProviderIdSchema,
126
+ /** Display name shown in the console. */
127
+ name: pipe(string(), minLength(1), maxLength(120)),
128
+ tier: ProviderTierSchema,
129
+ dialect: ProviderDialectSchema,
130
+ credentialKind: CredentialKindSchema,
131
+ /**
132
+ * Where this provider lives. Required for `openai-compatible`, which has no
133
+ * default host to fall back on; optional for the two first-party dialects,
134
+ * whose SDKs carry their own and which accept an override so a deployment can
135
+ * point them at a compatible endpoint; ignored for `workers-ai`, which is not
136
+ * reached over HTTP and has no URL to point anywhere.
137
+ */
138
+ baseUrl: optional(pipe(string(), url(), maxLength(400))),
139
+ /**
140
+ * Whether routing may pick this provider. A disabled provider keeps its
141
+ * credential and its routes, so taking a gateway out of rotation during an
142
+ * outage is one toggle and putting it back does not mean re-entering a key.
143
+ */
144
+ enabled: boolean(),
145
+ /** The canonical models this provider serves, and their ids here. */
146
+ models: array(ProviderModelRouteSchema),
147
+ /**
148
+ * Extra headers sent with every call. For the gateways that ask for
149
+ * attribution headers (OpenRouter's `HTTP-Referer` / `X-Title`) and for a
150
+ * self-hosted gateway behind a proxy that wants a routing header. Never a
151
+ * place to put a credential: values are stored in the clear.
152
+ */
153
+ headers: optional(array(object({ name: string(), value: string() }))),
154
+ /** Whether a credential is stored for this provider. */
155
+ credentialConfigured: boolean(),
156
+ /**
157
+ * The last four characters of the stored key, which is enough to tell two
158
+ * keys apart when someone is deciding whether to rotate one, and not enough
159
+ * to use. Absent for `none` and for a provider with nothing stored yet.
160
+ */
161
+ credentialHint: optional(string()),
162
+ createdAt: string(),
163
+ updatedAt: string(),
164
+ });
165
+ /** Fields accepted when registering a provider. */
166
+ export const CreateProviderRequestSchema = object({
167
+ providerId: ProviderIdSchema,
168
+ name: pipe(string(), minLength(1), maxLength(120)),
169
+ tier: ProviderTierSchema,
170
+ dialect: ProviderDialectSchema,
171
+ credentialKind: CredentialKindSchema,
172
+ baseUrl: optional(pipe(string(), url(), maxLength(400))),
173
+ enabled: optional(boolean()),
174
+ models: optional(array(ProviderModelRouteSchema)),
175
+ headers: optional(array(object({ name: string(), value: string() }))),
176
+ /**
177
+ * The API key, supplied at creation so registering a provider is one call.
178
+ * Sealed before it is written and never readable afterwards; replace it
179
+ * through the credential route.
180
+ */
181
+ apiKey: optional(pipe(string(), minLength(1), maxLength(4000))),
182
+ });
183
+ /** Fields accepted when updating a provider. Absent means unchanged. */
184
+ export const UpdateProviderRequestSchema = object({
185
+ name: optional(pipe(string(), minLength(1), maxLength(120))),
186
+ tier: optional(ProviderTierSchema),
187
+ dialect: optional(ProviderDialectSchema),
188
+ baseUrl: optional(pipe(string(), url(), maxLength(400))),
189
+ enabled: optional(boolean()),
190
+ /** Replaces the whole list. The console edits routes as a table, not row by row. */
191
+ models: optional(array(ProviderModelRouteSchema)),
192
+ headers: optional(array(object({ name: string(), value: string() }))),
193
+ });
194
+ /** A key to seal for a provider. */
195
+ export const SetProviderCredentialRequestSchema = object({
196
+ apiKey: pipe(string(), minLength(1), maxLength(4000)),
197
+ });
198
+ /** One provider. */
199
+ export const ProviderResponseSchema = createSuccessResponseSchema({
200
+ provider: optional(ProviderSchema),
201
+ });
202
+ /** Every configured provider. */
203
+ export const ProviderListResponseSchema = createSuccessResponseSchema({
204
+ providers: optional(array(ProviderSchema)),
205
+ });
206
+ /**
207
+ * What a live probe of a provider found.
208
+ *
209
+ * Separate fields rather than one boolean, because "the key is wrong" and "the
210
+ * host did not answer" are fixed in different places, and a caller told only
211
+ * that the provider is unhealthy has to guess which.
212
+ */
213
+ export const ProviderProbeResponseSchema = createSuccessResponseSchema({
214
+ providerId: optional(string()),
215
+ /** Whether the provider answered a real request. */
216
+ reachable: optional(boolean()),
217
+ /** The model the probe called, so a failure names something concrete. */
218
+ model: optional(string()),
219
+ /** Round-trip time of the probe call, in milliseconds. */
220
+ latencyMs: optional(number()),
221
+ /** Vendor or transport failure, verbatim, when there was one. */
222
+ failure: optional(string()),
223
+ });
224
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import { type InferOutput } from "valibot";
2
+ /**
3
+ * The published description of one registered request schema.
4
+ *
5
+ * A caller that names a `schemaId` has to be able to write code against what
6
+ * comes back, and the only honest way to give it that is the schema itself.
7
+ * `jsonSchema` is the same document handed to the provider's structured-output
8
+ * API, not a summary of it, so a caller generating types from this endpoint and
9
+ * the model filling in the response are working from one description.
10
+ */
11
+ export declare const RegisteredSchemaSchema: import("valibot").ObjectSchema<{
12
+ /** The id a request names. */
13
+ readonly id: import("valibot").StringSchema<undefined>;
14
+ /** What this shape is for, in a sentence. */
15
+ readonly description: import("valibot").StringSchema<undefined>;
16
+ /**
17
+ * Whether the provider is asked to enforce the shape exactly (no extra keys,
18
+ * every declared field present). True for everything shipped here; a schema
19
+ * whose union or recursion a provider's strict mode cannot express is
20
+ * registered non-strict rather than silently rewritten.
21
+ */
22
+ readonly strict: import("valibot").BooleanSchema<undefined>;
23
+ /** The JSON Schema document sent to the provider. */
24
+ readonly jsonSchema: import("valibot").AnySchema;
25
+ }, undefined>;
26
+ export type RegisteredSchema = InferOutput<typeof RegisteredSchemaSchema>;
27
+ /** Every schema this deployment will accept a `schemaId` for. */
28
+ export declare const SchemaListResponseSchema: import("valibot").ObjectSchema<{
29
+ readonly success: import("valibot").BooleanSchema<undefined>;
30
+ readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
31
+ } & {
32
+ schemas: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
33
+ /** The id a request names. */
34
+ readonly id: import("valibot").StringSchema<undefined>;
35
+ /** What this shape is for, in a sentence. */
36
+ readonly description: import("valibot").StringSchema<undefined>;
37
+ /**
38
+ * Whether the provider is asked to enforce the shape exactly (no extra keys,
39
+ * every declared field present). True for everything shipped here; a schema
40
+ * whose union or recursion a provider's strict mode cannot express is
41
+ * registered non-strict rather than silently rewritten.
42
+ */
43
+ readonly strict: import("valibot").BooleanSchema<undefined>;
44
+ /** The JSON Schema document sent to the provider. */
45
+ readonly jsonSchema: import("valibot").AnySchema;
46
+ }, undefined>, undefined>, undefined>;
47
+ }, undefined>;
48
+ export type SchemaListResponse = InferOutput<typeof SchemaListResponseSchema>;
49
+ /** One registered schema. */
50
+ export declare const SchemaResponseSchema: import("valibot").ObjectSchema<{
51
+ readonly success: import("valibot").BooleanSchema<undefined>;
52
+ readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
53
+ } & {
54
+ schema: import("valibot").OptionalSchema<import("valibot").ObjectSchema<{
55
+ /** The id a request names. */
56
+ readonly id: import("valibot").StringSchema<undefined>;
57
+ /** What this shape is for, in a sentence. */
58
+ readonly description: import("valibot").StringSchema<undefined>;
59
+ /**
60
+ * Whether the provider is asked to enforce the shape exactly (no extra keys,
61
+ * every declared field present). True for everything shipped here; a schema
62
+ * whose union or recursion a provider's strict mode cannot express is
63
+ * registered non-strict rather than silently rewritten.
64
+ */
65
+ readonly strict: import("valibot").BooleanSchema<undefined>;
66
+ /** The JSON Schema document sent to the provider. */
67
+ readonly jsonSchema: import("valibot").AnySchema;
68
+ }, undefined>, undefined>;
69
+ }, undefined>;
70
+ export type SchemaResponse = InferOutput<typeof SchemaResponseSchema>;
71
+ //# sourceMappingURL=schemaRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemaRegistry.d.ts","sourceRoot":"","sources":["../src/schemaRegistry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAiD,MAAM,SAAS,CAAC;AAE1F;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB;IACjC,8BAA8B;;IAE9B,6CAA6C;;IAE7C;;;;;OAKG;;IAEH,qDAAqD;;aAErD,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE1E,iEAAiE;AACjE,eAAO,MAAM,wBAAwB;;;;;QAlBnC,8BAA8B;;QAE9B,6CAA6C;;QAE7C;;;;;WAKG;;QAEH,qDAAqD;;;aASrD,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE9E,6BAA6B;AAC7B,eAAO,MAAM,oBAAoB;;;;;QAxB/B,8BAA8B;;QAE9B,6CAA6C;;QAE7C;;;;;WAKG;;QAEH,qDAAqD;;;aAerD,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { createSuccessResponseSchema } from "@game-infra/api-schemas-core";
2
+ import { any, array, boolean, object, optional, string } from "valibot";
3
+ /**
4
+ * The published description of one registered request schema.
5
+ *
6
+ * A caller that names a `schemaId` has to be able to write code against what
7
+ * comes back, and the only honest way to give it that is the schema itself.
8
+ * `jsonSchema` is the same document handed to the provider's structured-output
9
+ * API, not a summary of it, so a caller generating types from this endpoint and
10
+ * the model filling in the response are working from one description.
11
+ */
12
+ export const RegisteredSchemaSchema = object({
13
+ /** The id a request names. */
14
+ id: string(),
15
+ /** What this shape is for, in a sentence. */
16
+ description: string(),
17
+ /**
18
+ * Whether the provider is asked to enforce the shape exactly (no extra keys,
19
+ * every declared field present). True for everything shipped here; a schema
20
+ * whose union or recursion a provider's strict mode cannot express is
21
+ * registered non-strict rather than silently rewritten.
22
+ */
23
+ strict: boolean(),
24
+ /** The JSON Schema document sent to the provider. */
25
+ jsonSchema: any(),
26
+ });
27
+ /** Every schema this deployment will accept a `schemaId` for. */
28
+ export const SchemaListResponseSchema = createSuccessResponseSchema({
29
+ schemas: optional(array(RegisteredSchemaSchema)),
30
+ });
31
+ /** One registered schema. */
32
+ export const SchemaResponseSchema = createSuccessResponseSchema({
33
+ schema: optional(RegisteredSchemaSchema),
34
+ });
35
+ //# sourceMappingURL=schemaRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemaRegistry.js","sourceRoot":"","sources":["../src/schemaRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAoB,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE1F;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;IAC3C,8BAA8B;IAC9B,EAAE,EAAE,MAAM,EAAE;IACZ,6CAA6C;IAC7C,WAAW,EAAE,MAAM,EAAE;IACrB;;;;;OAKG;IACH,MAAM,EAAE,OAAO,EAAE;IACjB,qDAAqD;IACrD,UAAU,EAAE,GAAG,EAAE;CAClB,CAAC,CAAC;AAIH,iEAAiE;AACjE,MAAM,CAAC,MAAM,wBAAwB,GAAG,2BAA2B,CAAC;IAClE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;CACjD,CAAC,CAAC;AAGH,6BAA6B;AAC7B,MAAM,CAAC,MAAM,oBAAoB,GAAG,2BAA2B,CAAC;IAC9D,MAAM,EAAE,QAAQ,CAAC,sBAAsB,CAAC;CACzC,CAAC,CAAC"}
@@ -0,0 +1,143 @@
1
+ import { type InferOutput } from "valibot";
2
+ /**
3
+ * Whether ai-service is configured and migrated, without reading any
4
+ * configuration. Named checks rather than one boolean: a deployment missing
5
+ * `ENCRYPTION_KEY` and one missing its migrations need different fixes, and a
6
+ * bare `ready: false` names neither.
7
+ */
8
+ export declare const AiReadinessResponseSchema: import("valibot").ObjectSchema<{
9
+ readonly success: import("valibot").BooleanSchema<undefined>;
10
+ readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
11
+ } & {
12
+ checks: import("valibot").OptionalSchema<import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").BooleanSchema<undefined>, undefined>, undefined>;
13
+ failedChecks: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>, undefined>;
14
+ /**
15
+ * How many providers are enabled and hold whatever credential their kind
16
+ * needs. Reported beside the checks rather than counted as one: a freshly
17
+ * migrated deployment with nothing configured is correctly deployed, and
18
+ * saying so is different from saying it can serve a request.
19
+ */
20
+ usableProviders: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
21
+ /** How many presets a caller could name right now. */
22
+ enabledPresets: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
23
+ }, undefined>;
24
+ export type AiReadinessResponse = InferOutput<typeof AiReadinessResponseSchema>;
25
+ /** Acknowledgement of a delete. */
26
+ export declare const DeleteResponseSchema: import("valibot").ObjectSchema<{
27
+ readonly success: import("valibot").BooleanSchema<undefined>;
28
+ readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
29
+ } & {
30
+ deleted: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
31
+ }, undefined>;
32
+ export type DeleteResponse = InferOutput<typeof DeleteResponseSchema>;
33
+ /**
34
+ * One call, as the usage log recorded it.
35
+ *
36
+ * The log exists because routing is the whole product here, and a deployment
37
+ * whose subscription-first preset has been silently answering from OpenRouter
38
+ * for a fortnight has no other way to find out. It records which route answered
39
+ * and how many were tried, never a prompt or a completion: this service does
40
+ * not author the text it carries and has no business retaining it.
41
+ */
42
+ export declare const CallRecordSchema: import("valibot").ObjectSchema<{
43
+ readonly id: import("valibot").StringSchema<undefined>;
44
+ /** `text`, `object` or `stream`. */
45
+ readonly kind: import("valibot").StringSchema<undefined>;
46
+ /** The account whose token authorised the call. */
47
+ readonly userId: import("valibot").StringSchema<undefined>;
48
+ /** The preset named, when one was. */
49
+ readonly preset: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
50
+ /** The schema requested, for an object call. */
51
+ readonly schemaId: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
52
+ /** The label the caller attached, when it attached one. */
53
+ readonly callLabel: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
54
+ /** The route that answered, or the last one tried when none did. */
55
+ readonly providerId: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
56
+ readonly model: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
57
+ readonly succeeded: import("valibot").BooleanSchema<undefined>;
58
+ /** How many routes were tried, the successful one included. */
59
+ readonly attempts: import("valibot").NumberSchema<undefined>;
60
+ readonly inputTokens: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
61
+ readonly outputTokens: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
62
+ readonly latencyMs: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
63
+ /** The failure that ended the call, when it failed. */
64
+ readonly failure: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
65
+ readonly createdAt: import("valibot").StringSchema<undefined>;
66
+ }, undefined>;
67
+ export type CallRecord = InferOutput<typeof CallRecordSchema>;
68
+ /**
69
+ * How much of the log this answer covers.
70
+ *
71
+ * `account` is every ordinary caller's answer: the log names which provider
72
+ * served each call, so an unscoped read would hand any signed-in account both
73
+ * every other account's activity and the id of every provider this deployment
74
+ * has configured — the inventory the admin claim exists to withhold. `all` is
75
+ * what a caller holding that claim gets.
76
+ *
77
+ * Reported rather than inferred, because the two are the same shape and a
78
+ * reader cannot otherwise tell a quiet deployment from a narrowed view of a
79
+ * busy one.
80
+ */
81
+ export declare const CALL_LIST_SCOPES: readonly ["account", "all"];
82
+ export declare const CallListScopeSchema: import("valibot").PicklistSchema<readonly ["account", "all"], undefined>;
83
+ export type CallListScope = InferOutput<typeof CallListScopeSchema>;
84
+ /** Recent calls, newest first. */
85
+ export declare const CallListResponseSchema: import("valibot").ObjectSchema<{
86
+ readonly success: import("valibot").BooleanSchema<undefined>;
87
+ readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
88
+ } & {
89
+ /** Which calls this answer covers. */
90
+ scope: import("valibot").OptionalSchema<import("valibot").PicklistSchema<readonly ["account", "all"], undefined>, undefined>;
91
+ calls: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
92
+ readonly id: import("valibot").StringSchema<undefined>;
93
+ /** `text`, `object` or `stream`. */
94
+ readonly kind: import("valibot").StringSchema<undefined>;
95
+ /** The account whose token authorised the call. */
96
+ readonly userId: import("valibot").StringSchema<undefined>;
97
+ /** The preset named, when one was. */
98
+ readonly preset: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
99
+ /** The schema requested, for an object call. */
100
+ readonly schemaId: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
101
+ /** The label the caller attached, when it attached one. */
102
+ readonly callLabel: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
103
+ /** The route that answered, or the last one tried when none did. */
104
+ readonly providerId: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
105
+ readonly model: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
106
+ readonly succeeded: import("valibot").BooleanSchema<undefined>;
107
+ /** How many routes were tried, the successful one included. */
108
+ readonly attempts: import("valibot").NumberSchema<undefined>;
109
+ readonly inputTokens: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
110
+ readonly outputTokens: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
111
+ readonly latencyMs: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
112
+ /** The failure that ended the call, when it failed. */
113
+ readonly failure: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
114
+ readonly createdAt: import("valibot").StringSchema<undefined>;
115
+ }, undefined>, undefined>, undefined>;
116
+ /**
117
+ * Volume and tokens folded per provider over every retained call within
118
+ * {@link CallListResponseSchema} `scope` — not over the page above, which is
119
+ * only the most recent few.
120
+ */
121
+ byProvider: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
122
+ readonly providerId: import("valibot").StringSchema<undefined>;
123
+ readonly calls: import("valibot").NumberSchema<undefined>;
124
+ readonly failures: import("valibot").NumberSchema<undefined>;
125
+ readonly inputTokens: import("valibot").NumberSchema<undefined>;
126
+ readonly outputTokens: import("valibot").NumberSchema<undefined>;
127
+ }, undefined>, undefined>, undefined>;
128
+ }, undefined>;
129
+ export type CallListResponse = InferOutput<typeof CallListResponseSchema>;
130
+ /**
131
+ * How many calls to return.
132
+ *
133
+ * Query parameters arrive as strings, so the bound is applied after the
134
+ * conversion rather than to the text: `limit=abc` becomes `NaN` and is refused
135
+ * by the range check with the parameter named, which is what a caller can act
136
+ * on, where a string-shaped rule would have complained about the format of
137
+ * something it never converted.
138
+ */
139
+ export declare const CallListQuerySchema: import("valibot").ObjectSchema<{
140
+ readonly limit: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TransformAction<string, number>, import("valibot").NumberSchema<undefined>, import("valibot").IntegerAction<number, undefined>, import("valibot").MinValueAction<number, 1, undefined>, import("valibot").MaxValueAction<number, 200, undefined>]>, undefined>;
141
+ }, undefined>;
142
+ export type CallListQuery = InferOutput<typeof CallListQuerySchema>;
143
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAcjB,MAAM,SAAS,CAAC;AAEjB;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;;;;IAGpC;;;;;OAKG;;IAEH,sDAAsD;;aAEtD,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAEhF,mCAAmC;AACnC,eAAO,MAAM,oBAAoB;;;;;aAA+D,CAAC;AACjG,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEtE;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB;;IAE3B,oCAAoC;;IAEpC,mDAAmD;;IAEnD,sCAAsC;;IAEtC,gDAAgD;;IAEhD,2DAA2D;;IAE3D,oEAAoE;;;;IAIpE,+DAA+D;;;;;IAK/D,uDAAuD;;;aAGvD,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE9D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,YAAI,SAAS,EAAE,KAAK,CAAU,CAAC;AAC5D,eAAO,MAAM,mBAAmB,0EAA6B,CAAC;AAC9D,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEpE,kCAAkC;AAClC,eAAO,MAAM,sBAAsB;;;;IACjC,sCAAsC;;;;QA7CtC,oCAAoC;;QAEpC,mDAAmD;;QAEnD,sCAAsC;;QAEtC,gDAAgD;;QAEhD,2DAA2D;;QAE3D,oEAAoE;;;;QAIpE,+DAA+D;;;;;QAK/D,uDAAuD;;;;IA6BvD;;;;OAIG;;;;;;;;aAYH,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE1E;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB;;aAW9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -0,0 +1,103 @@
1
+ import { createSuccessResponseSchema } from "@game-infra/api-schemas-core";
2
+ import { array, boolean, integer, maxValue, minValue, number, object, optional, picklist, pipe, record, string, transform, } from "valibot";
3
+ /**
4
+ * Whether ai-service is configured and migrated, without reading any
5
+ * configuration. Named checks rather than one boolean: a deployment missing
6
+ * `ENCRYPTION_KEY` and one missing its migrations need different fixes, and a
7
+ * bare `ready: false` names neither.
8
+ */
9
+ export const AiReadinessResponseSchema = createSuccessResponseSchema({
10
+ checks: optional(record(string(), boolean())),
11
+ failedChecks: optional(array(string())),
12
+ /**
13
+ * How many providers are enabled and hold whatever credential their kind
14
+ * needs. Reported beside the checks rather than counted as one: a freshly
15
+ * migrated deployment with nothing configured is correctly deployed, and
16
+ * saying so is different from saying it can serve a request.
17
+ */
18
+ usableProviders: optional(number()),
19
+ /** How many presets a caller could name right now. */
20
+ enabledPresets: optional(number()),
21
+ });
22
+ /** Acknowledgement of a delete. */
23
+ export const DeleteResponseSchema = createSuccessResponseSchema({ deleted: optional(string()) });
24
+ /**
25
+ * One call, as the usage log recorded it.
26
+ *
27
+ * The log exists because routing is the whole product here, and a deployment
28
+ * whose subscription-first preset has been silently answering from OpenRouter
29
+ * for a fortnight has no other way to find out. It records which route answered
30
+ * and how many were tried, never a prompt or a completion: this service does
31
+ * not author the text it carries and has no business retaining it.
32
+ */
33
+ export const CallRecordSchema = object({
34
+ id: string(),
35
+ /** `text`, `object` or `stream`. */
36
+ kind: string(),
37
+ /** The account whose token authorised the call. */
38
+ userId: string(),
39
+ /** The preset named, when one was. */
40
+ preset: optional(string()),
41
+ /** The schema requested, for an object call. */
42
+ schemaId: optional(string()),
43
+ /** The label the caller attached, when it attached one. */
44
+ callLabel: optional(string()),
45
+ /** The route that answered, or the last one tried when none did. */
46
+ providerId: optional(string()),
47
+ model: optional(string()),
48
+ succeeded: boolean(),
49
+ /** How many routes were tried, the successful one included. */
50
+ attempts: number(),
51
+ inputTokens: optional(number()),
52
+ outputTokens: optional(number()),
53
+ latencyMs: optional(number()),
54
+ /** The failure that ended the call, when it failed. */
55
+ failure: optional(string()),
56
+ createdAt: string(),
57
+ });
58
+ /**
59
+ * How much of the log this answer covers.
60
+ *
61
+ * `account` is every ordinary caller's answer: the log names which provider
62
+ * served each call, so an unscoped read would hand any signed-in account both
63
+ * every other account's activity and the id of every provider this deployment
64
+ * has configured — the inventory the admin claim exists to withhold. `all` is
65
+ * what a caller holding that claim gets.
66
+ *
67
+ * Reported rather than inferred, because the two are the same shape and a
68
+ * reader cannot otherwise tell a quiet deployment from a narrowed view of a
69
+ * busy one.
70
+ */
71
+ export const CALL_LIST_SCOPES = ["account", "all"];
72
+ export const CallListScopeSchema = picklist(CALL_LIST_SCOPES);
73
+ /** Recent calls, newest first. */
74
+ export const CallListResponseSchema = createSuccessResponseSchema({
75
+ /** Which calls this answer covers. */
76
+ scope: optional(CallListScopeSchema),
77
+ calls: optional(array(CallRecordSchema)),
78
+ /**
79
+ * Volume and tokens folded per provider over every retained call within
80
+ * {@link CallListResponseSchema} `scope` — not over the page above, which is
81
+ * only the most recent few.
82
+ */
83
+ byProvider: optional(array(object({
84
+ providerId: string(),
85
+ calls: number(),
86
+ failures: number(),
87
+ inputTokens: number(),
88
+ outputTokens: number(),
89
+ }))),
90
+ });
91
+ /**
92
+ * How many calls to return.
93
+ *
94
+ * Query parameters arrive as strings, so the bound is applied after the
95
+ * conversion rather than to the text: `limit=abc` becomes `NaN` and is refused
96
+ * by the range check with the parameter named, which is what a caller can act
97
+ * on, where a string-shaped rule would have complained about the format of
98
+ * something it never converted.
99
+ */
100
+ export const CallListQuerySchema = object({
101
+ limit: optional(pipe(string(), transform((raw) => Number(raw)), number(), integer(), minValue(1), maxValue(200))),
102
+ });
103
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}