@to11ai/sdk 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/behaviors/store.d.ts +62 -0
  2. package/dist/client.cjs +37 -4
  3. package/dist/client.d.ts +41 -2
  4. package/dist/client.js +45 -4
  5. package/dist/errors.cjs +90 -1
  6. package/dist/errors.d.ts +142 -0
  7. package/dist/errors.js +90 -1
  8. package/dist/gateway.cjs +12 -0
  9. package/dist/gateway.d.ts +26 -12
  10. package/dist/gateway.js +14 -0
  11. package/dist/generated/index.d.ts +1 -0
  12. package/dist/generated/types.gen.d.ts +22978 -0
  13. package/dist/generated/zod.gen.d.ts +13543 -0
  14. package/dist/projectEnvironments/resource.cjs +7 -2
  15. package/dist/projectEnvironments/resource.js +7 -2
  16. package/dist/projectEnvironments/types.d.ts +4 -75
  17. package/dist/prompts/cache.d.ts +24 -3
  18. package/dist/prompts/resource.cjs +101 -3
  19. package/dist/prompts/resource.d.ts +47 -3
  20. package/dist/prompts/resource.js +103 -5
  21. package/dist/prompts/types.d.ts +36 -177
  22. package/dist/routingRules/resource.cjs +9 -2
  23. package/dist/routingRules/resource.js +9 -2
  24. package/dist/routingRules/types.d.ts +12 -123
  25. package/dist/transport.d.ts +23 -0
  26. package/package.json +23 -12
  27. package/src/behaviors/store.ts +175 -0
  28. package/src/client.ts +115 -3
  29. package/src/errors.ts +261 -0
  30. package/src/gateway.ts +54 -12
  31. package/src/generated/index.ts +3 -0
  32. package/src/generated/types.gen.ts +24087 -0
  33. package/src/generated/zod.gen.ts +12660 -0
  34. package/src/projectEnvironments/resource.ts +10 -0
  35. package/src/projectEnvironments/types.ts +9 -91
  36. package/src/prompts/cache.ts +39 -4
  37. package/src/prompts/resource.ts +258 -5
  38. package/src/prompts/types.ts +56 -237
  39. package/src/routingRules/resource.ts +10 -1
  40. package/src/routingRules/types.ts +21 -155
  41. package/src/traceparent.ts +69 -4
  42. package/src/transport.ts +188 -3
@@ -1,73 +1,35 @@
1
- /**
2
- * Per-row pointer carried on 422 validation envelopes.
3
- *
4
- * The published `@to11ai/sdk` package does NOT depend on the internal
5
- * `@to11/shared-kernel` workspace package (it would pull workspace-only
6
- * types into a public npm release). The shape below is therefore
7
- * declared identically to `RowError` in
8
- * `packages/shared-kernel/src/schemas/api-schemas.ts` — keep them in
9
- * lockstep when adding new fields.
10
- *
11
- * 422 responses for prompt-version writes carry an optional
12
- * `error.rowErrors` array — one entry per failing field. Each row
13
- * carries:
14
- *
15
- * - `path`: JSON-pointer-equivalent array, e.g.
16
- * `["messages", 3, "name"]`.
17
- * - `code`: stable identifier such as `tool_name_invalid_charset`
18
- * or `messages_empty` — see the platform spec for the full set.
19
- * - `message`: a human-readable summary.
20
- *
21
- * SDK consumers can detect the structured shape by inspecting
22
- * `error.code === "validation_failed"` and walking `error.rowErrors`
23
- * (always optional; absent on non-validation 422s).
24
- */
1
+ import type {
2
+ ProjectPromptLabel as GenProjectPromptLabel,
3
+ ProjectPromptLabelUsage as GenProjectPromptLabelUsage,
4
+ Prompt as GenPrompt,
5
+ PromptLabelEvent as GenPromptLabelEvent,
6
+ PromptLabelPointer as GenPromptLabelPointer,
7
+ PromptVersion as GenPromptVersion,
8
+ RenderedChatPrompt as GenRenderedChatPrompt,
9
+ RenderedPrompt as GenRenderedPrompt,
10
+ ResolvedPrompt as GenResolvedPrompt,
11
+ } from "../generated/types.gen";
12
+
25
13
  export interface RowError {
26
14
  path: ReadonlyArray<string | number>;
27
15
  code: string;
28
16
  message: string;
29
17
  }
