@oxy.so/contracts 4.6.0 → 4.8.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 (34) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/agency.js +49 -0
  3. package/dist/cjs/capabilityInvocation.js +173 -0
  4. package/dist/cjs/index.js +28 -1
  5. package/dist/cjs/inference/catalogue.js +11 -4
  6. package/dist/cjs/inference/decisions.js +245 -0
  7. package/dist/cjs/inference/request.js +46 -1
  8. package/dist/cjs/inference/scopedExecution.js +87 -0
  9. package/dist/cjs/inference/version.js +1 -1
  10. package/dist/esm/.tsbuildinfo +1 -1
  11. package/dist/esm/agency.js +49 -0
  12. package/dist/esm/capabilityInvocation.js +165 -0
  13. package/dist/esm/index.js +4 -0
  14. package/dist/esm/inference/catalogue.js +9 -2
  15. package/dist/esm/inference/decisions.js +239 -0
  16. package/dist/esm/inference/request.js +45 -0
  17. package/dist/esm/inference/scopedExecution.js +83 -0
  18. package/dist/esm/inference/version.js +1 -1
  19. package/dist/types/.tsbuildinfo +1 -1
  20. package/dist/types/agency.d.ts +6 -6
  21. package/dist/types/capabilityInvocation.d.ts +80 -0
  22. package/dist/types/index.d.ts +8 -0
  23. package/dist/types/inference/aliaModelRelease.d.ts +86 -86
  24. package/dist/types/inference/catalogue.d.ts +335 -142
  25. package/dist/types/inference/decisions.d.ts +1833 -0
  26. package/dist/types/inference/modelDocumentation.d.ts +236 -236
  27. package/dist/types/inference/realtime.d.ts +842 -842
  28. package/dist/types/inference/request.d.ts +3186 -419
  29. package/dist/types/inference/routingPolicy.d.ts +16 -16
  30. package/dist/types/inference/scopedExecution.d.ts +202 -0
  31. package/dist/types/inference/streamEvents.d.ts +8 -8
  32. package/dist/types/inference/usage.d.ts +4 -4
  33. package/dist/types/inference/version.d.ts +1 -1
  34. package/package.json +1 -1
@@ -25,8 +25,10 @@
25
25
  * docs/adr/0017-authorized-routes-in-the-envelope.md.
26
26
  */
27
27
  Object.defineProperty(exports, "__esModule", { value: true });
28
- exports.inferenceRequestSchema = exports.inferenceAudioOutputParametersSchema = exports.inferenceSpeechParametersSchema = exports.clientRequestMetadataSchema = exports.inferenceReasoningSchema = exports.responseFormatSchema = exports.toolChoiceSchema = exports.toolDefinitionSchema = exports.samplingParametersSchema = exports.inferenceInputSchema = exports.inferenceMessageSchema = exports.inferenceMessageRoleSchema = exports.inferenceToolCallSchema = exports.inferenceContentPartSchema = exports.inferenceContentSourceSchema = void 0;
28
+ exports.scopedInferenceRequestSchema = exports.inferenceRequestSchema = exports.inferenceAudioOutputParametersSchema = exports.inferenceSpeechParametersSchema = exports.clientRequestMetadataSchema = exports.inferenceReasoningSchema = exports.responseFormatSchema = exports.toolChoiceSchema = exports.toolDefinitionSchema = exports.samplingParametersSchema = exports.inferenceInputSchema = exports.inferenceMessageSchema = exports.inferenceMessageRoleSchema = exports.inferenceToolCallSchema = exports.inferenceContentPartSchema = exports.inferenceContentSourceSchema = void 0;
29
+ const decisions_1 = require("./decisions");
29
30
  const zod_1 = require("zod");
31
+ const scopedExecution_1 = require("./scopedExecution");
30
32
  const attribution_1 = require("./attribution");
31
33
  const catalogue_1 = require("./catalogue");
32
34
  const identifiers_1 = require("./identifiers");
@@ -198,6 +200,7 @@ exports.inferenceMessageSchema = zod_1.z
198
200
  * that both metering and provider translation depend on.
199
201
  */
