@lucern/sdk 0.2.0-alpha.5 → 0.2.0-alpha.7

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 (166) hide show
  1. package/.turbo/turbo-build.log +7 -0
  2. package/.turbo/turbo-typecheck.log +4 -0
  3. package/CHANGELOG.md +13 -0
  4. package/examples/README.md +69 -0
  5. package/examples/contradiction.ts +94 -0
  6. package/examples/investigation-context.ts +118 -0
  7. package/examples/questions-and-tasks.ts +55 -0
  8. package/examples/quickstart.ts +97 -0
  9. package/examples/shared.ts +318 -0
  10. package/examples/strict-public-types.ts +143 -0
  11. package/examples/worktree-lifecycle.ts +79 -0
  12. package/package.json +16 -59
  13. package/src/README.md +6 -0
  14. package/src/adminClient.ts +789 -0
  15. package/{dist/lib/platform/sdk/answersClient.d.ts → src/answersClient.ts} +17 -4
  16. package/src/audiencesClient.ts +209 -0
  17. package/src/auditClient.ts +50 -0
  18. package/src/beliefsClient.ts +319 -0
  19. package/src/client.ts +2647 -0
  20. package/src/contextClient.ts +130 -0
  21. package/src/contextFacade.ts +15 -0
  22. package/src/contextPackCompiler.ts +828 -0
  23. package/src/contextPackSchema.ts +251 -0
  24. package/src/contextTypes.ts +153 -0
  25. package/src/contracts/api-enums.contract.ts +202 -0
  26. package/src/contracts/auth-session.contract.ts +109 -0
  27. package/src/contracts/context-pack.contract.ts +700 -0
  28. package/src/contracts/contextPack.ts +1 -0
  29. package/src/contracts/index.ts +10 -0
  30. package/src/contracts/lens-filter.contract.ts +183 -0
  31. package/src/contracts/lens-workflow.contract.ts +162 -0
  32. package/src/contracts/lensFilter.ts +1 -0
  33. package/src/contracts/lensWorkflow.ts +1 -0
  34. package/src/contracts/mcp-tools.contract.ts +3636 -0
  35. package/src/contracts/mcpTools.ts +1 -0
  36. package/src/contracts/prompt.contract.ts +50 -0
  37. package/src/contracts/prompt.ts +1 -0
  38. package/src/contracts/sdk-tools.contract.ts +1457 -0
  39. package/src/contracts/sdkTools.ts +1 -0
  40. package/src/contracts/workflow-runtime.contract.ts +440 -0
  41. package/src/contracts/workflowRuntime.ts +1 -0
  42. package/src/controlObjectOwnership.ts +286 -0
  43. package/src/coreClient.ts +570 -0
  44. package/src/customTools.ts +398 -0
  45. package/src/decisionsClient.ts +286 -0
  46. package/src/domainContext.ts +15 -0
  47. package/src/events.ts +531 -0
  48. package/src/eventsCore.ts +168 -0
  49. package/src/facade/beliefs.ts +83 -0
  50. package/src/facade/context.ts +110 -0
  51. package/src/facade/contradictions.ts +29 -0
  52. package/src/facade/edges.ts +30 -0
  53. package/src/facade/events.ts +23 -0
  54. package/src/facade/evidence.ts +41 -0
  55. package/src/facade/graph.ts +38 -0
  56. package/src/facade/identity.ts +16 -0
  57. package/src/facade/ontologies.ts +34 -0
  58. package/src/facade/questions.ts +59 -0
  59. package/src/facade/search.ts +16 -0
  60. package/src/facade/tasks.ts +37 -0
  61. package/src/facade/topics.ts +42 -0
  62. package/src/facade/webhooks.ts +58 -0
  63. package/src/facade/worktrees.ts +51 -0
  64. package/src/gatewayFacades.ts +1666 -0
  65. package/src/graphClient.ts +529 -0
  66. package/src/harnessClient.ts +585 -0
  67. package/src/identityClient.ts +278 -0
  68. package/{dist/lib/platform/sdk/index.d.ts → src/index.ts} +3 -0
  69. package/src/learningClient.ts +95 -0
  70. package/src/mcpParityClient.ts +240 -0
  71. package/src/mcpParitySurface.ts +70 -0
  72. package/src/ontologyClient.ts +275 -0
  73. package/src/packRuntime.ts +3 -0
  74. package/src/packsClient.ts +260 -0
  75. package/src/policyClient.ts +572 -0
  76. package/src/promptCatalog.ts +1 -0
  77. package/src/realtime/index.ts +51 -0
  78. package/src/realtime/refs.ts +17 -0
  79. package/src/reportsClient.ts +99 -0
  80. package/src/schemaClient.ts +129 -0
  81. package/src/sdkSurface.ts +190 -0
  82. package/src/topicsClient.ts +243 -0
  83. package/src/types.ts +807 -0
  84. package/src/workflowClient.ts +826 -0
  85. package/tsconfig.json +9 -0
  86. package/dist/.generated +0 -2
  87. package/dist/index.d.ts +0 -3
  88. package/dist/index.js +0 -3
  89. package/dist/lib/platform/auth/credentials.d.ts +0 -5
  90. package/dist/lib/platform/auth/credentials.js +0 -40
  91. package/dist/lib/platform/sdk/adminClient.d.ts +0 -404
  92. package/dist/lib/platform/sdk/adminClient.js +0 -384
  93. package/dist/lib/platform/sdk/answersClient.js +0 -21
  94. package/dist/lib/platform/sdk/audiencesClient.d.ts +0 -93
  95. package/dist/lib/platform/sdk/audiencesClient.js +0 -111
  96. package/dist/lib/platform/sdk/auditClient.d.ts +0 -24
  97. package/dist/lib/platform/sdk/auditClient.js +0 -21
  98. package/dist/lib/platform/sdk/beliefsClient.d.ts +0 -157
  99. package/dist/lib/platform/sdk/beliefsClient.js +0 -124
  100. package/dist/lib/platform/sdk/client.d.ts +0 -2369
  101. package/dist/lib/platform/sdk/client.js +0 -1831
  102. package/dist/lib/platform/sdk/contextClient.d.ts +0 -21
  103. package/dist/lib/platform/sdk/contextClient.js +0 -86
  104. package/dist/lib/platform/sdk/contextPackCompiler.d.ts +0 -100
  105. package/dist/lib/platform/sdk/contextPackCompiler.js +0 -534
  106. package/dist/lib/platform/sdk/contextTypes.d.ts +0 -133
  107. package/dist/lib/platform/sdk/contextTypes.js +0 -1
  108. package/dist/lib/platform/sdk/controlObjectOwnership.d.ts +0 -308
  109. package/dist/lib/platform/sdk/controlObjectOwnership.js +0 -220
  110. package/dist/lib/platform/sdk/coreClient.d.ts +0 -139
  111. package/dist/lib/platform/sdk/coreClient.js +0 -366
  112. package/dist/lib/platform/sdk/customTools.d.ts +0 -83
  113. package/dist/lib/platform/sdk/customTools.js +0 -247
  114. package/dist/lib/platform/sdk/decisionsClient.d.ts +0 -106
  115. package/dist/lib/platform/sdk/decisionsClient.js +0 -129
  116. package/dist/lib/platform/sdk/domainContext.d.ts +0 -1
  117. package/dist/lib/platform/sdk/domainContext.js +0 -1
  118. package/dist/lib/platform/sdk/events.d.ts +0 -176
  119. package/dist/lib/platform/sdk/events.js +0 -261
  120. package/dist/lib/platform/sdk/gatewayFacades.d.ts +0 -586
  121. package/dist/lib/platform/sdk/gatewayFacades.js +0 -845
  122. package/dist/lib/platform/sdk/graphClient.d.ts +0 -266
  123. package/dist/lib/platform/sdk/graphClient.js +0 -235
  124. package/dist/lib/platform/sdk/harnessClient.d.ts +0 -309
  125. package/dist/lib/platform/sdk/harnessClient.js +0 -219
  126. package/dist/lib/platform/sdk/identityClient.d.ts +0 -134
  127. package/dist/lib/platform/sdk/identityClient.js +0 -131
  128. package/dist/lib/platform/sdk/index.js +0 -46
  129. package/dist/lib/platform/sdk/learningClient.d.ts +0 -40
  130. package/dist/lib/platform/sdk/learningClient.js +0 -53
  131. package/dist/lib/platform/sdk/mcpParityClient.d.ts +0 -69
  132. package/dist/lib/platform/sdk/mcpParityClient.js +0 -196
  133. package/dist/lib/platform/sdk/mcpParitySurface.d.ts +0 -10
  134. package/dist/lib/platform/sdk/mcpParitySurface.js +0 -57
  135. package/dist/lib/platform/sdk/ontologyClient.d.ts +0 -131
  136. package/dist/lib/platform/sdk/ontologyClient.js +0 -161
  137. package/dist/lib/platform/sdk/packRuntime.d.ts +0 -1
  138. package/dist/lib/platform/sdk/packRuntime.js +0 -1
  139. package/dist/lib/platform/sdk/packsClient.d.ts +0 -126
  140. package/dist/lib/platform/sdk/packsClient.js +0 -157
  141. package/dist/lib/platform/sdk/policyClient.d.ts +0 -293
  142. package/dist/lib/platform/sdk/policyClient.js +0 -277
  143. package/dist/lib/platform/sdk/promptCatalog.d.ts +0 -1
  144. package/dist/lib/platform/sdk/promptCatalog.js +0 -1
  145. package/dist/lib/platform/sdk/reportsClient.d.ts +0 -34
  146. package/dist/lib/platform/sdk/reportsClient.js +0 -64
  147. package/dist/lib/platform/sdk/schemaClient.d.ts +0 -59
  148. package/dist/lib/platform/sdk/schemaClient.js +0 -71
  149. package/dist/lib/platform/sdk/sdkSurface.d.ts +0 -56
  150. package/dist/lib/platform/sdk/sdkSurface.js +0 -140
  151. package/dist/lib/platform/sdk/topicsClient.d.ts +0 -78
  152. package/dist/lib/platform/sdk/topicsClient.js +0 -118
  153. package/dist/lib/platform/sdk/types.d.ts +0 -692
  154. package/dist/lib/platform/sdk/types.js +0 -1
  155. package/dist/lib/platform/sdk/version.d.ts +0 -2
  156. package/dist/lib/platform/sdk/workflowClient.d.ts +0 -313
  157. package/dist/lib/platform/sdk/workflowClient.js +0 -366
  158. package/dist/lucern/contracts/src/api-enums.contract.d.ts +0 -58
  159. package/dist/lucern/contracts/src/api-enums.contract.js +0 -147
  160. package/dist/lucern/contracts/src/lens-filter.contract.d.ts +0 -70
  161. package/dist/lucern/contracts/src/lens-filter.contract.js +0 -95
  162. package/dist/lucern/contracts/src/lens-workflow.contract.d.ts +0 -84
  163. package/dist/lucern/contracts/src/lens-workflow.contract.js +0 -54
  164. package/dist/lucern/contracts/src/mcp-tools.contract.d.ts +0 -151
  165. package/dist/lucern/contracts/src/mcp-tools.contract.js +0 -3281
  166. /package/{dist/lib/platform/sdk/version.js → src/version.ts} +0 -0