30
18
 
31
- // ─── Shared primitives ─────────────────────────────────────────────────────
32
-
33
- export type PromptStatus = "active" | "archived";
34
- export type PromptFormat = "text" | "chat";
19
+ export type Prompt = GenPrompt;
20
+ export type PromptStatus = Prompt["status"];
21
+ export type PromptVersion = GenPromptVersion;
22
+ export type PromptFormat = PromptVersion["format"];
23
+ export type PromptLabelPointer = GenPromptLabelPointer;
35
24
 
36
- /**
37
- * Roles supported by `TextChatMessage`.
38
- *
39
- * V1 server contract: `developer` is accepted at the wire boundary and
40
- * rendered as `user` in `:resolve` responses. The literal is preserved
41
- * here so SDK consumers can author developer-tagged messages today and
42
- * V2 can flip the rendered role without a wire-level break.
43
- */
44
25
  export type TextChatRole = "system" | "user" | "assistant" | "developer";
45
26
 
46
- /**
47
- * Text-style chat message. Carries a Liquid template body in `content`.
48
- *
49
- * `disabled` skips the message at render time but preserves it through
50
- * edit / list / get round-trips so authors can toggle messages without
51
- * losing them.
52
- */
53
27
  export interface TextChatMessage {
54
28
  role: TextChatRole;
55
29
  content: string;
56
30
  disabled?: boolean;
57
31
  }
58
32
 
