@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.
- package/LICENSE +21 -0
- package/README.md +149 -0
- package/dist/catalog.d.ts +137 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +209 -0
- package/dist/catalog.js.map +1 -0
- package/dist/contracts.d.ts +1073 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +243 -0
- package/dist/contracts.js.map +1 -0
- package/dist/featuredModels.d.ts +95 -0
- package/dist/featuredModels.d.ts.map +1 -0
- package/dist/featuredModels.js +189 -0
- package/dist/featuredModels.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/inference.d.ts +323 -0
- package/dist/inference.d.ts.map +1 -0
- package/dist/inference.js +162 -0
- package/dist/inference.js.map +1 -0
- package/dist/preference.d.ts +49 -0
- package/dist/preference.d.ts.map +1 -0
- package/dist/preference.js +74 -0
- package/dist/preference.js.map +1 -0
- package/dist/preset.d.ts +422 -0
- package/dist/preset.d.ts.map +1 -0
- package/dist/preset.js +212 -0
- package/dist/preset.js.map +1 -0
- package/dist/provider.d.ts +487 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +224 -0
- package/dist/provider.js.map +1 -0
- package/dist/schemaRegistry.d.ts +71 -0
- package/dist/schemaRegistry.d.ts.map +1 -0
- package/dist/schemaRegistry.js +35 -0
- package/dist/schemaRegistry.js.map +1 -0
- package/dist/service.d.ts +143 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +103 -0
- package/dist/service.js.map +1 -0
- package/dist/subscription.d.ts +275 -0
- package/dist/subscription.d.ts.map +1 -0
- package/dist/subscription.js +198 -0
- package/dist/subscription.js.map +1 -0
- package/package.json +50 -0
package/dist/provider.js
ADDED
|
@@ -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"}
|
package/dist/service.js
ADDED
|
@@ -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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"}
|