200
202
  exports.inferenceInputSchema = zod_1.z.discriminatedUnion("format", [
203
+ zod_1.z.object({ format: zod_1.z.literal("decisions"), decisions: decisions_1.decisionInputSchema }).strict(),
201
204
  zod_1.z
202
205
  .object({
203
206
  format: zod_1.z.literal("messages"),
@@ -352,6 +355,8 @@ exports.inferenceRequestSchema = zod_1.z
352
355
  .object({
353
356
  /** See `version.ts`: this is the Oxy→data-plane request envelope. */
354
357
  schemaVersion: zod_1.z.literal(2),
358
+ /** Recognized so v2 refuses rather than silently stripping a restriction. */
359
+ scopedExecution: scopedExecution_1.scopedExecutionSchema.optional(),
355
360
  attribution: attribution_1.inferenceAttributionSchema,
356
361
  target: routingPolicy_1.routingTargetSchema,
357
362
  modality: catalogue_1.inferenceModalitySchema,
@@ -406,6 +411,19 @@ exports.inferenceRequestSchema = zod_1.z
406
411
  authorizedRoutes: zod_1.z.array(routingPolicy_1.authorizedRouteSchema).min(1).optional(),
407
412
  })
408
413
  .superRefine((request, ctx) => {
414
+ if (request.scopedExecution !== undefined)
415
+ ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, path: ["scopedExecution"], message: "Scoped execution requires envelope v3." });
416
+ if (request.input.format === "decisions" || request.client.apiFormat === "decisions") {
417
+ const exactModel = request.target.kind === "model" && request.target.modelReference.includes('@');
418
+ const foreignRoute = request.authorizedRoutes?.some((route) => request.target.kind !== "model" || route.modelReference !== request.target.modelReference || route.substitution !== "same_model");
419
+ if (request.input.format !== "decisions" || request.client.apiFormat !== "decisions" ||
420
+ request.modality !== "text" || request.stream || !exactModel || foreignRoute ||
421
+ request.maxOutputTokens !== undefined || Object.keys(request.sampling).length > 0 ||
422
+ request.tools.length > 0 || request.toolChoice !== undefined || request.responseFormat !== undefined ||
423
+ request.reasoning !== undefined || request.speech !== undefined || request.audioOutput !== undefined) {
424
+ ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, path: ["input"], message: "Decisions require exact-model typed nonstreaming input without generation controls or model substitution." });
425
+ }
426
+ }
409
427
  const isSpeech = request.client.apiFormat === "audio_speech";
410
428
  if (isSpeech && request.speech !== undefined && (request.modality !== "audio" || request.input.format !== "text" || request.stream)) {
411
429
  ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, path: ["speech"], message: "speech requires audio modality, text input, parameters and non-streaming output" });
@@ -524,3 +542,30 @@ exports.inferenceRequestSchema = zod_1.z
524
542
  });
525
543
  }
526
544
  });