59
- /**
60
- * Tool-call chat message. Structurally distinct from text messages: it
61
- * carries `name` / `description` / `parameters` instead of `content`.
62
- *
63
- * - `name`: 1..200 chars, matches the tool name the gateway exposes to
64
- * providers.
65
- * - `description`: optional human-readable summary surfaced in the
66
- * provider's tool-choice UI.
67
- * - `parameters`: JSON Schema (an object) describing the tool's
68
- * arguments. Not validated against the JSON Schema meta-schema at
69
- * edit time — the gateway is the source of truth.
70
- */
71
33
  export interface ToolChatMessage {
72
34
  role: "tool";
73
35
  name: string;
@@ -76,85 +38,16 @@ export interface ToolChatMessage {
76
38
  disabled?: boolean;
77
39
  }
78
40
 
79
- /**
80
- * Discriminated union of text and tool chat messages.
81
- *
82
- * Legacy `{role: "tool", content: "..."}` rows are auto-upgraded by the
83
- * server on read: they decode as `{role: "tool", name: "(unnamed)",
84
- * description: <legacy content>, parameters: {}}`. Writes always emit
85
- * the new shape.
86
- */
87
41
  export type ChatMessage = TextChatMessage | ToolChatMessage;
88
42
 
89
- // ─── Prompt ────────────────────────────────────────────────────────────────
90
-
91
- export interface Prompt {
92
- id: string;
93
- projectId: string;
94
- name: string;
95
- slug: string;
96
- description: string | null;
97
- tags: string[];
98
- status: PromptStatus;
99
- createdByUserId: string;
100
- createdAt: string;
101
- updatedAt: string;
102
- }
103
-
104
- // ─── PromptVersion ─────────────────────────────────────────────────────────
105
-
106
- export interface PromptVersion {
107
- id: string;
108
- promptId: string;
109
- version: number;
110
- format: PromptFormat;
111
- templateJson: unknown;
112
- variablesSchema: unknown;
113
- modelConfig: unknown;
114
- changelog: string | null;
115
- createdByUserId: string;
116
- createdAt: string;
117
- }
118
-
119
- // ─── PromptLabelPointer ────────────────────────────────────────────────────
43
+ export type RenderedChatMessage = GenRenderedChatPrompt["messages"][number];
120
44
 
121
- export interface PromptLabelPointer {
122
- promptId: string;
123
- label: string;
124
- versionId: string;
125
- updatedByUserId: string;
126
- updatedAt: string;
127
- }
128
-
129
- // ─── ResolvedPrompt ────────────────────────────────────────────────────────
130
-
131
- /**
132
- * A single message in a rendered chat prompt returned by `:resolve`.
133
- *
134
- * Always carries a flat `{role, content}` shape — even tool/developer
135
- * messages, since the server normalises them at render time
136
- * (V1 contract: tool messages are filtered, developer is mapped to user).
137
- * The `role` literal stays wide so V2 changes are wire-compatible.
138
- */
139
- export interface RenderedChatMessage {
140
- role: "system" | "user" | "assistant" | "developer" | "tool";
141
- content: string;
142
- }
143
-
144
- export type RenderedPrompt =
145
- | { format: "text"; text: string }
146
- | { format: "chat"; messages: RenderedChatMessage[] };
147
-
148
- export interface ResolvedPrompt {
149
- promptId: string;
150
- versionId: string;
151
- version: number;
152
- labels: string[];
153
- contentHash: string;
154
- rendered: RenderedPrompt;
155
- }
45
+ export type RenderedPrompt = GenRenderedPrompt;
156
46
 
157
- // ─── Pagination ────────────────────────────────────────────────────────────
47
+ export type ResolvedPrompt = Pick<
48
+ GenResolvedPrompt,
49
+ "promptId" | "versionId" | "version" | "labels" | "contentHash" | "rendered"
50
+ >;
158
51
 
159
52
  export interface PaginationInfo {
160
53
  page: number;
@@ -168,8 +61,6 @@ export interface PaginatedResult<T> {
168
61
  pagination: PaginationInfo;
169
62
  }
170
63
 
171
- // ─── Input types ──────────────────────────────────────────────────────────
172
-
173
64
  export interface CreatePromptInput {
174
65
  projectId: string;
175
66
  name: string;
@@ -180,8 +71,6 @@ export interface CreatePromptInput {
180
71
 
181
72
  export type CreatePromptResult = Prompt;
182
73
 
183
- // ─────────────────────────────────────────────────────────────────────────
184
-
185
74
  export interface ListPromptsInput {
186
75
  projectId: string;
187
76
  status?: PromptStatus;
@@ -193,8 +82,6 @@ export interface ListPromptsInput {
193
82
 
194
83
  export type ListPromptsResult = Prompt;
195
84
 
196
- // ─────────────────────────────────────────────────────────────────────────
197
-
198
85
  export interface GetPromptInput {
199
86
  projectId: string;
200
87
  promptId: string;
@@ -202,8 +89,6 @@ export interface GetPromptInput {
202
89
 
203
90
  export type GetPromptResult = Prompt;
204
91
 
205
- // ─────────────────────────────────────────────────────────────────────────
206
-
207
92
  export interface UpdatePromptInput {
208
93
  projectId: string;
209
94
  promptId: string;
@@ -214,8 +99,6 @@ export interface UpdatePromptInput {
214
99
 
215
100
  export type UpdatePromptResult = Prompt;
216
101
 
217
- // ─────────────────────────────────────────────────────────────────────────
218
-
219
102
  export interface ArchivePromptInput {
220
103
  projectId: string;
221
104
  promptId: string;
@@ -223,8 +106,6 @@ export interface ArchivePromptInput {
223
106
 
224
107
  export type ArchivePromptResult = Prompt;
225
108
 
226
- // ─────────────────────────────────────────────────────────────────────────
227
-
228
109
  export interface CreatePromptVersionInput {
229
110
  projectId: string;
230
111
  promptId: string;
@@ -237,8 +118,6 @@ export interface CreatePromptVersionInput {
237
118
 
238
119
  export type CreatePromptVersionResult = PromptVersion;
239
120
 
240
- // ─────────────────────────────────────────────────────────────────────────
241
-
242
121
  export interface ListPromptVersionsInput {
243
122
  projectId: string;
244
123
  promptId: string;
@@ -246,8 +125,6 @@ export interface ListPromptVersionsInput {
246
125
 
247
126
  export type ListPromptVersionsResult = PromptVersion[];
248
127
 
249
- // ─────────────────────────────────────────────────────────────────────────
250
-
251
128
  export interface GetPromptVersionInput {
252
129
  projectId: string;
253
130
  promptId: string;
@@ -256,8 +133,6 @@ export interface GetPromptVersionInput {
256
133
 
257
134
  export type GetPromptVersionResult = PromptVersion;
258
135
 
259
- // ─────────────────────────────────────────────────────────────────────────
260
-
261
136
  export interface MovePromptLabelInput {
262
137
  projectId: string;
263
138
  promptId: string;
@@ -268,8 +143,6 @@ export interface MovePromptLabelInput {
268
143
 
269
144
  export type MovePromptLabelResult = PromptLabelPointer;
270
145
 
271
- // ─────────────────────────────────────────────────────────────────────────
272
-
273
146
  export interface ListPromptLabelsInput {
274
147
  projectId: string;
275
148
  promptId: string;
@@ -277,8 +150,6 @@ export interface ListPromptLabelsInput {
277
150
 
278
151
  export type ListPromptLabelsResult = PromptLabelPointer[];
279
152
 
280
- // ─────────────────────────────────────────────────────────────────────────
281
-
282
153
  export interface ResolvePromptInput {
283
154
  projectId: string;
284
155
  slug: string;
@@ -292,84 +163,46 @@ export interface ResolvePromptInput {
292
163
 
293
164
  export type ResolvePromptResult = ResolvedPrompt;
294
165
 
295
- // ─── Project label registry (TO11-666 / phase 2) ───────────────────────────
296
- //
297
- // Wire shapes mirror the API's `ProjectPromptLabel`, `ProjectPromptLabelUsage`,
298
- // and `PromptLabelEvent` schemas. The palette token enum is kept in lockstep
299
- // with the DB CHECK constraint introduced in the prompt-label-registry
300
- // migration.
301
-
302
- /** Palette token assigned to a project label for UI rendering. */
303
- export type PaletteToken =
304
- | "accent"
305
- | "red"
306
- | "orange"
307
- | "amber"
308
- | "green"
309
- | "teal"
310
- | "blue"
311
- | "indigo"
312
- | "purple"
313
- | "pink";
314
-
315
- /**
316
- * Project-level label registry entry.
317
- *
318
- * System labels (`isSystem: true`) cannot be archived. `archivedAt` is
319
- * non-null for soft-deleted entries; the list endpoint excludes archived
320
- * entries by default — pass `includeArchived: true` if the call site needs
321
- * them (e.g. admin / history affordances).
322
- */
323
- export interface ProjectPromptLabel {
324
- projectId: string;
325
- label: string;
326
- isSystem: boolean;
327
- isDefault: boolean;
328
- description: string | null;
329
- displayColor: PaletteToken;
330
- createdByUserId: string;
331
- createdAt: string;
332
- updatedAt: string;
333
- archivedAt: string | null;
334
- }
166
+ export const ENV_SLUG_REGEX = /^[a-z0-9-]{1,63}$/;
167
+
168
+ export type BlockRenderRecord = Record<string, "rendered" | "dimmed">;
335
169
 
336
- /**
337
- * A single prompt currently pointed at by a given project label.
338
- *
339
- * Returned by `GET /v1/projects/:projectId/prompt-labels/:label/usages`.
340
- * `updatedAt` / `updatedByUserId` carry the last-move metadata so the UI
341
- * can render a "moved 3 days ago by …" affordance without a second
342
- * roundtrip.
343
- */
344
- export interface ProjectPromptLabelUsage {
170
+ export type PromptContext = Record<string, string | number | boolean>;
171
+
172
+ export interface FetchedPrompt {
173
+ messages: RenderedChatMessage[];
174
+ version: number;
175
+ releaseId: string | null;
176
+ variantName?: string;
177
+ blockRenderRecord: BlockRenderRecord;
345
178
  promptId: string;
346
- promptSlug: string;
347
- promptName: string;
348
179
  versionId: string;
349
- version: number;
350
- updatedAt: string;
351
- updatedByUserId: string;
180
+ contentHash: string;
181
+ labels: string[];
182
+ rendered: RenderedPrompt;
352
183
  }
353
184
 
354
- /**
355
- * An immutable history row for a single label movement.
356
- *
357
- * `fromVersionId` is `null` for the first time the label is pointed at a
358
- * version (no prior pointer). `reason` is the optional caller-supplied
359
- * audit string.
360
- */
361
- export interface PromptLabelEvent {
362
- id: string;
363
- promptId: string;
364
- label: string;
365
- fromVersionId: string | null;
366
- toVersionId: string;
367
- movedByUserId: string;
368
- movedAt: string;
369
- reason: string | null;
185
+ export type ResolvedPromptEnvelope = GenResolvedPrompt & {
186
+ /** Active release strategy. Used to decide weighted-no-subject cache bypass (D8). */
187
+ strategy?: "single" | "weighted";
188
+ };
189
+
190
+ export interface FetchPromptOptions {
191
+ env?: string;
192
+ context?: PromptContext;
193
+ subject?: string;
194
+ variables?: Record<string, unknown>;
195
+ cache?: boolean;
196
+ fallback?: ResolvedPrompt | FetchedPrompt;
370
197
  }
371
198
 
372
- // ─── Project label registry inputs ─────────────────────────────────────────
199
+ export type PaletteToken = ProjectPromptLabel["displayColor"];
200
+
201
+ export type ProjectPromptLabel = GenProjectPromptLabel;
202
+
203
+ export type ProjectPromptLabelUsage = GenProjectPromptLabelUsage;
204
+
205
+ export type PromptLabelEvent = GenPromptLabelEvent;
373
206
 
374
207
  export interface ListProjectPromptLabelsInput {
375
208
  projectId: string;
@@ -411,12 +244,6 @@ export interface DeleteProjectPromptLabelInput {
411
244
  label: string;
412
245
  }
413
246
 
414
- /**
415
- * The DELETE endpoint returns 200 with the archived row (mirrors the
416
- * `archivePrompt` pattern — call sites can show "archived just now"
417
- * without a follow-up GET). System labels (`isSystem: true`) cannot be
418
- * archived; the server returns 409 `PROJECT_LABEL_SYSTEM_NOT_DELETABLE`.
419
- */
420
247
  export type DeleteProjectPromptLabelResult = ProjectPromptLabel;
421
248
 
422
249
  export interface ListProjectPromptLabelUsagesInput {
@@ -426,14 +253,6 @@ export interface ListProjectPromptLabelUsagesInput {
426
253
 
427
254
  export type ListProjectPromptLabelUsagesResult = ProjectPromptLabelUsage[];
428
255
 
429
- // ─── Label event history (TO11-668 / phase 4) ──────────────────────────────
430
- //
431
- // One polymorphic SDK method `listLabelEvents` covers all three URL shapes
432
- // the server exposes. The `scope` discriminator selects between:
433
- // - `"label"` → `/v1/projects/:p/prompts/:pp/labels/:l/events`
434
- // - `"prompt"` → `/v1/projects/:p/prompts/:pp/label-events`
435
- // - `"project"` → `/v1/projects/:p/label-events`
436
-
437
256
  export type ListLabelEventsInput =
438
257
  | {
439
258
  scope: "label";
@@ -1,3 +1,5 @@
1
+ import { z } from "zod";
2
+ import { zRuleRelease, zRuleVersion } from "../generated/zod.gen";
1
3
  import type { ApiEnvelope, Transport } from "../transport";
2
4
  import type {
3
5
  CreateRuleVersionInput,
@@ -118,6 +120,9 @@ export class RoutingRuleVersionResource {
118
120
  const envelope = await this.transport.request<GetRuleVersionResult>(
119
121
  "GET",
120
122
  versionPath(input.projectId, input.ruleId, input.versionId),
123
+ {
124
+ decode: (data) => zRuleVersion.parse(data) as GetRuleVersionResult,
125
+ },
121
126
  );
122
127
  return unwrap(envelope);
123
128
  }
@@ -163,7 +168,11 @@ export class RoutingRuleReleaseResource {
163
168
  const envelope = await this.transport.request<ListRuleReleasesResult>(
164
169
  "GET",
165
170
  path,
166
- { query },
171
+ {
172
+ query,
173
+ decode: (data) =>
174
+ z.array(zRuleRelease).parse(data) as ListRuleReleasesResult,
175
+ },
167
176
  );
168
177
  return unwrap(envelope);
169
178
  }
@@ -1,118 +1,22 @@
1
- // ---------------------------------------------------------------------------
2
- // Routing Rule Versions + Env Pointers wire types (TO11-795 / llm-routing §S17).
3
- // ---------------------------------------------------------------------------
4
- // Spec: docs/product-specs/2026-05-14-llm-routing-env-pointers.md
5
- // Plan: docs/exec-plans/active/2026-05-14-llm-routing-env-pointers-plan.md §S17
6
- //
7
- // Hand-rolled TS mirrors of the Effect Schema types defined in
8
- // `apps/api/src/domains/llm-routing/model/rule-version.ts` and the wire
9
- // schemas exported from `apps/api/src/infrastructure/http/routes/rule-versions.ts`.
10
- // The published `@to11ai/sdk` package intentionally does NOT depend on the
11
- // internal `@to11/api` workspace package — keep these in lockstep with the
12
- // API model when adding fields.
13
- //
14
- // Credential invariant (per spec §"Data model"): `snapshotJson` MUST NOT
15
- // carry plaintext credentials. The wire shape declares it as `unknown` to
16
- // mirror the domain — provider references live inside `modelBindings[]` and
17
- // the gateway resolves credentials lazily at request time.
18
- // ---------------------------------------------------------------------------
19
-
20
- // ─── Snapshot shape ────────────────────────────────────────────────────────
21
-
22
- /**
23
- * Reference to a provider config bound to a specific environment. Mirrors
24
- * `RuleProviderRef` in the API domain model. `envSlug` is optional — when
25
- * omitted, the gateway falls back to the project's `is_gateway_fallback`
26
- * environment.
27
- */
28
- export interface RuleProviderRef {
29
- providerId: string;
30
- envSlug?: string;
31
- }
1
+ import type {
2
+ RuleModelBinding as GenRuleModelBinding,
3
+ RuleProviderRef as GenRuleProviderRef,
4
+ RuleRelease as GenRuleRelease,
5
+ RuleReleaseWeight as GenRuleReleaseWeight,
6
+ RuleSnapshot as GenRuleSnapshot,
7
+ RuleVersion as GenRuleVersion,
8
+ } from "../generated/types.gen";
32
9
 
33
- /**
34
- * Per-variant model binding inside a rule snapshot. Identifies which
35
- * `(provider, model)` pair serves a strategy variant; the gateway resolves
36
- * the actual credential at request time. `weight` is intentionally
37
- * permissive (0..100 in v1) so weighted/experimental strategies can evolve
38
- * without a SDK churn.
39
- */
40
- export interface RuleModelBinding {
41
- modelId: string;
42
- provider: RuleProviderRef;
43
- weight?: number;
44
- }
10
+ export type RuleProviderRef = GenRuleProviderRef;
45
11
 
46
- export type RuleStrategy = "single" | "weighted" | "fallback" | "experiment";
47
-
48
- /**
49
- * Frozen rule snapshot — the JSONB payload stored in
50
- * `rule_versions.snapshot_json`. Mirrors the API domain `RuleSnapshot`:
51
- *
52
- * * `alias` — optional `function::<alias>` indirection (S1).
53
- * * `strategy` — `single`, `weighted`, `fallback`, `experiment`.
54
- * * `endpoint` — `chat`, `embeddings`, …
55
- * * `variants[]` | `steps[]` | `chain[]` — strategy-shape arrays.
56
- * * `when` — optional condition AST that gates the rule.
57
- * * `retry` — optional `{ maxRetries?, backoffBaseMs?, retryableStatusCodes? }`.
58
- * * `modelBindings[]` — which `(providerId, modelId, envSlug)` serves each variant.
59
- * * `providerRefs[]` — flat denormalized list of referenced providers.
60
- *
61
- * No credential field exists; the gateway resolves credentials lazily from
62
- * the per-env `routing_snapshots` ciphertext.
63
- */
64
- export interface RuleSnapshot {
65
- alias?: string;
66
- strategy: RuleStrategy | string;
67
- endpoint: string;
68
- variants?: unknown[];
69
- steps?: unknown[];
70
- chain?: unknown[];
71
- when?: unknown;
72
- retry?: {
73
- maxRetries?: number;
74
- backoffBaseMs?: number;
75
- retryableStatusCodes?: number[];
76
- };
77
- modelBindings?: RuleModelBinding[];
78
- providerRefs?: RuleProviderRef[];
79
- }
12
+ export type RuleModelBinding = GenRuleModelBinding;
80
13
 
81
- // ─── Persisted shapes ──────────────────────────────────────────────────────
82
-
83
- /**
84
- * The persisted form of a rule version row as returned by
85
- * `GET /v1/projects/:projectId/routing/rules/:ruleId/versions/:versionId`.
86
- *
87
- * `version` is monotonic per `ruleId` — the server allocates it inside a
88
- * `SELECT MAX … FOR UPDATE` transaction. `snapshotJson` is typed as
89
- * `unknown` to mirror the API contract (the storage path persists JSONB
90
- * verbatim); callers that need the typed shape should cast through
91
- * `RuleSnapshot`.
92
- */
93
- export interface RuleVersion {
94
- id: string;
95
- ruleId: string;
96
- version: number;
97
- snapshotJson: unknown;
98
- description: string | null;
99
- createdBy: string;
100
- /** ISO-8601 timestamp. */
101
- createdAt: string;
102
- }
14
+ export type RuleStrategy = GenRuleSnapshot["strategy"];
15
+
16
+ export type RuleSnapshot = GenRuleSnapshot;
17
+
18
+ export type RuleVersion = GenRuleVersion;
103
19
 
104
- // ─── Inputs ─────────────────────────────────────────────────────────────────
105
-
106
- /**
107
- * Wire input accepted by
108
- * `POST /v1/projects/:p/routing/rules/:ruleId/versions`. Requires the
109
- * `routing:write` capability.
110
- *
111
- * `snapshot` is the cleartext snapshot JSON the gateway uses to resolve
112
- * runtime traffic — stored verbatim in `rule_versions.snapshot_json`.
113
- * `description` is an optional commit message; the API surfaces it on the
114
- * audit timeline.
115
- */
116
20
  export interface CreateRuleVersionInput {
117
21
  projectId: string;
118
22
  ruleId: string;
@@ -122,22 +26,10 @@ export interface CreateRuleVersionInput {
122
26
 
123
27
  export type CreateRuleVersionResult = RuleVersion;
124
28
 
125
- /**
126
- * Cursor-paginated list input. `cursor` is the `version` number BELOW which
127
- * to fetch (keyset pagination — pass the last item's `version` to continue).
128
- * `limit` is clamped server-side to `MAX_LIST_LIMIT` (200 at the time of
129
- * writing); default is 50.
130
- */
131
29
  export interface ListRuleVersionsInput {
132
30
  projectId: string;
133
31
  ruleId: string;
134
- /**
135
- * The `version` number BELOW which to fetch (the route uses a keyset
136
- * `WHERE version < cursor` clause and returns versions in `version DESC`
137
- * order). Omit for the first page.
138
- */
139
32
  cursor?: number;
140
- /** Page size. Server clamps to `[1, MAX_LIST_LIMIT]`. */
141
33
  limit?: number;
142
34
  }
143
35
 
@@ -151,43 +43,17 @@ export interface GetRuleVersionInput {
151
43
 
152
44
  export type GetRuleVersionResult = RuleVersion;
153
45
 
154
- // ─── Releases (S2 / TO11-1009) ──────────────────────────────────────────────
46
+ export type RuleReleaseStrategy = GenRuleRelease["strategy"];
155
47
 
156
- export type RuleReleaseStrategy = "single" | "weighted";
48
+ export type RuleReleaseChangeKind = GenRuleRelease["changeKind"];
157
49
 
158
- export type RuleReleaseChangeKind =
159
- | "release_initial"
160
- | "release_promoted"
161
- | "release_rolled_back"
162
- | "release_weight_changed";
50
+ export type RuleReleaseApprovalStatus = GenRuleRelease["approvalStatus"];
163
51
 
164
- export type RuleReleaseApprovalStatus = "committed" | "pending" | "rejected";
52
+ export type RuleReleaseActorType = GenRuleRelease["actorType"];
165
53
 
166
- export type RuleReleaseActorType = "user" | "api_key" | "worker";
54
+ export type RuleReleaseWeight = GenRuleReleaseWeight;
167
55
 
168
- export interface RuleReleaseWeight {
169
- versionId: string;
170
- weight: number;
171
- }
172
-
173
- export interface RuleRelease {
174
- id: string;
175
- ruleId: string;
176
- environmentId: string;
177
- envSlug: string;
178
- strategy: RuleReleaseStrategy;
179
- versionId: string | null;
180
- weights: RuleReleaseWeight[] | null;
181
- changeKind: RuleReleaseChangeKind;
182
- priorReleaseId: string | null;
183
- actorId: string;
184
- actorType: RuleReleaseActorType;
185
- reason: string | null;
186
- approvalStatus: RuleReleaseApprovalStatus;
187
- activeFrom: string | null;
188
- activeTo: string | null;
189
- createdAt: string;
190
- }
56
+ export type RuleRelease = GenRuleRelease;
191
57
 
192
58
  export interface SetRuleReleaseInput {
193
59
  projectId: string;