@kaana.ai/contracts 0.0.0-stage → 4.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 (79) hide show
  1. package/LICENSE +673 -0
  2. package/NOTICE +21 -0
  3. package/dist/index.d.ts +29 -0
  4. package/dist/index.js +29 -0
  5. package/dist/internal/attribution.d.ts +116 -0
  6. package/dist/internal/attribution.js +82 -0
  7. package/dist/internal/canonical.d.ts +31 -0
  8. package/dist/internal/canonical.js +57 -0
  9. package/dist/internal/catalogue.d.ts +1030 -0
  10. package/dist/internal/catalogue.js +349 -0
  11. package/dist/internal/credentialControl.d.ts +329 -0
  12. package/dist/internal/credentialControl.js +256 -0
  13. package/dist/internal/decisions.d.ts +245 -0
  14. package/dist/internal/decisions.js +69 -0
  15. package/dist/internal/economics.d.ts +27 -0
  16. package/dist/internal/economics.js +26 -0
  17. package/dist/internal/embeddings.d.ts +164 -0
  18. package/dist/internal/embeddings.js +59 -0
  19. package/dist/internal/errors.d.ts +185 -0
  20. package/dist/internal/errors.js +211 -0
  21. package/dist/internal/grant.d.ts +696 -0
  22. package/dist/internal/grant.js +437 -0
  23. package/dist/internal/identifiers.d.ts +63 -0
  24. package/dist/internal/identifiers.js +65 -0
  25. package/dist/internal/privateAutoExecution.d.ts +158 -0
  26. package/dist/internal/privateAutoExecution.js +188 -0
  27. package/dist/internal/realtime.d.ts +1005 -0
  28. package/dist/internal/realtime.js +187 -0
  29. package/dist/internal/request.d.ts +1079 -0
  30. package/dist/internal/request.js +404 -0
  31. package/dist/internal/routing.d.ts +90 -0
  32. package/dist/internal/routing.js +139 -0
  33. package/dist/internal/scopedExecution.d.ts +74 -0
  34. package/dist/internal/scopedExecution.js +61 -0
  35. package/dist/internal/settlement.d.ts +205 -0
  36. package/dist/internal/settlement.js +71 -0
  37. package/dist/internal/streamEvents.d.ts +422 -0
  38. package/dist/internal/streamEvents.js +171 -0
  39. package/dist/internal/usage.d.ts +127 -0
  40. package/dist/internal/usage.js +109 -0
  41. package/dist/internal.d.ts +30 -0
  42. package/dist/internal.js +30 -0
  43. package/dist/public/audio.d.ts +347 -0
  44. package/dist/public/audio.js +236 -0
  45. package/dist/public/audioFormats.d.ts +64 -0
  46. package/dist/public/audioFormats.js +60 -0
  47. package/dist/public/catalogue.d.ts +914 -0
  48. package/dist/public/catalogue.js +516 -0
  49. package/dist/public/chatCompletions.d.ts +381 -0
  50. package/dist/public/chatCompletions.js +321 -0
  51. package/dist/public/decisions.d.ts +182 -0
  52. package/dist/public/decisions.js +257 -0
  53. package/dist/public/embeddings.d.ts +34 -0
  54. package/dist/public/embeddings.js +66 -0
  55. package/dist/public/errors.d.ts +195 -0
  56. package/dist/public/errors.js +274 -0
  57. package/dist/public/generations.d.ts +330 -0
  58. package/dist/public/generations.js +121 -0
  59. package/dist/public/identifiers.d.ts +139 -0
  60. package/dist/public/identifiers.js +160 -0
  61. package/dist/public/images.d.ts +36 -0
  62. package/dist/public/images.js +36 -0
  63. package/dist/public/messages.d.ts +297 -0
  64. package/dist/public/messages.js +251 -0
  65. package/dist/public/money.d.ts +308 -0
  66. package/dist/public/money.js +237 -0
  67. package/dist/public/policy.d.ts +19 -0
  68. package/dist/public/policy.js +20 -0
  69. package/dist/public/realtime.d.ts +2006 -0
  70. package/dist/public/realtime.js +797 -0
  71. package/dist/public/responses.d.ts +253 -0
  72. package/dist/public/responses.js +95 -0
  73. package/dist/public/streamEvents.d.ts +372 -0
  74. package/dist/public/streamEvents.js +157 -0
  75. package/dist/public/version.d.ts +177 -0
  76. package/dist/public/version.js +177 -0
  77. package/openapi.json +6967 -0
  78. package/package.json +44 -4
  79. package/README.md +0 -3
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Money, prices and usage units.
3
+ *
4
+ * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/money.ts`) by Kaana ADR 0002.
5
+ * `priceSnapshotSchema` comes from `priceVersion.ts`; the price VERSION record
6
+ * itself stays in `@oxy.so/contracts`, because Oxy owns the price lists.
7
+ */
8
+ import { z } from 'zod';
9
+ /** ISO 4217 alpha-3 currency code, e.g. `USD`. */
10
+ export const currencyCodeSchema = z
11
+ .string()
12
+ .regex(/^[A-Z]{3}$/, 'currency must be an ISO 4217 alpha-3 code');
13
+ /**
14
+ * The declared fractional scale of every amount and price in this contract, and
15
+ * of the `NUMERIC` columns the ledger stores them in.
16
+ *
17
+ * Twelve digits is sub-minor-unit precision by a wide margin: at $3 per million
18
+ * input tokens, one token costs `0.000003000000`, which this scale represents
19
+ * exactly. Amounts are compared and summed NUMERICALLY, never as text — `3.0`
20
+ * and `3.000000000000` are one amount written two ways.
21
+ */
22
+ export const INFERENCE_MONEY_SCALE = 12;
23
+ /**
24
+ * An exact non-negative decimal, carried as a STRING so no parse step can turn
25
+ * it into a float on the way past. Up to 18 integer digits and
26
+ * {@link INFERENCE_MONEY_SCALE} fractional digits.
27
+ *
28
+ * Non-negative: direction is carried by the SHAPE — a receipt debits, a refund
29
+ * credits — so a stray sign can never silently invert an entry.
30
+ *
31
+ * No exponent form: `1e-6` and `0.000001` are the same number, but only one of
32
+ * them survives a naive string comparison, a cache key or a log grep intact.
33
+ *
34
+ * Branded, so a bare `string` is not assignable and an amount cannot arrive
35
+ * from string concatenation that was never checked. Producers construct one
36
+ * with `exactDecimalSchema.parse(value)`.
37
+ */
38
+ export const exactDecimalSchema = z
39
+ .string()
40
+ .regex(/^(?:0|[1-9][0-9]{0,17})(?:\.[0-9]{1,12})?$/, 'must be an exact non-negative decimal string without an exponent')
41
+ .brand();
42
+ /**
43
+ * An amount of money: the exact decimal plus the currency it is in.
44
+ *
45
+ * `.strict()` so a payload carrying a convenience float beside the exact value
46
+ * (`{ amount: '18.06', amountFloat: 18.06 }`) is REJECTED rather than stripped.
47
+ * A stripped float is the more dangerous outcome: it disappears silently here
48
+ * and survives in the producer, where it is the value somebody eventually
49
+ * displays.
50
+ */
51
+ export const moneySchema = z
52
+ .object({
53
+ amount: exactDecimalSchema,
54
+ currency: currencyCodeSchema,
55
+ })
56
+ .strict();
57
+ /**
58
+ * The closed set of units inference is metered in.
59
+ *
60
+ * **The units PARTITION a request: every unit counts material no other unit
61
+ * counts.** `cached_input_tokens` is not part of `input_tokens`, and
62
+ * `reasoning_tokens` is not part of `output_tokens` — they are siblings, not
63
+ * subsets. A request whose 10 000-token prompt was served 9 000 tokens from
64
+ * cache is reported as `input_tokens: 1000` beside `cached_input_tokens: 9000`,
65
+ * never as `input_tokens: 10000` beside it.
66
+ *
67
+ * That belongs to the definition rather than to a convention somewhere else,
68
+ * because settlement applies a price to EVERY reported unit and sums them
69
+ * (`inferenceLedger.service.ts`'s `computeCharge`). Under the partition rule
70
+ * that sum IS the request's cost, and a cached token can carry its own — lower
71
+ * — price. Under the nested reading the same sum charges the cached and
72
+ * reasoning tokens twice: once inside their parent and once on their own line.
73
+ * It fails silently, because every total still looks plausible and the receipt
74
+ * is still internally consistent, and on a reasoning model the reasoning tokens
75
+ * can dominate the completion, so the error is not marginal.
76
+ *
77
+ * **Every OpenAI-compatible provider reports the other way round**:
78
+ * `prompt_tokens` INCLUDES `prompt_tokens_details.cached_tokens`, and
79
+ * `completion_tokens` INCLUDES `completion_tokens_details.reasoning_tokens`.
80
+ * Normalising is the data plane's job and it is subtraction:
81
+ *
82
+ * ```text
83
+ * input_tokens = prompt_tokens - prompt_tokens_details.cached_tokens
84
+ * output_tokens = completion_tokens - completion_tokens_details.reasoning_tokens
85
+ * ```
86
+ *
87
+ * **Audio tokens are siblings too** (added in contract set 3.2.0). A model that
88
+ * consumes or produces audio AS TOKENS — OpenAI's audio chat and Realtime
89
+ * models — reports them inside the same totals, and they are priced several
90
+ * times higher than text tokens, so folding them into `input_tokens` would
91
+ * under-charge by exactly the audio. They are subtracted out the same way:
92
+ *
93
+ * ```text
94
+ * cached_audio_input_tokens = prompt_tokens_details.cached_tokens_details.audio_tokens
95
+ * audio_input_tokens = prompt_tokens_details.audio_tokens - cached_audio_input_tokens
96
+ * input_tokens = prompt_tokens - (text AND audio cached) - audio_input_tokens
97
+ * audio_output_tokens = completion_tokens_details.audio_tokens
98
+ * output_tokens = completion_tokens - reasoning_tokens - audio_output_tokens
99
+ * ```
100
+ *
101
+ * `audio_input_milliseconds` and `audio_output_milliseconds` remain the units
102
+ * for audio metered by DURATION (file transcription, speech synthesis). A
103
+ * report carries one reading of a given audio, never both: the same audio
104
+ * reported as tokens and as milliseconds is the double charge this rule exists
105
+ * to prevent.
106
+ *
107
+ * **`session_milliseconds` is session wall-clock time** (added in contract set
108
+ * 3.3.0): wall-clock milliseconds a realtime session was open with the upstream
109
+ * provider; reported only by a provider that bills session time, and never
110
+ * together with a per-audio reading of the same span. xAI's Voice Agent API
111
+ * bills a session using server-side voice activity detection for its whole
112
+ * duration, speech or silence, which is neither audio sent nor audio received:
113
+ * reporting that clock as `audio_input_milliseconds` would misdescribe the
114
+ * charge, and reporting both would bill the same span twice. It is measured by
115
+ * the data plane from the upstream session's open to its close, never
116
+ * estimated from the audio, and a provider billed by the audio it carries (or
117
+ * by tokens) never reports it.
118
+ *
119
+ * **`input_transcription_milliseconds` is a second model's reading** (added in
120
+ * contract set 4.1.0): milliseconds of a realtime session's input audio that
121
+ * the deployment's own TRANSCRIPTION model transcribed, when the provider bills
122
+ * that model apart from the session model. OpenAI runs input transcription on
123
+ * a separate ASR model "billed according to the ASR model's pricing rather
124
+ * than the realtime model's", so the session model's `audio_input_tokens` and
125
+ * this unit are two charges for two models, each read once — which is why the
126
+ * partition rule holds: no other unit counts the transcription model's work.
127
+ * Reporting the ASR duration as `audio_input_milliseconds` beside the session
128
+ * model's audio tokens would be the "same audio as tokens and as milliseconds"
129
+ * this rule forbids, and folding it into the tokens would price it at the
130
+ * wrong model's rate. A provider whose session price already includes the
131
+ * transcription (xAI's Voice Agent) never reports it. A transcription model
132
+ * billed by TOKENS is a charge this unit does not express: the data plane
133
+ * declares only duration-billed transcription models and ends a session whose
134
+ * provider reports tokens for one, rather than approximate the charge.
135
+ *
136
+ * No refinement in this package can enforce it, and saying so is part of the
137
+ * rule: a nested report and a disjoint one are the same four non-negative
138
+ * integers, so no predicate over a single report can tell them apart. The two
139
+ * structural guards that DO exist — refining `cached <= input` and
140
+ * `reasoning <= output`, or deriving the parents instead of reporting them —
141
+ * both encode the nested reading, which is the one this rule rejects. What IS
142
+ * enforceable is the arithmetic that depends on the rule, and that is where the
143
+ * enforcement lives — `inferenceLedger.service.test.ts` prices a report in
144
+ * which cached and reasoning tokens are both non-zero and asserts the exact
145
+ * total, which the nested reading cannot produce.
146
+ *
147
+ * Where the public surface has to speak a nested dialect, the sum is put back
148
+ * at the boundary rather than the internal reading being bent to it
149
+ * (`routes/inferenceEdge.ts` renders `prompt_tokens` as
150
+ * `input_tokens + cached_input_tokens`).
151
+ *
152
+ * Time is carried in integer MILLISECONDS rather than seconds so that no unit
153
+ * quantity is ever fractional: a 12.5-second transcription is `12500`, exactly,
154
+ * and the "units are integers" rule holds for every modality instead of holding
155
+ * for tokens and being quietly broken by audio.
156
+ */
157
+ export const USAGE_UNITS = [
158
+ 'input_tokens',
159
+ 'cached_input_tokens',
160
+ 'output_tokens',
161
+ 'reasoning_tokens',
162
+ 'requests',
163
+ 'images',
164
+ 'audio_input_milliseconds',
165
+ 'audio_output_milliseconds',
166
+ 'video_milliseconds',
167
+ 'characters',
168
+ 'embeddings',
169
+ 'audio_input_tokens',
170
+ 'cached_audio_input_tokens',
171
+ 'audio_output_tokens',
172
+ 'session_milliseconds',
173
+ 'input_transcription_milliseconds',
174
+ ];
175
+ export const usageUnitSchema = z.enum(USAGE_UNITS);
176
+ /**
177
+ * A metered quantity of ONE unit. Never money — a quantity carries no price and
178
+ * no currency, so a consumer cannot mistake a token count for an amount owed.
179
+ */
180
+ export const usageQuantitySchema = z
181
+ .object({
182
+ unit: usageUnitSchema,
183
+ quantity: z.number().int().nonnegative().safe(),
184
+ })
185
+ .strict();
186
+ /**
187
+ * Where a metered quantity came from.
188
+ *
189
+ * Kept explicit because the three are not interchangeable when a charge is
190
+ * disputed: `provider_reported` is the upstream's own count, `oxy_measured` is
191
+ * counted by the platform (streamed bytes, wall-clock milliseconds), and
192
+ * `estimated` is a reconstruction used when a provider returned no usage at
193
+ * all. An estimate that is indistinguishable from a reported number is an
194
+ * estimate nobody can later reconcile or refund against.
195
+ */
196
+ export const USAGE_SOURCES = ['provider_reported', 'oxy_measured', 'estimated'];
197
+ export const usageSourceSchema = z.enum(USAGE_SOURCES);
198
+ /**
199
+ * A price for one unit, as `amount` per `per` units — `per` because a price
200
+ * quoted per single token would need more fractional digits than it is worth
201
+ * ("$3.00 per 1000000 input_tokens" is how every provider quotes it, and how
202
+ * every customer reads it).
203
+ */
204
+ export const unitPriceSchema = z
205
+ .object({
206
+ unit: usageUnitSchema,
207
+ amount: exactDecimalSchema,
208
+ per: z.number().int().positive().safe(),
209
+ currency: currencyCodeSchema,
210
+ })
211
+ .strict();
212
+ /**
213
+ * The price snapshot a settled receipt keeps.
214
+ *
215
+ * The unit prices are COPIED onto the receipt, not just referenced, so a receipt
216
+ * remains readable even if the price version record is later archived, and so
217
+ * that a mistake in the copy is visible as a disagreement with the version it
218
+ * names rather than silently invisible.
219
+ */
220
+ export const priceSnapshotSchema = z
221
+ .object({
222
+ priceVersionId: z.string().min(1).max(128),
223
+ currency: currencyCodeSchema,
224
+ unitPrices: z.array(unitPriceSchema).min(1),
225
+ })
226
+ .strict();
227
+ /**
228
+ * What a request consumed, as a public response reports it: one quantity per
229
+ * unit, each unit at most once, the units partitioning the request (see
230
+ * {@link USAGE_UNITS}). New in contract set 4.0.0.
231
+ */
232
+ export const usageSchema = z.array(usageQuantitySchema).superRefine((units, ctx) => {
233
+ const names = units.map((quantity) => quantity.unit);
234
+ if (new Set(names).size !== names.length) {
235
+ ctx.addIssue({ code: 'custom', message: 'each unit is reported once, as a total' });
236
+ }
237
+ });
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The routing-policy reference a response and a receipt record.
3
+ *
4
+ * The policy itself is a Console resource and stays in `@oxy.so/contracts`; what
5
+ * a client reads back is only which of its own policy revisions served it.
6
+ *
7
+ * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/routingPolicy.ts`) by Kaana ADR 0002.
8
+ */
9
+ import { z } from 'zod';
10
+ /**
11
+ * The reference a request records: which policy, at which of the customer's own
12
+ * revisions. Embedded in the request envelope and in the settled receipt, so a
13
+ * charge can be explained against the exact configuration that produced it.
14
+ */
15
+ export declare const routingPolicyReferenceSchema: z.ZodObject<{
16
+ routingPolicyId: z.ZodString;
17
+ policyVersion: z.ZodNumber;
18
+ }, z.core.$strict>;
19
+ export type RoutingPolicyReference = z.infer<typeof routingPolicyReferenceSchema>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The routing-policy reference a response and a receipt record.
3
+ *
4
+ * The policy itself is a Console resource and stays in `@oxy.so/contracts`; what
5
+ * a client reads back is only which of its own policy revisions served it.
6
+ *
7
+ * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/routingPolicy.ts`) by Kaana ADR 0002.
8
+ */
9
+ import { z } from 'zod';
10
+ /**
11
+ * The reference a request records: which policy, at which of the customer's own
12
+ * revisions. Embedded in the request envelope and in the settled receipt, so a
13
+ * charge can be explained against the exact configuration that produced it.
14
+ */
15
+ export const routingPolicyReferenceSchema = z
16
+ .object({
17
+ routingPolicyId: z.string().min(1).max(128),
18
+ policyVersion: z.number().int().positive().safe(),
19
+ })
20
+ .strict();