545
+ /** Explicit restrictive generation: old v2 receivers reject this version whole. */
546
+ exports.scopedInferenceRequestSchema = exports.inferenceRequestSchema.innerType()
547
+ .extend({ schemaVersion: zod_1.z.literal(scopedExecution_1.SCOPED_REQUEST_ENVELOPE_VERSION), scopedExecution: scopedExecution_1.scopedExecutionSchema })
548
+ .superRefine((request, ctx) => {
549
+ const { scopedExecution: scope, ...base } = request;
550
+ const legacy = exports.inferenceRequestSchema.safeParse({ ...base, schemaVersion: 2 });
551
+ if (!legacy.success)
552
+ for (const issue of legacy.error.issues)
553
+ ctx.addIssue(issue);
554
+ const principal = request.attribution.principal;
555
+ const route = request.authorizedRoutes?.[0];
556
+ if (request.input.format !== "decisions" || request.client.apiFormat !== "decisions" ||
557
+ scope.requestId !== request.attribution.requestId ||
558
+ scope.idempotencyKey !== request.idempotencyKey ||
559
+ scope.principal.accountId !== principal.billing.accountId ||
560
+ scope.principal.applicationId !== principal.applicationId ||
561
+ scope.principal.credentialId !== principal.credentialId ||
562
+ scope.principal.environment !== principal.environment ||
563
+ scope.policy.routingPolicyId !== request.routingPolicy.routingPolicyId ||
564
+ scope.policy.policyVersion !== request.routingPolicy.policyVersion ||
565
+ request.authorizedRoutes?.length !== 1 || route?.customerProviderCredential !== undefined ||
566
+ route?.deploymentId !== scope.deploymentId || route?.provider !== scope.provider ||
567
+ route?.modelReference !== scope.modelReference ||
568
+ request.target.kind !== "model" || request.target.modelReference !== scope.modelReference) {
569
+ ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, path: ["scopedExecution"], message: "Scoped execution must restrict the exact attributed decisions request and one platform route." });
570
+ }
571
+ });
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scopedExecutionSchema = exports.scopedExecutionAudienceSchema = exports.SCOPED_REQUEST_ENVELOPE_VERSION = exports.SCOPED_EXECUTION_CONTRACT_VERSION = void 0;
4
+ exports.canonicalScopedExecutionJson = canonicalScopedExecutionJson;
5
+ const zod_1 = require("zod");
6
+ const identifiers_1 = require("./identifiers");
7
+ const money_1 = require("./money");
8
+ /** Explicit extension negotiation; never replaces the legacy 3.5 handshake. */
9
+ exports.SCOPED_EXECUTION_CONTRACT_VERSION = "3.6.0";
10
+ /** Scoped only; normal envelope v2 and metadata 3.5 remain unchanged. */
11
+ exports.SCOPED_REQUEST_ENVELOPE_VERSION = 3;
12
+ const identity = zod_1.z.string().min(1).max(256);
13
+ const sha256 = zod_1.z.string().regex(/^[0-9a-f]{64}$/);
14
+ const maxCost = money_1.exactDecimalSchema.refine((value) => {
15
+ if (!money_1.exactDecimalSchema.safeParse(value).success)
16
+ return false;
17
+ const [whole, fraction = ""] = value.split(".");
18
+ const units = BigInt(whole) * 1000000000000n + BigInt(fraction.padEnd(12, "0"));
19
+ return units > 0n && units <= 10000000000n;
20
+ }, "scoped cost must be positive and at most 0.01 USD");
21
+ /** Restriction only: none of these identities grants catalogue eligibility. */
22
+ exports.scopedExecutionAudienceSchema = zod_1.z
23
+ .object({
24
+ permitId: identity,
25
+ idempotencyKey: identifiers_1.idempotencyKeySchema,
26
+ fixtureSha256: sha256,
27
+ expiresAt: zod_1.z.string().datetime(),
28
+ principal: zod_1.z
29
+ .object({
30
+ accountId: identity,
31
+ applicationId: identity,
32
+ credentialId: identity,
33
+ environment: identifiers_1.inferenceEnvironmentSchema,
34
+ })
35
+ .strict(),
36
+ policy: zod_1.z
37
+ .object({
38
+ routingPolicyId: zod_1.z.string().min(1).max(128),
39
+ policyVersion: zod_1.z.number().int().positive().safe(),
40
+ })
41
+ .strict(),
42
+ deploymentId: identifiers_1.deploymentIdSchema,
43
+ provider: identifiers_1.inferenceProviderSlugSchema,
44
+ keyId: identity,
45
+ modelReference: identifiers_1.modelReferenceSchema.refine((value) => value.includes("@"), "must pin a revision"),
46
+ upstreamModelId: identity,
47
+ priceVersionId: identity,
48
+ providerRateCardVersionId: identity,
49
+ providerSourceVersion: identity,
50
+ maxCostUsd: maxCost,
51
+ })
52
+ .strict();
53
+ exports.scopedExecutionSchema = exports.scopedExecutionAudienceSchema
54
+ .extend({
55
+ requestId: identifiers_1.requestIdSchema,
56
+ snapshotId: identity,
57
+ catalogueEvidenceHash: sha256,
58
+ })
59
+ .strict();
60
+ /**
61
+ * Canonical JSON wire bytes: recursive UTF-16 key order, JSON string/number
62
+ * encoding, arrays in order, no whitespace. Hash the whole signed input, not a
63
+ * reparsed/defaulted decision. Reject non-JSON values rather than dropping them.
64
+ */
65
+ function canonicalScopedExecutionJson(value) {
66
+ if (value === null || typeof value === "string" || typeof value === "boolean")
67
+ return JSON.stringify(value);
68
+ if (typeof value === "number" && Number.isFinite(value))
69
+ return JSON.stringify(value);
70
+ if (Array.isArray(value)) {
71
+ const entries = Array.from(value, (entry, index) => {
72
+ if (!(index in value))
73
+ throw new Error("Scoped execution requires dense JSON arrays.");
74
+ return canonicalScopedExecutionJson(entry);
75
+ });
76
+ return `[${entries.join(",")}]`;
77
+ }
78
+ if (typeof value === "object" &&
79
+ value !== null &&
80
+ Object.getPrototypeOf(value) === Object.prototype) {
81
+ const entries = Object.keys(value)
82
+ .sort()
83
+ .map((key) => `${JSON.stringify(key)}:${canonicalScopedExecutionJson(value[key])}`);
84
+ return `{${entries.join(",")}}`;
85
+ }
86
+ throw new Error("Scoped execution requires JSON wire values.");
87
+ }
@@ -102,4 +102,4 @@ exports.INFERENCE_CONTRACT_VERSION = void 0;
102
102
  * change to, say, the catalogue reject every in-flight inference request; the
103
103
  * per-shape `schemaVersion` is what a message is validated against.
104
104
  */
105
- exports.INFERENCE_CONTRACT_VERSION = '3.4.0';
105
+ exports.INFERENCE_CONTRACT_VERSION = '3.5.0';