@@ -0,0 +1,789 @@
1
+ import {
2
+ createGatewayRequestClient,
3
+ type GatewayClientConfig,
4
+ type GatewayScope,
5
+ LucernApiError,
6
+ randomIdempotencyKey,
7
+ toQueryString,
8
+ } from "./coreClient";
9
+ import { createListResult, mapGatewayData } from "./sdkSurface";
10
+ import type { ControlObjectOwnershipContract } from "./controlObjectOwnership";
11
+ import type { JsonObject } from "./types";
12
+
13
+ export { LucernApiError };
14
+ export type { GatewayScope, PlatformGatewaySuccess } from "./coreClient";
15
+
16
+ /** Configuration for the admin client. */
17
+ export type AdminClientConfig = GatewayClientConfig;
18
+
19
+ export type TenantApiKeyRecord = {
20
+ id?: string;
21
+ tenantId?: string;
22
+ workspaceId?: string;
23
+ label?: string;
24
+ keyPrefix?: string;
25
+ hashedKey?: string;
26
+ scopes?: string[];
27
+ status?: string;
28
+ expiresAt?: number;
29
+ lastUsedAt?: number;
30
+ revokedAt?: number;
31
+ revokedBy?: string;
32
+ createdBy?: string;
33
+ createdAt?: number;
34
+ updatedAt?: number;
35
+ };
36
+
37
+ export type TenantVaultSecretRecord = {
38
+ id?: string;
39
+ tenantId?: string;
40
+ workspaceId?: string;
41
+ name?: string;
42
+ description?: string;
43
+ lastRotated?: number;
44
+ createdBy?: string;
45
+ updatedBy?: string;
46
+ createdAt?: number;
47
+ updatedAt?: number;
48
+ };
49
+
50
+ export type TenantAuthPolicyMode = "open" | "invite_only" | "sso_required";
51
+ export type TenantTopicVisibility = "private" | "tenant" | "public";
52
+ export type TenantFeatureFlags = Record<string, boolean>;
53
+ export type TenantModelSlotOverrides = Record<string, string>;
54
+
55
+ export type TenantConfigRecord = {
56
+ tenantId: string;
57
+ authPolicyMode: TenantAuthPolicyMode;
58
+ defaultSessionTTL: number;
59
+ defaultTopicVisibility: TenantTopicVisibility;
60
+ featureFlags: TenantFeatureFlags;
61
+ maxWorkspaceCount: number;
62
+ defaultModelSlotOverrides: TenantModelSlotOverrides;
63
+ updatedAt?: number;
64
+ updatedBy?: string;
65
+ };
66
+
67
+ export type TenantModelRoutingSlotRecord = {
68
+ slot: string;
69
+ category?: string;
70
+ description?: string;
71
+ modelKey: string;
72
+ promptName?: string;
73
+ temperature?: number;
74
+ maxTokens?: number;
75
+ enabled?: boolean;
76
+ };
77
+
78
+ export type TenantModelRoutingModelRecord = {
79
+ key: string;
80
+ name?: string;
81
+ modelId?: string;
82
+ provider?: string;
83
+ enabled?: boolean;
84
+ recommended?: boolean;
85
+ notes?: string;
86
+ };
87
+
88
+ export type TenantModelRoutingBindingRecord = {
89
+ slot: string;
90
+ providerId: string;
91
+ secretRef: string;
92
+ label?: string;
93
+ keyHint?: string;
94
+ };
95
+
96
+ export type TenantModelRouteOverrideStatus =
97
+ | "inherit"
98
+ | "active"
99
+ | "blocked_missing_model"
100
+ | "blocked_missing_binding";
101
+
102
+ export type TenantModelRouteBindingState = "ready" | "missing";
103
+ export type TenantModelRouteSource = "platform_default" | "tenant_override";
104
+
105
+ export type TenantModelRouteRow = {
106
+ slot: string;
107
+ category: string;
108
+ description?: string;
109
+ promptName?: string;
110
+ slotEnabled: boolean;
111
+ platformModelKey: string;
112
+ platformModelName?: string;
113
+ platformProviderId?: string;
114
+ overrideModelKey?: string;
115
+ overrideModelName?: string;
116
+ overrideProviderId?: string;
117
+ effectiveModelKey: string;
118
+ effectiveModelName?: string;
119
+ effectiveProviderId?: string;
120
+ effectiveSource: TenantModelRouteSource;
121
+ overrideStatus: TenantModelRouteOverrideStatus;
122
+ bindingState: TenantModelRouteBindingState;
123
+ bindingLabel?: string;
124
+ bindingKeyHint?: string;
125
+ bindingSecretRef?: string;
126
+ };
127
+
128
+ export type TenantModelRoutingSummary = {
129
+ totalSlots: number;
130
+ promptBoundSlots: number;
131
+ activeOverrides: number;
132
+ blockedOverrides: number;
133
+ readyBindings: number;
134
+ };
135
+
136
+ export type TenantModelRoutingSnapshot = {
137
+ tenantId: string;
138
+ defaultModelSlotOverrides: Record<string, string>;
139
+ slots: TenantModelRoutingSlotRecord[];
140
+ models: TenantModelRoutingModelRecord[];
141
+ bindings: TenantModelRoutingBindingRecord[];
142
+ rows: TenantModelRouteRow[];
143
+ summary: TenantModelRoutingSummary;
144
+ notes: string[];
145
+ };
146
+
147
+ function asTenantApiKeyRecord(data: unknown): TenantApiKeyRecord | null {
148
+ if (!data || typeof data !== "object") {
149
+ return null;
150
+ }
151
+ return data as TenantApiKeyRecord;
152
+ }
153
+
154
+ function asTenantApiKeyArray(data: unknown): TenantApiKeyRecord[] {
155
+ if (!Array.isArray(data)) {
156
+ return [];
157
+ }
158
+ return data
159
+ .map(asTenantApiKeyRecord)
160
+ .filter((row): row is TenantApiKeyRecord => Boolean(row));
161
+ }
162
+
163
+ function asTenantVaultSecretRecord(
164
+ data: unknown
165
+ ): TenantVaultSecretRecord | null {
166
+ if (!data || typeof data !== "object") {
167
+ return null;
168
+ }
169
+ return data as TenantVaultSecretRecord;
170
+ }
171
+
172
+ function asTenantVaultSecretArray(data: unknown): TenantVaultSecretRecord[] {
173
+ if (!Array.isArray(data)) {
174
+ return [];
175
+ }
176
+ return data
177
+ .map(asTenantVaultSecretRecord)
178
+ .filter((row): row is TenantVaultSecretRecord => Boolean(row));
179
+ }
180
+
181
+ /**
182
+ * Create the admin client for tenant, workspace, and membership administration.
183
+ * @param config - Gateway transport configuration.
184
+ * @returns An object with methods to manage tenants, workspaces, and memberships.
185
+ */
186
+ export function createAdminClient(config: AdminClientConfig = {}) {
187
+ const gateway = createGatewayRequestClient(config);
188
+
189
+ return {
190
+ /**
191
+ * List tenants visible to the current principal.
192
+ */
193
+ async listTenants(
194
+ query: {
195
+ status?: "active" | "disabled" | "archived";
196
+ limit?: number;
197
+ } = {}
198
+ ) {
199
+ return gateway.request<unknown>({
200
+ path: `/api/platform/v1/tenants${toQueryString(query)}`,
201
+ }).then((response) =>
202
+ mapGatewayData(response, (data) =>
203
+ createListResult(
204
+ Array.isArray(data) ? data : [],
205
+ "tenants"
206
+ )
207
+ )
208
+ );
209
+ },
210
+
211
+ /**
212
+ * Create a tenant.
213
+ */
214
+ async createTenant(
215
+ input: {
216
+ key: string;
217
+ slug?: string;
218
+ name: string;
219
+ status?: "active" | "disabled" | "archived";
220
+ metadata?: JsonObject;
221
+ },
222
+ idempotencyKey?: string
223
+ ) {
224
+ return gateway.request<unknown>({
225
+ path: "/api/platform/v1/tenants",
226
+ method: "POST",
227
+ body: input,
228
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
229
+ });
230
+ },
231
+
232
+ /**
233
+ * Get the control-object ownership contract.
234
+ */
235
+ async getControlObjectOwnership() {
236
+ return gateway.request<ControlObjectOwnershipContract>({
237
+ path: "/api/platform/v1/admin/control-ownership",
238
+ });
239
+ },
240
+
241
+ /**
242
+ * @deprecated Use getControlObjectOwnership.
243
+ */
244
+ async getControlObjectOwnershipContract() {
245
+ return gateway.request<ControlObjectOwnershipContract>({
246
+ path: "/api/platform/v1/admin/control-ownership",
247
+ });
248
+ },
249
+
250
+ /**
251
+ * List workspaces for the current admin scope.
252
+ */
253
+ async listWorkspaces(
254
+ query: GatewayScope & {
255
+ status?: "active" | "archived";
256
+ limit?: number;
257
+ } = {}
258
+ ) {
259
+ return gateway.request<unknown>({
260
+ path: `/api/platform/v1/workspaces${toQueryString(query)}`,
261
+ }).then((response) =>
262
+ mapGatewayData(response, (data) =>
263
+ createListResult(
264
+ Array.isArray(data) ? data : [],
265
+ "workspaces"
266
+ )
267
+ )
268
+ );
269
+ },
270
+
271
+ /**
272
+ * Create a workspace.
273
+ */
274
+ async createWorkspace(
275
+ input: GatewayScope & {
276
+ workspaceId?: string;
277
+ key?: string;
278
+ slug?: string;
279
+ name?: string;
280
+ status?: "active" | "archived";
281
+ defaultProjectVisibility?:
282
+ | "private"
283
+ | "team"
284
+ | "firm"
285
+ | "external"
286
+ | "public";
287
+ restore?: boolean;
288
+ metadata?: JsonObject;
289
+ },
290
+ idempotencyKey?: string
291
+ ) {
292
+ return gateway.request<unknown>({
293
+ path: "/api/platform/v1/workspaces",
294
+ method: "POST",
295
+ body: input,
296
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
297
+ });
298
+ },
299
+
300
+ /**
301
+ * List memberships for the current admin scope.
302
+ */
303
+ async listMemberships(
304
+ query: GatewayScope & {
305
+ principalId?: string;
306
+ status?: "active" | "revoked" | "expired";
307
+ limit?: number;
308
+ } = {}
309
+ ) {
310
+ return gateway.request<unknown>({
311
+ path: `/api/platform/v1/memberships${toQueryString(query)}`,
312
+ }).then((response) =>
313
+ mapGatewayData(response, (data) =>
314
+ createListResult(
315
+ Array.isArray(data) ? data : [],
316
+ "memberships"
317
+ )
318
+ )
319
+ );
320
+ },
321
+
322
+ /**
323
+ * Create a membership.
324
+ */
325
+ async createMembership(
326
+ input: GatewayScope & {
327
+ membershipId?: string;
328
+ principalId: string;
329
+ role:
330
+ | "platform_admin"
331
+ | "tenant_admin"
332
+ | "workspace_admin"
333
+ | "editor"
334
+ | "viewer"
335
+ | "auditor"
336
+ | "service_agent";
337
+ status?: "active" | "revoked" | "expired";
338
+ source?: "bootstrap" | "manual" | "sync" | "invitation";
339
+ },
340
+ idempotencyKey?: string
341
+ ) {
342
+ return gateway.request<unknown>({
343
+ path: "/api/platform/v1/memberships",
344
+ method: "POST",
345
+ body: input,
346
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
347
+ });
348
+ },
349
+
350
+ /**
351
+ * Update a membership.
352
+ */
353
+ async updateMembership(
354
+ input: GatewayScope & {
355
+ membershipId?: string;
356
+ principalId: string;
357
+ role:
358
+ | "platform_admin"
359
+ | "tenant_admin"
360
+ | "workspace_admin"
361
+ | "editor"
362
+ | "viewer"
363
+ | "auditor"
364
+ | "service_agent";
365
+ status?: "active" | "revoked" | "expired";
366
+ source?: "bootstrap" | "manual" | "sync" | "invitation";
367
+ },
368
+ idempotencyKey?: string
369
+ ) {
370
+ return this.createMembership(input, idempotencyKey);
371
+ },
372
+
373
+ /**
374
+ * @deprecated Use createMembership or updateMembership.
375
+ */
376
+ async upsertMembership(
377
+ input: GatewayScope & {
378
+ membershipId?: string;
379
+ principalId: string;
380
+ role:
381
+ | "platform_admin"
382
+ | "tenant_admin"
383
+ | "workspace_admin"
384
+ | "editor"
385
+ | "viewer"
386
+ | "auditor"
387
+ | "service_agent";
388
+ status?: "active" | "revoked" | "expired";
389
+ source?: "bootstrap" | "manual" | "sync" | "invitation";
390
+ },
391
+ idempotencyKey?: string
392
+ ) {
393
+ return this.createMembership(input, idempotencyKey);
394
+ },
395
+
396
+ /**
397
+ * List tenant API keys in the current admin scope.
398
+ */
399
+ async listTenantApiKeys(
400
+ scope: GatewayScope & {
401
+ status?: "active" | "revoked" | "expired";
402
+ }
403
+ ) {
404
+ const response = await gateway.request<{ keys?: unknown[] }>({
405
+ path: `/api/platform/v1/tenant-api-keys${toQueryString(scope)}`,
406
+ });
407
+
408
+ return {
409
+ ...response,
410
+ data: {
411
+ keys: asTenantApiKeyArray(response.data?.keys),
412
+ },
413
+ };
414
+ },
415
+
416
+ /**
417
+ * Create a tenant API key.
418
+ */
419
+ async createTenantApiKey(
420
+ input: GatewayScope & {
421
+ label?: string;
422
+ scopes: string[];
423
+ expiresAt?: number;
424
+ },
425
+ idempotencyKey?: string
426
+ ) {
427
+ const response = await gateway.request<{
428
+ key?: unknown;
429
+ plaintextKey?: string;
430
+ }>({
431
+ path: "/api/platform/v1/tenant-api-keys",
432
+ method: "POST",
433
+ body: input,
434
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
435
+ });
436
+
437
+ return {
438
+ ...response,
439
+ data: {
440
+ key: asTenantApiKeyRecord(response.data?.key),
441
+ plaintextKey:
442
+ typeof response.data?.plaintextKey === "string"
443
+ ? response.data.plaintextKey
444
+ : undefined,
445
+ },
446
+ };
447
+ },
448
+
449
+ /**
450
+ * Revoke a tenant API key.
451
+ */
452
+ async revokeTenantApiKey(
453
+ keyId: string,
454
+ input: GatewayScope & { reason?: string } = {},
455
+ idempotencyKey?: string
456
+ ) {
457
+ return gateway.request<unknown>({
458
+ path: `/api/platform/v1/tenant-api-keys/${encodeURIComponent(keyId)}/revoke`,
459
+ method: "POST",
460
+ body: input,
461
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
462
+ });
463
+ },
464
+
465
+ /**
466
+ * List tenant vault secrets.
467
+ */
468
+ async listTenantVaultSecrets(scope: GatewayScope) {
469
+ const response = await gateway.request<{ secrets?: unknown[] }>({
470
+ path: `/api/platform/v1/tenant-vault-secrets${toQueryString(scope)}`,
471
+ });
472
+
473
+ return {
474
+ ...response,
475
+ data: {
476
+ secrets: asTenantVaultSecretArray(response.data?.secrets),
477
+ },
478
+ };
479
+ },
480
+
481
+ /**
482
+ * Create a tenant vault secret.
483
+ */
484
+ async createTenantVaultSecret(
485
+ input: GatewayScope & {
486
+ name: string;
487
+ description?: string;
488
+ value: string;
489
+ },
490
+ idempotencyKey?: string
491
+ ) {
492
+ const response = await gateway.request<{ secret?: unknown }>({
493
+ path: "/api/platform/v1/tenant-vault-secrets",
494
+ method: "POST",
495
+ body: input,
496
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
497
+ });
498
+
499
+ return {
500
+ ...response,
501
+ data: {
502
+ secret: asTenantVaultSecretRecord(response.data?.secret),
503
+ },
504
+ };
505
+ },
506
+
507
+ /**
508
+ * Update a tenant vault secret.
509
+ */
510
+ async updateTenantVaultSecret(
511
+ secretId: string,
512
+ input: GatewayScope & {
513
+ name: string;
514
+ description?: string;
515
+ value?: string;
516
+ },
517
+ idempotencyKey?: string
518
+ ) {
519
+ const response = await gateway.request<{ secret?: unknown }>({
520
+ path: `/api/platform/v1/tenant-vault-secrets/${encodeURIComponent(secretId)}`,
521
+ method: "PATCH",
522
+ body: input,
523
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
524
+ });
525
+
526
+ return {
527
+ ...response,
528
+ data: {
529
+ secret: asTenantVaultSecretRecord(response.data?.secret),
530
+ },
531
+ };
532
+ },
533
+
534
+ /**
535
+ * Delete a tenant vault secret.
536
+ */
537
+ async deleteTenantVaultSecret(
538
+ secretId: string,
539
+ scope: GatewayScope,
540
+ idempotencyKey?: string
541
+ ) {
542
+ return gateway.request<unknown>({
543
+ path: `/api/platform/v1/tenant-vault-secrets/${encodeURIComponent(
544
+ secretId
545
+ )}${toQueryString(scope)}`,
546
+ method: "DELETE",
547
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
548
+ });
549
+ },
550
+
551
+ /**
552
+ * List tenant provider secrets.
553
+ */
554
+ async listTenantSecrets(
555
+ scope: GatewayScope & {
556
+ providerId?: string;
557
+ status?: "active" | "revoked";
558
+ }
559
+ ) {
560
+ return gateway.request<unknown>({
561
+ path: `/api/platform/v1/tenant-secrets${toQueryString(scope)}`,
562
+ });
563
+ },
564
+
565
+ /**
566
+ * Upsert a tenant provider secret.
567
+ */
568
+ async upsertTenantSecret(
569
+ input: GatewayScope & {
570
+ providerId: string;
571
+ apiKey: string;
572
+ label?: string;
573
+ modelSlotIds?: string[];
574
+ passThroughOnly?: boolean;
575
+ metadata?: JsonObject;
576
+ },
577
+ idempotencyKey?: string
578
+ ) {
579
+ return gateway.request<unknown>({
580
+ path: "/api/platform/v1/tenant-secrets",
581
+ method: "POST",
582
+ body: input,
583
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
584
+ });
585
+ },
586
+
587
+ /**
588
+ * Revoke a tenant provider secret.
589
+ */
590
+ async revokeTenantSecret(
591
+ secretRef: string,
592
+ input: GatewayScope & { reason?: string },
593
+ idempotencyKey?: string
594
+ ) {
595
+ return gateway.request<unknown>({
596
+ path: `/api/platform/v1/tenant-secrets/${encodeURIComponent(secretRef)}/revoke`,
597
+ method: "POST",
598
+ body: input,
599
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
600
+ });
601
+ },
602
+
603
+ /**
604
+ * Get tenant configuration.
605
+ */
606
+ async getTenantConfig(scope: GatewayScope & { tenantId: string }) {
607
+ return gateway.request<TenantConfigRecord>({
608
+ path: `/api/platform/v1/tenant-config${toQueryString(scope)}`,
609
+ });
610
+ },
611
+
612
+ /**
613
+ * Get tenant model routing.
614
+ */
615
+ async getTenantModelRouting(scope: GatewayScope & { tenantId: string }) {
616
+ return gateway.request<TenantModelRoutingSnapshot>({
617
+ path: `/api/platform/v1/tenant-config/model-routing${toQueryString(scope)}`,
618
+ });
619
+ },
620
+
621
+ /**
622
+ * Upsert tenant configuration.
623
+ */
624
+ async upsertTenantConfig(
625
+ input: GatewayScope & Omit<TenantConfigRecord, "updatedAt" | "updatedBy">,
626
+ idempotencyKey?: string
627
+ ) {
628
+ return gateway.request<TenantConfigRecord>({
629
+ path: "/api/platform/v1/tenant-config",
630
+ method: "POST",
631
+ body: input,
632
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
633
+ });
634
+ },
635
+
636
+ /**
637
+ * List groups.
638
+ */
639
+ async listGroups(scope: GatewayScope & { limit?: number } = {}) {
640
+ return gateway.request<unknown>({
641
+ path: `/api/platform/v1/groups${toQueryString(scope)}`,
642
+ });
643
+ },
644
+
645
+ /**
646
+ * Create a group.
647
+ */
648
+ async createGroup(
649
+ input: GatewayScope & {
650
+ name: string;
651
+ groupKey?: string;
652
+ groupType?: string;
653
+ description?: string;
654
+ },
655
+ idempotencyKey?: string
656
+ ) {
657
+ return gateway.request<unknown>({
658
+ path: "/api/platform/v1/groups",
659
+ method: "POST",
660
+ body: input,
661
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
662
+ });
663
+ },
664
+
665
+ /**
666
+ * Update a group.
667
+ */
668
+ async updateGroup(
669
+ groupId: string,
670
+ input: GatewayScope & {
671
+ name?: string;
672
+ description?: string;
673
+ workspaceId?: string;
674
+ clearWorkspaceId?: boolean;
675
+ },
676
+ idempotencyKey?: string
677
+ ) {
678
+ return gateway.request<unknown>({
679
+ path: `/api/platform/v1/groups/${encodeURIComponent(groupId)}`,
680
+ method: "PATCH",
681
+ body: input,
682
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
683
+ });
684
+ },
685
+
686
+ /**
687
+ * Delete a group.
688
+ */
689
+ async deleteGroup(
690
+ groupId: string,
691
+ input: GatewayScope = {},
692
+ idempotencyKey?: string
693
+ ) {
694
+ return gateway.request<unknown>({
695
+ path: `/api/platform/v1/groups/${encodeURIComponent(groupId)}${toQueryString(input)}`,
696
+ method: "DELETE",
697
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
698
+ });
699
+ },
700
+
701
+ /**
702
+ * List group members.
703
+ */
704
+ async listGroupMembers(query: GatewayScope & { groupId: string }) {
705
+ return gateway.request<unknown>({
706
+ path: `/api/platform/v1/groups/members${toQueryString(query)}`,
707
+ });
708
+ },
709
+
710
+ /**
711
+ * Add a group member.
712
+ */
713
+ async addGroupMember(
714
+ input: GatewayScope & {
715
+ groupId: string;
716
+ principalId: string;
717
+ },
718
+ idempotencyKey?: string
719
+ ) {
720
+ return gateway.request<unknown>({
721
+ path: "/api/platform/v1/groups/members",
722
+ method: "POST",
723
+ body: input,
724
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
725
+ });
726
+ },
727
+
728
+ /**
729
+ * Remove a group member.
730
+ */
731
+ async removeGroupMember(
732
+ input: GatewayScope & { groupId: string; principalId: string },
733
+ idempotencyKey?: string
734
+ ) {
735
+ return gateway.request<unknown>({
736
+ path: `/api/platform/v1/groups/members${toQueryString(input)}`,
737
+ method: "DELETE",
738
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
739
+ });
740
+ },
741
+
742
+ /**
743
+ * List pack-to-group assignments.
744
+ */
745
+ async listPackGroupAssignments(
746
+ query: GatewayScope & {
747
+ groupId?: string;
748
+ status?: string;
749
+ } = {}
750
+ ) {
751
+ return gateway.request<unknown>({
752
+ path: `/api/platform/v1/groups/packs${toQueryString(query)}`,
753
+ });
754
+ },
755
+
756
+ /**
757
+ * Assign a pack to a group.
758
+ */
759
+ async assignPackToGroup(
760
+ input: GatewayScope & {
761
+ groupId: string;
762
+ packKey: string;
763
+ packVersion?: string;
764
+ },
765
+ idempotencyKey?: string
766
+ ) {
767
+ return gateway.request<unknown>({
768
+ path: "/api/platform/v1/groups/packs",
769
+ method: "POST",
770
+ body: input,
771
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
772
+ });
773
+ },
774
+
775
+ /**
776
+ * Remove a pack from a group.
777
+ */
778
+ async removePackFromGroup(
779
+ input: GatewayScope & { groupId: string; packKey: string },
780
+ idempotencyKey?: string
781
+ ) {
782
+ return gateway.request<unknown>({
783
+ path: `/api/platform/v1/groups/packs${toQueryString(input)}`,
784
+ method: "DELETE",
785
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
786
+ });
787
+ },
788
+ };
789
+ }