@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
package/dist/preset.js ADDED
@@ -0,0 +1,212 @@
1
+ import { createSuccessResponseSchema } from "@game-infra/api-schemas-core";
2
+ import { array, boolean, integer, maxLength, maxValue, minLength, minValue, number, object, optional, picklist, pipe, regex, string, } from "valibot";
3
+ import { ProviderIdSchema, ProviderTierSchema } from "./provider.js";
4
+ /**
5
+ * A preset is a stored answer to "which model, and if that one is not
6
+ * available, then what".
7
+ *
8
+ * Callers name a preset instead of a model, which is what lets a deployment
9
+ * change where its work runs without touching the caller. The preset holds two
10
+ * orderings and they answer different questions: the model list says which
11
+ * models are acceptable and in what order of preference, and the tier and
12
+ * provider preferences say how to reach whichever model is being tried. Keeping
13
+ * them apart is what makes "prefer the subscription, fall back to OpenRouter
14
+ * rather than to Cloudflare" expressible without writing out every combination.
15
+ */
16
+ /** Lowercase, dash-separated key a request names a preset by. */
17
+ export const PresetSlugSchema = pipe(string(), minLength(1), maxLength(64), regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "must be lowercase words separated by single dashes"));
18
+ /**
19
+ * One model in a preset's order of preference.
20
+ *
21
+ * The entry's position in the list is its priority: the first entry whose model
22
+ * some enabled provider can serve wins. Everything else on the entry is a
23
+ * narrowing of how that model may be reached.
24
+ */
25
+ export const PresetModelEntrySchema = object({
26
+ /** Canonical model id, matched against each provider's route table. */
27
+ model: pipe(string(), minLength(1), maxLength(160)),
28
+ /**
29
+ * Reach this model only through this provider. A pin turns off fallback for
30
+ * the entry: if the named provider is disabled, uncredentialed or does not
31
+ * serve the model, the entry contributes nothing and routing moves to the
32
+ * next model rather than quietly using a different provider. That is the
33
+ * point of pinning, so it is stated rather than treated as a hint.
34
+ */
35
+ provider: optional(ProviderIdSchema),
36
+ /** Tier order for this model only. Absent means the preset's own order. */
37
+ tierPreference: optional(array(ProviderTierSchema)),
38
+ /** Provider order for this model only. Absent means the preset's own order. */
39
+ providerPreference: optional(array(ProviderIdSchema)),
40
+ /** Sampling temperature for this model. Absent means the preset default. */
41
+ temperature: optional(pipe(number(), minValue(0), maxValue(2))),
42
+ /** Output-token cap for this model. Absent means the preset default. */
43
+ maxOutputTokens: optional(pipe(number(), integer(), minValue(1), maxValue(200_000))),
44
+ });
45
+ /**
46
+ * What a preset does when the only route left is a locked subscription.
47
+ *
48
+ * - `fall-back` — skip it and try the metered routes. The default, because a
49
+ * caller that could not supply a password still wants an answer.
50
+ * - `require` — serve this preset from a subscription or not at all. Every
51
+ * route that is not one is dropped from the plan with
52
+ * `subscription_required`, so a request carrying no password is refused with
53
+ * 428 and one whose subscription is disabled, absent or failing is refused
54
+ * rather than quietly billed. For work whose whole point is that it must not
55
+ * be billed per token, where falling back is the failure rather than the
56
+ * recovery.
57
+ */
58
+ export const LOCKED_SUBSCRIPTION_POLICIES = ["fall-back", "require"];
59
+ export const LockedSubscriptionPolicySchema = picklist(LOCKED_SUBSCRIPTION_POLICIES);
60
+ /** A stored routing preset. */
61
+ export const PresetSchema = object({
62
+ id: string(),
63
+ slug: PresetSlugSchema,
64
+ name: pipe(string(), minLength(1), maxLength(120)),
65
+ description: optional(pipe(string(), maxLength(600))),
66
+ /** Models in order of preference. A preset with none can route nothing. */
67
+ models: array(PresetModelEntrySchema),
68
+ /**
69
+ * Tier order. A preference REORDERS rather than filters: tiers left out are
70
+ * appended in the built-in order, so a preset written before a tier existed
71
+ * keeps working and gains the new tier as a last resort rather than being
72
+ * silently unable to reach it.
73
+ */
74
+ tierPreference: array(ProviderTierSchema),
75
+ /**
76
+ * Provider order inside a tier, which is where "OpenRouter before Cloudflare"
77
+ * is expressed. Providers not named come after the named ones, ordered by
78
+ * their own id so the result is stable rather than dependent on insertion
79
+ * order in the database.
80
+ */
81
+ providerPreference: array(ProviderIdSchema),
82
+ lockedSubscriptionPolicy: LockedSubscriptionPolicySchema,
83
+ /** Sampling temperature applied to any entry that does not set its own. */
84
+ temperature: optional(pipe(number(), minValue(0), maxValue(2))),
85
+ /** Output-token cap applied to any entry that does not set its own. */
86
+ maxOutputTokens: optional(pipe(number(), integer(), minValue(1), maxValue(200_000))),
87
+ /**
88
+ * How many routes a single request may try before giving up. Bounds the tail
89
+ * latency of a request whose preset lists many models across many gateways:
90
+ * without it, one request against a broadly-configured deployment can spend
91
+ * a minute failing through routes nobody is waiting for any more.
92
+ */
93
+ maxAttempts: pipe(number(), integer(), minValue(1), maxValue(10)),
94
+ /** Whether callers may name this preset. */
95
+ enabled: boolean(),
96
+ createdAt: string(),
97
+ updatedAt: string(),
98
+ });
99
+ /** Fields accepted when creating a preset. */
100
+ export const CreatePresetRequestSchema = object({
101
+ slug: PresetSlugSchema,
102
+ name: pipe(string(), minLength(1), maxLength(120)),
103
+ description: optional(pipe(string(), maxLength(600))),
104
+ models: array(PresetModelEntrySchema),
105
+ tierPreference: optional(array(ProviderTierSchema)),
106
+ providerPreference: optional(array(ProviderIdSchema)),
107
+ lockedSubscriptionPolicy: optional(LockedSubscriptionPolicySchema),
108
+ temperature: optional(pipe(number(), minValue(0), maxValue(2))),
109
+ maxOutputTokens: optional(pipe(number(), integer(), minValue(1), maxValue(200_000))),
110
+ maxAttempts: optional(pipe(number(), integer(), minValue(1), maxValue(10))),
111
+ enabled: optional(boolean()),
112
+ });
113
+ /** Fields accepted when updating a preset. Absent means unchanged. */
114
+ export const UpdatePresetRequestSchema = object({
115
+ name: optional(pipe(string(), minLength(1), maxLength(120))),
116
+ description: optional(pipe(string(), maxLength(600))),
117
+ models: optional(array(PresetModelEntrySchema)),
118
+ tierPreference: optional(array(ProviderTierSchema)),
119
+ providerPreference: optional(array(ProviderIdSchema)),
120
+ lockedSubscriptionPolicy: optional(LockedSubscriptionPolicySchema),
121
+ temperature: optional(pipe(number(), minValue(0), maxValue(2))),
122
+ maxOutputTokens: optional(pipe(number(), integer(), minValue(1), maxValue(200_000))),
123
+ maxAttempts: optional(pipe(number(), integer(), minValue(1), maxValue(10))),
124
+ enabled: optional(boolean()),
125
+ });
126
+ /**
127
+ * One route a request could take, as the planner ordered them.
128
+ *
129
+ * This is the same list the executor walks, exposed so a preset can be checked
130
+ * before anything is spent on it. A preset that reads correctly and routes to
131
+ * nothing is the failure mode worth catching here rather than in production,
132
+ * and it is invisible from the stored preset alone: it depends on which
133
+ * providers are enabled and what they were told they serve.
134
+ */
135
+ export const RouteCandidateSchema = object({
136
+ /** Position in the plan, zero-based. */
137
+ order: pipe(number(), integer(), minValue(0)),
138
+ /** Canonical model this route serves. */
139
+ model: string(),
140
+ /** The id the provider serves it under. */
141
+ providerModelId: string(),
142
+ providerId: string(),
143
+ providerName: string(),
144
+ tier: ProviderTierSchema,
145
+ /**
146
+ * For a subscription route, whether the request as it stands could unlock it.
147
+ * A plan built without a password reports `false` here, which is what tells
148
+ * an operator that their subscription-first preset is quietly running on API
149
+ * keys.
150
+ */
151
+ unlockable: optional(boolean()),
152
+ });
153
+ /**
154
+ * Why a configured route was left out of the plan.
155
+ *
156
+ * A dry run that answered only with the routes it kept would be no help with
157
+ * the question people actually ask it, which is why the subscription they
158
+ * configured is not being used. Each reason names one fixable thing.
159
+ */
160
+ export const ROUTE_EXCLUSION_REASONS = [
161
+ /** No enabled provider maps this canonical model at all. */
162
+ "model_not_served",
163
+ /** The provider exists but is switched off. */
164
+ "provider_disabled",
165
+ /** The provider needs a key and none is stored. */
166
+ "credential_missing",
167
+ /** A subscription route with no password on the request to open it. */
168
+ "subscription_locked",
169
+ /** A subscription owned by somebody other than the caller. */
170
+ "subscription_not_owned",
171
+ /**
172
+ * The route is not a subscription and the preset's `lockedSubscriptionPolicy`
173
+ * is `require`, so only subscription routes are eligible.
174
+ */
175
+ "subscription_required",
176
+ /** The entry pins a provider that does not exist or does not serve the model. */
177
+ "pinned_provider_unavailable",
178
+ /** The request carries images and this route is declared text-only. */
179
+ "model_no_image_input",
180
+ /** The request carries images and nobody has declared whether this route reads them. */
181
+ "unknown_model_image_input",
182
+ /** `/generate/object` against a route declared to have no structured-output path. */
183
+ "structured_output_unsupported",
184
+ /** The route was valid but fell outside the preset's attempt budget. */
185
+ "attempt_budget_exhausted",
186
+ ];
187
+ export const RouteExclusionReasonSchema = picklist(ROUTE_EXCLUSION_REASONS);
188
+ /** A route that was considered and dropped, with the reason it was dropped. */
189
+ export const RouteExclusionSchema = object({
190
+ model: string(),
191
+ providerId: optional(string()),
192
+ tier: optional(ProviderTierSchema),
193
+ reason: RouteExclusionReasonSchema,
194
+ /** Operator-facing wording for {@link reason}, naming this specific route. */
195
+ detail: string(),
196
+ });
197
+ /** The plan a preset produces against the current configuration. */
198
+ export const RoutePlanResponseSchema = createSuccessResponseSchema({
199
+ preset: optional(string()),
200
+ candidates: optional(array(RouteCandidateSchema)),
201
+ /** Routes considered and dropped. Empty is a real answer, not a missing one. */
202
+ excluded: optional(array(RouteExclusionSchema)),
203
+ });
204
+ /** One preset. */
205
+ export const PresetResponseSchema = createSuccessResponseSchema({
206
+ preset: optional(PresetSchema),
207
+ });
208
+ /** Every stored preset. */
209
+ export const PresetListResponseSchema = createSuccessResponseSchema({
210
+ presets: optional(array(PresetSchema)),
211
+ });
212
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.js","sourceRoot":"","sources":["../src/preset.ts"],"names":[],"mappings":"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"}