@kaana.ai/contracts 0.0.0-stage → 4.4.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 +1059 -0
  10. package/dist/internal/catalogue.js +389 -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 +699 -0
  22. package/dist/internal/grant.js +445 -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 +184 -0
  76. package/dist/public/version.js +184 -0
  77. package/openapi.json +6967 -0
  78. package/package.json +44 -4
  79. package/README.md +0 -3
package/NOTICE ADDED
@@ -0,0 +1,21 @@
1
+ ============================================================================
2
+ NOTICE
3
+ @kaana.ai/contracts
4
+ Copyright (c) 2026-present The Oxy Collective, Inc.
5
+ ============================================================================
6
+
7
+ This product is licensed under the Breathe License 1.0, license identifier
8
+ LicenseRef-Breathe-1.0. See the LICENSE file in this directory. Commercial
9
+ terms are available at
10
+ https://github.com/OxyHQ/.github/blob/main/LICENSE-COMMERCIAL.md
11
+
12
+ Attribution under Section 3.1 of the Breathe License is required of
13
+ everyone, including paying commercial licensees, and cannot be waived.
14
+
15
+ ----------------------------------------------------------------------------
16
+ THIRD PARTY COMPONENTS
17
+ ----------------------------------------------------------------------------
18
+
19
+ This package contains no third party source. Its dependencies are resolved
20
+ and installed by the package manager and remain governed by their own
21
+ licenses.
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `@kaana.ai/contracts` — the public contract of `https://kaana.ai/v1`.
3
+ *
4
+ * Every request and response of the public API, its stream events, the public
5
+ * error vocabulary, the catalogue with prices, power levels, audio
6
+ * capabilities and generation records, as Zod schemas with their inferred
7
+ * types. The shapes Oxy and Kaana exchange privately live under
8
+ * `@kaana.ai/contracts/internal` and are not part of the public API.
9
+ *
10
+ * Accounts, applications, `oxy_sk_…` keys, limits and billing are managed in
11
+ * Oxy Console (`https://console.oxy.so`), never here.
12
+ */
13
+ export * from './public/audio.js';
14
+ export * from './public/audioFormats.js';
15
+ export * from './public/catalogue.js';
16
+ export * from './public/chatCompletions.js';
17
+ export * from './public/decisions.js';
18
+ export * from './public/embeddings.js';
19
+ export * from './public/errors.js';
20
+ export * from './public/generations.js';
21
+ export * from './public/identifiers.js';
22
+ export * from './public/images.js';
23
+ export * from './public/messages.js';
24
+ export * from './public/money.js';
25
+ export * from './public/policy.js';
26
+ export * from './public/realtime.js';
27
+ export * from './public/responses.js';
28
+ export * from './public/streamEvents.js';
29
+ export * from './public/version.js';
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `@kaana.ai/contracts` — the public contract of `https://kaana.ai/v1`.
3
+ *
4
+ * Every request and response of the public API, its stream events, the public
5
+ * error vocabulary, the catalogue with prices, power levels, audio
6
+ * capabilities and generation records, as Zod schemas with their inferred
7
+ * types. The shapes Oxy and Kaana exchange privately live under
8
+ * `@kaana.ai/contracts/internal` and are not part of the public API.
9
+ *
10
+ * Accounts, applications, `oxy_sk_…` keys, limits and billing are managed in
11
+ * Oxy Console (`https://console.oxy.so`), never here.
12
+ */
13
+ export * from './public/audio.js';
14
+ export * from './public/audioFormats.js';
15
+ export * from './public/catalogue.js';
16
+ export * from './public/chatCompletions.js';
17
+ export * from './public/decisions.js';
18
+ export * from './public/embeddings.js';
19
+ export * from './public/errors.js';
20
+ export * from './public/generations.js';
21
+ export * from './public/identifiers.js';
22
+ export * from './public/images.js';
23
+ export * from './public/messages.js';
24
+ export * from './public/money.js';
25
+ export * from './public/policy.js';
26
+ export * from './public/realtime.js';
27
+ export * from './public/responses.js';
28
+ export * from './public/streamEvents.js';
29
+ export * from './public/version.js';
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Canonical attribution carried by the signed envelope.
3
+ *
4
+ * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/attribution.ts`) by Kaana ADR 0002.
5
+ */
6
+ import { z } from 'zod';
7
+ /**
8
+ * The inference capability scopes the data plane needs to know about.
9
+ *
10
+ * A credential may carry many other Oxy scopes; only these cross the boundary,
11
+ * because the data plane's authorization questions are exactly "may this caller
12
+ * invoke", "may it read the catalogue", "may it read usage", "may it read or
13
+ * write routing", "may it read or write provider connections". Everything else
14
+ * is the control plane's business and is not the data plane's to hold.
15
+ */
16
+ export declare const INFERENCE_SCOPES: readonly ["inference:invoke", "inference:models:read", "inference:usage:read", "inference:routing:read", "inference:routing:write", "inference:providers:read", "inference:providers:write"];
17
+ export declare const inferenceScopeSchema: z.ZodEnum<{
18
+ "inference:invoke": "inference:invoke";
19
+ "inference:models:read": "inference:models:read";
20
+ "inference:usage:read": "inference:usage:read";
21
+ "inference:routing:read": "inference:routing:read";
22
+ "inference:routing:write": "inference:routing:write";
23
+ "inference:providers:read": "inference:providers:read";
24
+ "inference:providers:write": "inference:providers:write";
25
+ }>;
26
+ /**
27
+ * The financially responsible principal, and the ONLY identity a charge may be
28
+ * booked against.
29
+ *
30
+ * It is its own type — not a field on a larger principal object — precisely so
31
+ * that a function taking "who pays" cannot be handed a user, a session, a
32
+ * device or an application. It cannot be constructed from a delegated user id:
33
+ * the brands differ, and this object accepts no other key.
34
+ */
35
+ export declare const billingPrincipalSchema: z.ZodObject<{
36
+ accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
37
+ }, z.core.$strict>;
38
+ /**
39
+ * Who authenticated, as resolved by the Oxy edge before a request is forwarded.
40
+ *
41
+ * Mirrors what a verified Oxy service token carries (`appId`, `credentialId`,
42
+ * `ownerAccountId`, `environment`, effective scopes) so that the two
43
+ * authentication paths — a machine API key and a first-party service token —
44
+ * produce one shape downstream. The data plane authorizes against this
45
+ * envelope; it does not re-derive access from its own database, because it has
46
+ * no account graph to re-derive it from.
47
+ */
48
+ export declare const authenticatedPrincipalSchema: z.ZodObject<{
49
+ billing: z.ZodObject<{
50
+ accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
51
+ }, z.core.$strict>;
52
+ applicationId: z.ZodString;
53
+ credentialId: z.ZodString;
54
+ environment: z.ZodEnum<{
55
+ development: "development";
56
+ staging: "staging";
57
+ production: "production";
58
+ }>;
59
+ inferenceScopes: z.ZodArray<z.ZodEnum<{
60
+ "inference:invoke": "inference:invoke";
61
+ "inference:models:read": "inference:models:read";
62
+ "inference:usage:read": "inference:usage:read";
63
+ "inference:routing:read": "inference:routing:read";
64
+ "inference:routing:write": "inference:routing:write";
65
+ "inference:providers:read": "inference:providers:read";
66
+ "inference:providers:write": "inference:providers:write";
67
+ }>>;
68
+ }, z.core.$strip>;
69
+ /**
70
+ * The attribution block carried by every request, receipt and ledger record.
71
+ *
72
+ * `userId` is the OPTIONAL delegated end user — Alia's `X-Oxy-User-Id`. It is
73
+ * attribution only: it never changes which account is charged, never grants
74
+ * access, and lives outside {@link billingPrincipalSchema} so that no code path
75
+ * can read it as the payer.
76
+ *
77
+ * `requestId` is generated by the OXY EDGE, on admission and before
78
+ * authentication completes, and is always present (ADR 0007). Not by the data
79
+ * plane: a data plane that minted the correlation key could not correlate a
80
+ * request it never received, and the requests rejected at the edge are exactly
81
+ * the ones an operator most needs to find.
82
+ *
83
+ * `generationId` is present once a generation exists, which is why it is
84
+ * optional on a request and expected on a receipt. That one IS the data plane's,
85
+ * because only the data plane knows how many outputs a request produced.
86
+ */
87
+ export declare const inferenceAttributionSchema: z.ZodObject<{
88
+ principal: z.ZodObject<{
89
+ billing: z.ZodObject<{
90
+ accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
91
+ }, z.core.$strict>;
92
+ applicationId: z.ZodString;
93
+ credentialId: z.ZodString;
94
+ environment: z.ZodEnum<{
95
+ development: "development";
96
+ staging: "staging";
97
+ production: "production";
98
+ }>;
99
+ inferenceScopes: z.ZodArray<z.ZodEnum<{
100
+ "inference:invoke": "inference:invoke";
101
+ "inference:models:read": "inference:models:read";
102
+ "inference:usage:read": "inference:usage:read";
103
+ "inference:routing:read": "inference:routing:read";
104
+ "inference:routing:write": "inference:routing:write";
105
+ "inference:providers:read": "inference:providers:read";
106
+ "inference:providers:write": "inference:providers:write";
107
+ }>>;
108
+ }, z.core.$strip>;
109
+ userId: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "DelegatedUserId", "out">>;
110
+ requestId: z.ZodString;
111
+ generationId: z.ZodOptional<z.ZodString>;
112
+ }, z.core.$strip>;
113
+ export type InferenceScope = z.infer<typeof inferenceScopeSchema>;
114
+ export type BillingPrincipal = z.infer<typeof billingPrincipalSchema>;
115
+ export type AuthenticatedPrincipal = z.infer<typeof authenticatedPrincipalSchema>;
116
+ export type InferenceAttribution = z.infer<typeof inferenceAttributionSchema>;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Canonical attribution carried by the signed envelope.
3
+ *
4
+ * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/attribution.ts`) by Kaana ADR 0002.
5
+ */
6
+ import { z } from 'zod';
7
+ import { delegatedUserIdSchema, generationIdSchema, inferenceEnvironmentSchema, oxyApplicationIdSchema, oxyCredentialIdSchema, requestIdSchema, } from '../public/identifiers.js';
8
+ import { oxyAccountIdSchema } from './identifiers.js';
9
+ /**
10
+ * The inference capability scopes the data plane needs to know about.
11
+ *
12
+ * A credential may carry many other Oxy scopes; only these cross the boundary,
13
+ * because the data plane's authorization questions are exactly "may this caller
14
+ * invoke", "may it read the catalogue", "may it read usage", "may it read or
15
+ * write routing", "may it read or write provider connections". Everything else
16
+ * is the control plane's business and is not the data plane's to hold.
17
+ */
18
+ export const INFERENCE_SCOPES = [
19
+ 'inference:invoke',
20
+ 'inference:models:read',
21
+ 'inference:usage:read',
22
+ 'inference:routing:read',
23
+ 'inference:routing:write',
24
+ 'inference:providers:read',
25
+ 'inference:providers:write',
26
+ ];
27
+ export const inferenceScopeSchema = z.enum(INFERENCE_SCOPES);
28
+ /**
29
+ * The financially responsible principal, and the ONLY identity a charge may be
30
+ * booked against.
31
+ *
32
+ * It is its own type — not a field on a larger principal object — precisely so
33
+ * that a function taking "who pays" cannot be handed a user, a session, a
34
+ * device or an application. It cannot be constructed from a delegated user id:
35
+ * the brands differ, and this object accepts no other key.
36
+ */
37
+ export const billingPrincipalSchema = z
38
+ .object({
39
+ accountId: oxyAccountIdSchema,
40
+ })
41
+ .strict();
42
+ /**
43
+ * Who authenticated, as resolved by the Oxy edge before a request is forwarded.
44
+ *
45
+ * Mirrors what a verified Oxy service token carries (`appId`, `credentialId`,
46
+ * `ownerAccountId`, `environment`, effective scopes) so that the two
47
+ * authentication paths — a machine API key and a first-party service token —
48
+ * produce one shape downstream. The data plane authorizes against this
49
+ * envelope; it does not re-derive access from its own database, because it has
50
+ * no account graph to re-derive it from.
51
+ */
52
+ export const authenticatedPrincipalSchema = z.object({
53
+ billing: billingPrincipalSchema,
54
+ applicationId: oxyApplicationIdSchema,
55
+ credentialId: oxyCredentialIdSchema,
56
+ environment: inferenceEnvironmentSchema,
57
+ inferenceScopes: z.array(inferenceScopeSchema),
58
+ });
59
+ /**
60
+ * The attribution block carried by every request, receipt and ledger record.
61
+ *
62
+ * `userId` is the OPTIONAL delegated end user — Alia's `X-Oxy-User-Id`. It is
63
+ * attribution only: it never changes which account is charged, never grants
64
+ * access, and lives outside {@link billingPrincipalSchema} so that no code path
65
+ * can read it as the payer.
66
+ *
67
+ * `requestId` is generated by the OXY EDGE, on admission and before
68
+ * authentication completes, and is always present (ADR 0007). Not by the data
69
+ * plane: a data plane that minted the correlation key could not correlate a
70
+ * request it never received, and the requests rejected at the edge are exactly
71
+ * the ones an operator most needs to find.
72
+ *
73
+ * `generationId` is present once a generation exists, which is why it is
74
+ * optional on a request and expected on a receipt. That one IS the data plane's,
75
+ * because only the data plane knows how many outputs a request produced.
76
+ */
77
+ export const inferenceAttributionSchema = z.object({
78
+ principal: authenticatedPrincipalSchema,
79
+ userId: delegatedUserIdSchema.optional(),
80
+ requestId: requestIdSchema,
81
+ generationId: generationIdSchema.optional(),
82
+ });
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Canonical JSON and the canonical input hash.
3
+ *
4
+ * Operations with a source approval (scoped execution, Private Auto, the Jev
5
+ * classifier) bind the exact input they were approved for. Kaana computes the
6
+ * hash of the input it is about to execute and Oxy compares it with the one
7
+ * the approval fixed (Kaana ADR 0002, decision 4), so both sides must hash the
8
+ * same bytes. This is that one definition.
9
+ *
10
+ * `canonicalJson` is moved from `@oxy.so/contracts` 4.12.0
11
+ * (`canonicalScopedExecutionJson`, `src/inference/scopedExecution.ts`), and Go
12
+ * restates it in `internal/contract/scoped_execution.go`.
13
+ */
14
+ /**
15
+ * Canonical JSON wire bytes: recursive UTF-16 key order, JSON string/number
16
+ * encoding, arrays in order, no whitespace. Hash the whole signed input, not a
17
+ * reparsed/defaulted decision. Reject non-JSON values rather than dropping them.
18
+ */
19
+ export declare function canonicalJson(value: unknown): string;
20
+ /** The name scoped execution has always used for {@link canonicalJson}. */
21
+ export declare const canonicalScopedExecutionJson: typeof canonicalJson;
22
+ /**
23
+ * The canonical input hash: lowercase hex SHA-256 of {@link canonicalJson} of
24
+ * the request input, UTF-8 encoded.
25
+ *
26
+ * Asynchronous because it uses Web Crypto, which every runtime this package
27
+ * supports (Node 20+, Bun, browsers, Hermes with a crypto polyfill) provides
28
+ * without importing a platform module. Never logged or persisted: it binds
29
+ * transient signed bytes.
30
+ */
31
+ export declare function canonicalInputSha256(input: unknown): Promise<string>;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Canonical JSON and the canonical input hash.
3
+ *
4
+ * Operations with a source approval (scoped execution, Private Auto, the Jev
5
+ * classifier) bind the exact input they were approved for. Kaana computes the
6
+ * hash of the input it is about to execute and Oxy compares it with the one
7
+ * the approval fixed (Kaana ADR 0002, decision 4), so both sides must hash the
8
+ * same bytes. This is that one definition.
9
+ *
10
+ * `canonicalJson` is moved from `@oxy.so/contracts` 4.12.0
11
+ * (`canonicalScopedExecutionJson`, `src/inference/scopedExecution.ts`), and Go
12
+ * restates it in `internal/contract/scoped_execution.go`.
13
+ */
14
+ /**
15
+ * Canonical JSON wire bytes: recursive UTF-16 key order, JSON string/number
16
+ * encoding, arrays in order, no whitespace. Hash the whole signed input, not a
17
+ * reparsed/defaulted decision. Reject non-JSON values rather than dropping them.
18
+ */
19
+ export function canonicalJson(value) {
20
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
21
+ return JSON.stringify(value);
22
+ if (typeof value === 'number' && Number.isFinite(value))
23
+ return JSON.stringify(value);
24
+ if (Array.isArray(value)) {
25
+ const entries = Array.from(value, (entry, index) => {
26
+ if (!(index in value))
27
+ throw new Error('Canonical JSON requires dense JSON arrays.');
28
+ return canonicalJson(entry);
29
+ });
30
+ return `[${entries.join(',')}]`;
31
+ }
32
+ if (typeof value === 'object' &&
33
+ value !== null &&
34
+ Object.getPrototypeOf(value) === Object.prototype) {
35
+ const entries = Object.keys(value)
36
+ .sort()
37
+ .map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`);
38
+ return `{${entries.join(',')}}`;
39
+ }
40
+ throw new Error('Canonical JSON requires JSON wire values.');
41
+ }
42
+ /** The name scoped execution has always used for {@link canonicalJson}. */
43
+ export const canonicalScopedExecutionJson = canonicalJson;
44
+ /**
45
+ * The canonical input hash: lowercase hex SHA-256 of {@link canonicalJson} of
46
+ * the request input, UTF-8 encoded.
47
+ *
48
+ * Asynchronous because it uses Web Crypto, which every runtime this package
49
+ * supports (Node 20+, Bun, browsers, Hermes with a crypto polyfill) provides
50
+ * without importing a platform module. Never logged or persisted: it binds
51
+ * transient signed bytes.
52
+ */
53
+ export async function canonicalInputSha256(input) {
54
+ const bytes = new TextEncoder().encode(canonicalJson(input));
55
+ const digest = await globalThis.crypto.subtle.digest('SHA-256', bytes);
56
+ return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, '0')).join('');
57
+ }