@opengeni/sdk 0.57.0 → 2.2.0-canary.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 (94) hide show
  1. package/README.md +123 -2
  2. package/dist/artifacts.js +5 -5
  3. package/dist/automations-client.d.ts +17 -0
  4. package/dist/automations.d.ts +3 -0
  5. package/dist/automations.js +78 -0
  6. package/dist/automations.js.map +1 -0
  7. package/dist/{chunk-JDLDDRNE.js → chunk-C2H7HBNP.js} +290 -33
  8. package/dist/chunk-C2H7HBNP.js.map +1 -0
  9. package/dist/{chunk-GU6JF75T.js → chunk-C4DJPZRU.js} +1 -1
  10. package/dist/{chunk-GU6JF75T.js.map → chunk-C4DJPZRU.js.map} +1 -1
  11. package/dist/{chunk-JRPFWI6T.js → chunk-G6LBVWKT.js} +2 -2
  12. package/dist/{chunk-HJ3HHUT5.js → chunk-GLDV5QY7.js} +16 -2
  13. package/dist/chunk-GLDV5QY7.js.map +1 -0
  14. package/dist/{chunk-ST5DDKJP.js → chunk-GW3EJ2GP.js} +52 -1
  15. package/dist/chunk-GW3EJ2GP.js.map +1 -0
  16. package/dist/{chunk-VWE2QIVO.js → chunk-XNG7YGR3.js} +23 -6
  17. package/dist/chunk-XNG7YGR3.js.map +1 -0
  18. package/dist/{chunk-PKQ377ED.js → chunk-YBQTKNTL.js} +696 -57
  19. package/dist/chunk-YBQTKNTL.js.map +1 -0
  20. package/dist/client.d.ts +151 -26
  21. package/dist/codex-realtime-controller.d.ts +3 -0
  22. package/dist/codex-realtime-controller.js +2 -2
  23. package/dist/codex-realtime-v3.d.ts +13 -2
  24. package/dist/company-brain.d.ts +32 -0
  25. package/dist/company-profile.d.ts +1 -1
  26. package/dist/core.js +4 -4
  27. package/dist/editable-artifacts/browser-session.d.ts +7 -3
  28. package/dist/editable-artifacts/controller.d.ts +4 -1
  29. package/dist/editable-artifacts/errors.d.ts +1 -1
  30. package/dist/editable-artifacts/http-live-transport.d.ts +6 -2
  31. package/dist/editable-artifacts/index.d.ts +2 -0
  32. package/dist/editable-artifacts/open-failure.d.ts +9 -0
  33. package/dist/editable-artifacts/types.d.ts +4 -3
  34. package/dist/editable-artifacts/worker/kernel-adapter.d.ts +1 -1
  35. package/dist/editable-artifacts-worker.js +44 -17
  36. package/dist/editable-artifacts-worker.js.map +1 -1
  37. package/dist/editable-artifacts.js +222 -119
  38. package/dist/editable-artifacts.js.map +1 -1
  39. package/dist/errors.d.ts +1 -1
  40. package/dist/index.d.ts +7 -4
  41. package/dist/index.js +61 -12
  42. package/dist/index.js.map +1 -1
  43. package/dist/interaction.d.ts +23 -0
  44. package/dist/interaction.js +4 -1
  45. package/dist/organization-private-session-settings.d.ts +6 -0
  46. package/dist/organization-private-session-settings.js +22 -0
  47. package/dist/organization-private-session-settings.js.map +1 -0
  48. package/dist/pr-review-client.d.ts +15 -0
  49. package/dist/pr-review.d.ts +4 -0
  50. package/dist/pr-review.js +56 -0
  51. package/dist/pr-review.js.map +1 -0
  52. package/dist/preference-registry.d.ts +8 -0
  53. package/dist/realtime.js +2 -2
  54. package/dist/retained-artifacts.d.ts +5 -1
  55. package/dist/types.d.ts +976 -17
  56. package/dist/workspace-instruction-policies.d.ts +22 -0
  57. package/dist/workspace-learning.d.ts +124 -0
  58. package/package.json +14 -2
  59. package/src/automations-client.ts +118 -0
  60. package/src/automations.ts +15 -0
  61. package/src/client.ts +974 -71
  62. package/src/codex-realtime-controller.ts +235 -5
  63. package/src/codex-realtime-v3.ts +162 -31
  64. package/src/company-brain.ts +99 -0
  65. package/src/company-profile.ts +4 -1
  66. package/src/editable-artifacts/browser-session.ts +36 -22
  67. package/src/editable-artifacts/controller.ts +66 -45
  68. package/src/editable-artifacts/errors.ts +2 -0
  69. package/src/editable-artifacts/http-live-transport.ts +62 -37
  70. package/src/editable-artifacts/index.ts +6 -0
  71. package/src/editable-artifacts/open-failure.ts +79 -0
  72. package/src/editable-artifacts/storage.ts +31 -40
  73. package/src/editable-artifacts/types.ts +4 -3
  74. package/src/editable-artifacts/worker/kernel-adapter.ts +23 -7
  75. package/src/editable-artifacts/worker/runtime.ts +26 -13
  76. package/src/editable-artifacts/worker/wire-codec.ts +23 -5
  77. package/src/errors.ts +1 -1
  78. package/src/index.ts +131 -0
  79. package/src/interaction.ts +95 -0
  80. package/src/organization-private-session-settings.ts +33 -0
  81. package/src/pr-review-client.ts +84 -0
  82. package/src/pr-review.ts +15 -0
  83. package/src/preference-registry.ts +9 -0
  84. package/src/retained-artifacts.ts +101 -0
  85. package/src/stream.ts +13 -2
  86. package/src/types.ts +1117 -16
  87. package/src/workspace-instruction-policies.ts +24 -0
  88. package/src/workspace-learning.ts +138 -0
  89. package/dist/chunk-HJ3HHUT5.js.map +0 -1
  90. package/dist/chunk-JDLDDRNE.js.map +0 -1
  91. package/dist/chunk-PKQ377ED.js.map +0 -1
  92. package/dist/chunk-ST5DDKJP.js.map +0 -1
  93. package/dist/chunk-VWE2QIVO.js.map +0 -1
  94. /package/dist/{chunk-JRPFWI6T.js.map → chunk-G6LBVWKT.js.map} +0 -0
package/src/client.ts CHANGED
@@ -163,14 +163,31 @@ import type {
163
163
  UninstallPluginResult,
164
164
  AddDocumentRequest,
165
165
  CreateKnowledgeDropRequest,
166
+ DocumentAuthorityReclassification,
167
+ DocumentDefaultCollectionBackfill,
168
+ ListDocumentAuthorityReclassificationsOptions,
169
+ ListDocumentAuthorityReclassificationsResponse,
166
170
  MoveDocumentRequest,
171
+ ReclassifyDocumentAuthorityRequest,
172
+ RunDocumentDefaultCollectionBackfillRequest,
167
173
  ClientConfig,
174
+ WorkspaceModelAccessPolicy,
168
175
  WorkspaceModelCatalogResponse,
169
176
  WorkspaceRealtimeModelCatalogResponse,
170
177
  ClientSessionEventInput,
178
+ UserMessageEventInput,
171
179
  CompactSessionContextResult,
172
180
  CompleteFileUploadResponse,
173
181
  ConnectionMetadata,
182
+ PersonalGitHubConnectionStatusResponse,
183
+ PersonalGitHubDisconnectRequest,
184
+ PersonalGitHubOAuthStartRequest,
185
+ PersonalGitHubOAuthStartResponse,
186
+ ListPersonalGitHubRepositoriesOptions,
187
+ ListPersonalGitHubRepositoriesResponse,
188
+ PersonalGitHubRepositorySelectionState,
189
+ ReplacePersonalGitHubRepositorySelectionsRequest,
190
+ VerifyPersonalGitHubRepositorySelectionsRequest,
174
191
  CreateApiKeyRequest,
175
192
  CreateApiKeyResponse,
176
193
  CreateCapabilityCatalogItemRequest,
@@ -178,6 +195,8 @@ import type {
178
195
  InstallLibrarySkillRequest,
179
196
  InstalledSkill,
180
197
  ListInstalledSkillsResponse,
198
+ CreateBillingPortalRequest,
199
+ CreateBillingPortalResponse,
181
200
  CreateCheckoutRequest,
182
201
  CreateCheckoutResponse,
183
202
  OpenGeniSlackBotInstallRequest,
@@ -201,6 +220,7 @@ import type {
201
220
  CreateWorkspaceRequest,
202
221
  // Enrollment UX (design 11): the click-Grant approve-page lookup/deny + headless
203
222
  // enroll-token mint.
223
+ DeviceEnrollmentApproveRequest,
204
224
  DeviceEnrollmentApproveResponse,
205
225
  DeviceEnrollmentDenyResponse,
206
226
  DeviceEnrollmentLookupResponse,
@@ -226,6 +246,29 @@ import type {
226
246
  KnowledgeMemorySearchRequest,
227
247
  ListApiKeysResponse,
228
248
  ListManagedOrganizationMembershipsResponse,
249
+ ListUserResourceAuthoritiesOptions,
250
+ ListUserResourceAuthoritiesResponse,
251
+ IssueUserResourceGrantRequest,
252
+ UserResourceGrantMutationResponse,
253
+ RevokeUserResourceGrantResponse,
254
+ ListOrganizationInvitationsPageResponse,
255
+ ListOrganizationMembersResponse,
256
+ AcceptOrganizationInvitationRequest,
257
+ AcceptOrganizationInvitationResponse,
258
+ AddOrganizationWorkspaceMemberRequest,
259
+ CreateOrganizationInvitationRequest,
260
+ CreateOrganizationRequest,
261
+ CreateOrganizationResponse,
262
+ CreateOrganizationWorkspaceRequest,
263
+ OrganizationInvitation,
264
+ OrganizationAdministrationOverview,
265
+ OrganizationMember,
266
+ OrganizationRetentionPolicy,
267
+ OrganizationSummary,
268
+ RevokeOrganizationInvitationRequest,
269
+ UpdateOrganizationMemberRequest,
270
+ UpdateOrganizationNameRequest,
271
+ UpdateOrganizationRetentionPolicyRequest,
229
272
  ListPacksResponse,
230
273
  // Bring-your-own-compute: the Machines dashboard + per-machine metrics (M10).
231
274
  MachinesResponse,
@@ -233,6 +276,9 @@ import type {
233
276
  MachineMetricsSeriesResponse,
234
277
  RemoveEnrollmentRequest,
235
278
  RemoveEnrollmentResponse,
279
+ MachineOperationPolicy,
280
+ UpdateMachineOperationPolicyRequest,
281
+ UpdateMachineAgentResponse,
236
282
  // Bring-your-own-compute: the user-authenticated active-sandbox swap (M7).
237
283
  SwapActiveSandboxRequest,
238
284
  SwapActiveSandboxResponse,
@@ -246,8 +292,6 @@ import type {
246
292
  ApproveSlackUserLinkAccessRequest,
247
293
  PackInstallation,
248
294
  PackUninstallPreview,
249
- LatencyMode,
250
- ReasoningEffort,
251
295
  RetainedScreenshotDownload,
252
296
  RetainedScreenshotDownloadOptions,
253
297
  RetainedArtifactDownload,
@@ -262,16 +306,24 @@ import type {
262
306
  VideoGenerationPolicy,
263
307
  WorkspaceVideoGenerationSettings,
264
308
  RegisterCapabilityPackRequest,
265
- ResourceRef,
266
309
  PreviewPackInstallationRequest,
267
310
  PreviewSkillImportRequest,
268
311
  ScheduledTask,
269
312
  ScheduledTaskRun,
313
+ ForkSessionRequest,
314
+ ForkSessionResponse,
270
315
  Session,
316
+ SessionBackgroundCommandListResponse,
317
+ CancelSessionBackgroundCommandResult,
271
318
  SessionListResponse,
319
+ SessionTenancyCreateCapabilities,
272
320
  AgentTopologyPageResponse,
273
321
  UpdateSessionChannelRequest,
322
+ UpdateSessionAttentionRequest,
323
+ UpdateSessionArchiveRequest,
274
324
  UpdateSessionPinRequest,
325
+ UpdateSessionVisibilityRequest,
326
+ UpdateSessionVisibilityResponse,
275
327
  UninstallPackRequest,
276
328
  UninstallPackResult,
277
329
  SessionEvent,
@@ -281,24 +333,31 @@ import type {
281
333
  SessionEventPage,
282
334
  SessionGoal,
283
335
  SessionGoalRevision,
336
+ ListSessionGoalRevisionsOptions,
337
+ ListSessionGoalRevisionsResponse,
338
+ RejectSessionGoalRevisionRequest,
339
+ RejectSessionGoalRevisionResponse,
340
+ RollbackSessionGoalRevisionRequest,
284
341
  SessionHumanInputRequest,
285
342
  SessionLineageResponse,
286
343
  SessionRealtimeMutationResponse,
287
344
  SyncSessionRealtimeLedgerRequest,
288
345
  SyncSessionRealtimeLedgerResponse,
289
346
  RenewSessionRealtimeRequest,
290
- SessionMcpCredentialUpdateInput,
291
- SubmittedTimelineAnnotation,
292
347
  UpdateSessionMcpApprovalPolicyRequest,
293
348
  UpdateSessionMcpApprovalPolicyResponse,
294
349
  SessionQueueSnapshot,
295
350
  SessionQueueMutationResponse,
351
+ SessionCommandReceipt,
352
+ SessionPromptRouting,
296
353
  ComposerDraft,
297
354
  DeleteSessionQueueItemRequest,
298
355
  EditSessionQueueItemRequest,
299
356
  MoveSessionQueueItemRequest,
300
357
  NewSessionDraft,
301
358
  SaveComposerDraftRequest,
359
+ SubmitComposerDraftRequest,
360
+ SubmitComposerDraftResponse,
302
361
  SaveNewSessionDraftRequest,
303
362
  SteerSessionQueueItemRequest,
304
363
  SessionControlResponse,
@@ -321,6 +380,8 @@ import type {
321
380
  FsListBatchResponse,
322
381
  FsReadRequest,
323
382
  FsReadResponse,
383
+ PublishSandboxFileArtifactRequest,
384
+ SandboxFileArtifactReceipt,
324
385
  FsWriteRequest,
325
386
  FsWriteResponse,
326
387
  FsDeleteRequest,
@@ -349,7 +410,6 @@ import type {
349
410
  PtyWriteRequest,
350
411
  PtyResizeRequest,
351
412
  PtyCloseRequest,
352
- ToolRef,
353
413
  TranscribeAudioResponse,
354
414
  TranscriptionRecordingListResponse,
355
415
  TranscriptionRecordingResponse,
@@ -364,6 +424,7 @@ import type {
364
424
  UpdateVariableSetRequest,
365
425
  UpdateRigRequest,
366
426
  UpdateWorkspaceMemberRequest,
427
+ UpdateWorkspaceModelAccessPolicyRequest,
367
428
  UpdateWorkspaceRequest,
368
429
  UpdateWorkspaceSettingsRequest,
369
430
  SetWorkspaceDefaultRigRequest,
@@ -373,6 +434,7 @@ import type {
373
434
  VariableSetVariableMetadata,
374
435
  Channel,
375
436
  CreateChannelRequest,
437
+ ReorderChannelsRequest,
376
438
  UpdateChannelRequest,
377
439
  Rig,
378
440
  RigVersion,
@@ -397,7 +459,10 @@ import type {
397
459
  UninstallSkillResult,
398
460
  } from "./types";
399
461
  import { GENERATED_VIDEO_MAX_BYTES } from "./types";
400
- import { parseRetainedGeneratedImageReference } from "./retained-artifacts";
462
+ import {
463
+ parseRetainedGeneratedImageReference,
464
+ parseRetainedWorkspaceFileReference,
465
+ } from "./retained-artifacts";
401
466
  import type {
402
467
  ActivateWorkspaceInstructionPolicyRequest,
403
468
  CreateWorkspaceInstructionPolicyDraftRequest,
@@ -414,6 +479,16 @@ import type {
414
479
  WorkspaceInstructionPolicyOnboardingProposalListResponse,
415
480
  WorkspaceInstructionPolicyRevision,
416
481
  } from "./workspace-instruction-policies";
482
+ import type {
483
+ ActivateWorkspaceLearningPolicyRevisionRequest,
484
+ CreateWorkspaceLearningPolicyRevisionRequest,
485
+ GovernedLearningActivationUndoReceipt,
486
+ RollbackWorkspaceLearningPolicyRevisionRequest,
487
+ WorkspaceLearningHistoryOptions,
488
+ WorkspaceLearningHistoryResponse,
489
+ WorkspaceLearningPolicyMutationResponse,
490
+ WorkspaceLearningPolicyRevision,
491
+ } from "./workspace-learning";
417
492
  import type {
418
493
  ActivateCompanyProfileRevisionRequest,
419
494
  CompanyProfileDiffRequest,
@@ -430,6 +505,7 @@ import type {
430
505
  WorkspaceStateGetOptions,
431
506
  WorkspaceStateResponse,
432
507
  } from "./workspace-state";
508
+ import type { CompanyBrainOkfDownload, CompanyBrainOkfPackage } from "./company-brain";
433
509
  import type {
434
510
  ActivatePreferenceRegistryRevisionRequest,
435
511
  ChangePreferenceRegistryScopeRequest,
@@ -483,38 +559,42 @@ export type OpenGeniClientOptions = {
483
559
  headers?: Record<string, string> | (() => Record<string, string>);
484
560
  /** Custom fetch implementation. Defaults to the global `fetch`. */
485
561
  fetch?: FetchLike;
562
+ /** Positive deadline for interactive session commands. Defaults to 15 seconds. */
563
+ sessionCommandTimeoutMs?: number;
486
564
  };
487
565
 
488
566
  /** Per-request cancellation for operations whose caller owns an AbortSignal. */
489
567
  export type OpenGeniRequestOptions = {
490
568
  signal?: AbortSignal | undefined;
569
+ timeoutMs?: number | undefined;
491
570
  };
492
571
 
493
- export type SendMessageInput = {
494
- text: string;
495
- annotations?: SubmittedTimelineAnnotation[];
496
- /** System instructions scoped to this exact turn; never visible timeline text. */
497
- turnInstructions?: string;
498
- resources?: ResourceRef[];
499
- tools?: ToolRef[];
500
- model?: string;
501
- reasoningEffort?: ReasoningEffort;
502
- latencyMode?: LatencyMode;
572
+ /** Follow-up prompt fields accepted by both queue and Steer. Session tools are updated separately. */
573
+ export type SendMessageInput = UserMessageEventInput["payload"] & {
503
574
  clientEventId?: string;
504
- controlEtag?: string;
505
- expectedDraftRevision?: number;
506
- mcpCredentialUpdates?: SessionMcpCredentialUpdateInput[];
507
575
  };
508
576
 
577
+ function assertNoMessageTools(input: object): void {
578
+ if (Object.prototype.hasOwnProperty.call(input, "tools")) {
579
+ throw new TypeError(
580
+ "Message-level tools are not supported; update the session tool policy before sending.",
581
+ );
582
+ }
583
+ }
584
+
509
585
  export type SteerMessageResult = {
510
586
  /** The accepted `user.message` event. */
511
587
  accepted: SessionEvent;
512
588
  /** The exact turn created for this message in the same server transaction. */
513
589
  turn: SessionTurn;
590
+ /** Durable proof that this exact operation committed. */
591
+ receipt: SessionCommandReceipt;
592
+ /** Server-owned destination at admission time. */
593
+ routing: SessionPromptRouting;
514
594
  /** Number of live attempts durably asked to stop by this atomic Steer. */
515
- interruptionCount?: number;
595
+ interruptionCount: number;
516
596
  /** True when this response came from the command's immutable idempotency receipt. */
517
- replay?: boolean;
597
+ replay: boolean;
518
598
  };
519
599
 
520
600
  export type TranscribeAudioInput = {
@@ -555,6 +635,7 @@ export class OpenGeniClient {
555
635
  private readonly baseUrl: string;
556
636
  private readonly options: OpenGeniClientOptions;
557
637
  private readonly fetchImpl: FetchLike;
638
+ private readonly sessionCommandTimeoutMs: number;
558
639
  private readonly readInFlight = new Map<string, Promise<unknown>>();
559
640
  private readonly readTrailing = new Map<string, Promise<unknown>>();
560
641
  /** Resource-oriented Browser/Computer facade over this exact authenticated client. */
@@ -565,6 +646,11 @@ export class OpenGeniClient {
565
646
  this.options = options;
566
647
  // Bind lazily so variable sets that polyfill fetch after module load work.
567
648
  this.fetchImpl = options.fetch ?? ((input, init) => fetch(input, init));
649
+ const sessionCommandTimeoutMs = options.sessionCommandTimeoutMs ?? 15_000;
650
+ if (!Number.isFinite(sessionCommandTimeoutMs) || sessionCommandTimeoutMs <= 0) {
651
+ throw new RangeError("sessionCommandTimeoutMs must be a finite positive number");
652
+ }
653
+ this.sessionCommandTimeoutMs = sessionCommandTimeoutMs;
568
654
  this.interaction = new OpenGeniInteractionClient(this);
569
655
  }
570
656
 
@@ -836,6 +922,42 @@ export class OpenGeniClient {
836
922
  );
837
923
  }
838
924
 
925
+ /** Whether this exact authenticated principal may atomically create a private session. */
926
+ async getSessionTenancyCreateCapabilities(
927
+ workspaceId: string,
928
+ ): Promise<SessionTenancyCreateCapabilities> {
929
+ return await this.requestJson<SessionTenancyCreateCapabilities>(
930
+ "GET",
931
+ `/v1/workspaces/${workspaceId}/session-tenancy/capabilities`,
932
+ );
933
+ }
934
+
935
+ /** Change an owned, fully quiescent session between private and workspace visibility. */
936
+ async updateSessionVisibility(
937
+ workspaceId: string,
938
+ sessionId: string,
939
+ request: UpdateSessionVisibilityRequest,
940
+ ): Promise<UpdateSessionVisibilityResponse> {
941
+ return await this.requestJson<UpdateSessionVisibilityResponse>(
942
+ "PUT",
943
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/visibility`,
944
+ request,
945
+ );
946
+ }
947
+
948
+ /** Create an independent same-workspace fork with explicit destination visibility. */
949
+ async forkSession(
950
+ workspaceId: string,
951
+ sessionId: string,
952
+ request: ForkSessionRequest,
953
+ ): Promise<ForkSessionResponse> {
954
+ return await this.requestJson<ForkSessionResponse>(
955
+ "POST",
956
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/forks`,
957
+ request,
958
+ );
959
+ }
960
+
839
961
  /** Replace the durable tool policy or explicitly adopt workspace defaults. */
840
962
  async updateSessionToolPolicy(
841
963
  workspaceId: string,
@@ -893,6 +1015,27 @@ export class OpenGeniClient {
893
1015
  );
894
1016
  }
895
1017
 
1018
+ async listSessionBackgroundCommands(
1019
+ workspaceId: string,
1020
+ sessionId: string,
1021
+ ): Promise<SessionBackgroundCommandListResponse> {
1022
+ return await this.requestJson<SessionBackgroundCommandListResponse>(
1023
+ "GET",
1024
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/background-commands`,
1025
+ );
1026
+ }
1027
+
1028
+ async cancelSessionBackgroundCommand(
1029
+ workspaceId: string,
1030
+ sessionId: string,
1031
+ commandId: string,
1032
+ ): Promise<CancelSessionBackgroundCommandResult> {
1033
+ return await this.requestJson<CancelSessionBackgroundCommandResult>(
1034
+ "DELETE",
1035
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/background-commands/${commandId}`,
1036
+ );
1037
+ }
1038
+
896
1039
  /** Pin-aware ordinary-session page with a stable keyset cursor. */
897
1040
  async listSessionPage(
898
1041
  workspaceId: string,
@@ -903,6 +1046,8 @@ export class OpenGeniClient {
903
1046
  search?: string;
904
1047
  /** Return only the complete personal pinned projection. */
905
1048
  pinsOnly?: boolean;
1049
+ /** Return archived root chats instead of the active session list. */
1050
+ archivedOnly?: boolean;
906
1051
  } = {},
907
1052
  ): Promise<SessionListResponse> {
908
1053
  const search = options.search?.trim();
@@ -918,6 +1063,7 @@ export class OpenGeniClient {
918
1063
  ...(options.cursor !== undefined ? { cursor: options.cursor } : {}),
919
1064
  ...(search ? { search } : {}),
920
1065
  ...(options.pinsOnly ? { pinsOnly: "true" } : {}),
1066
+ ...(options.archivedOnly ? { archivedOnly: "true" } : {}),
921
1067
  },
922
1068
  );
923
1069
  } catch (error) {
@@ -949,6 +1095,9 @@ export class OpenGeniClient {
949
1095
  if (options.pinsOnly) {
950
1096
  throw new Error("The connected OpenGeni API does not support pins-only session lists");
951
1097
  }
1098
+ if (options.archivedOnly) {
1099
+ throw new Error("The connected OpenGeni API does not support archived session lists");
1100
+ }
952
1101
  return { pinned: [], sessions: response, nextCursor: null };
953
1102
  }
954
1103
  return response;
@@ -993,6 +1142,43 @@ export class OpenGeniClient {
993
1142
  );
994
1143
  }
995
1144
 
1145
+ /** Set this authenticated member's explicit read/actively-working state. */
1146
+ async updateSessionAttention(
1147
+ workspaceId: string,
1148
+ sessionId: string,
1149
+ request: UpdateSessionAttentionRequest,
1150
+ ): Promise<Session> {
1151
+ return await this.requestJson<Session>(
1152
+ "PUT",
1153
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/attention`,
1154
+ request,
1155
+ );
1156
+ }
1157
+
1158
+ /** Archive or restore this authenticated member's root chat. */
1159
+ async updateSessionArchive(
1160
+ workspaceId: string,
1161
+ sessionId: string,
1162
+ request: UpdateSessionArchiveRequest,
1163
+ ): Promise<Session> {
1164
+ return await this.requestJson<Session>(
1165
+ "PUT",
1166
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/archive`,
1167
+ request,
1168
+ );
1169
+ }
1170
+
1171
+ /** Permanently delete one quiescent root session and its full descendant tree. */
1172
+ async deleteSession(
1173
+ workspaceId: string,
1174
+ sessionId: string,
1175
+ ): Promise<{ deletedSessionCount: number }> {
1176
+ return await this.requestJson<{ deletedSessionCount: number }>(
1177
+ "DELETE",
1178
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}`,
1179
+ );
1180
+ }
1181
+
996
1182
  async getSessionLineage(workspaceId: string, sessionId: string): Promise<SessionLineageResponse> {
997
1183
  const path = `/v1/workspaces/${workspaceId}/sessions/${sessionId}/lineage`;
998
1184
  return await this.singleFlightRead(path, () =>
@@ -1196,6 +1382,33 @@ export class OpenGeniClient {
1196
1382
  );
1197
1383
  }
1198
1384
 
1385
+ /** Ask one authoritative Connected Machine runner to drain accepted work and
1386
+ * install the exact signed version promoted for its channel. Progress is read
1387
+ * from `listMachines`; completion requires the successor build identity. */
1388
+ async updateMachineAgent(
1389
+ workspaceId: string,
1390
+ enrollmentId: string,
1391
+ ): Promise<UpdateMachineAgentResponse> {
1392
+ return await this.requestJson<UpdateMachineAgentResponse>(
1393
+ "POST",
1394
+ `/v1/workspaces/${workspaceId}/machines/${enrollmentId}/update`,
1395
+ );
1396
+ }
1397
+
1398
+ /** Revision-fenced update of a Connected Machine's optional command memory
1399
+ * policy. Null byte limits preserve unrestricted machine access. */
1400
+ async updateMachineOperationPolicy(
1401
+ workspaceId: string,
1402
+ enrollmentId: string,
1403
+ request: UpdateMachineOperationPolicyRequest,
1404
+ ): Promise<MachineOperationPolicy> {
1405
+ return await this.requestJson<MachineOperationPolicy>(
1406
+ "PATCH",
1407
+ `/v1/workspaces/${workspaceId}/machines/${enrollmentId}/operation-policy`,
1408
+ request,
1409
+ );
1410
+ }
1411
+
1199
1412
  /**
1200
1413
  * Read the downsampled (~1/min) metrics series for ONE machine over a time
1201
1414
  * window (default 1h). The samples are oldest-first (a left-to-right chart).
@@ -1217,8 +1430,9 @@ export class OpenGeniClient {
1217
1430
  /**
1218
1431
  * Remove one connected self-hosted machine enrollment. The control-plane
1219
1432
  * operation works while the agent is offline, revokes future reconnects,
1220
- * retains history, and returns a typed blocker when active route/lease or
1221
- * recovery dependencies make removal unsafe. `idempotencyKey` is replay-safe.
1433
+ * retains history, and atomically detaches idle dependent sessions (a
1434
+ * machine-home session becomes `backend:none`). Active turns, live leases,
1435
+ * and recovery work remain typed blockers. `idempotencyKey` is replay-safe.
1222
1436
  */
1223
1437
  async removeEnrollment(
1224
1438
  workspaceId: string,
@@ -1258,7 +1472,7 @@ export class OpenGeniClient {
1258
1472
  */
1259
1473
  async approveDeviceEnrollment(
1260
1474
  workspaceId: string,
1261
- request: { userCode: string; allowScreenControl?: boolean },
1475
+ request: DeviceEnrollmentApproveRequest,
1262
1476
  ): Promise<DeviceEnrollmentApproveResponse> {
1263
1477
  return await this.requestJson<DeviceEnrollmentApproveResponse>(
1264
1478
  "POST",
@@ -1266,6 +1480,7 @@ export class OpenGeniClient {
1266
1480
  {
1267
1481
  userCode: request.userCode,
1268
1482
  allowScreenControl: request.allowScreenControl ?? false,
1483
+ ...(request.scope ? { scope: request.scope } : {}),
1269
1484
  },
1270
1485
  );
1271
1486
  }
@@ -1498,7 +1713,7 @@ export class OpenGeniClient {
1498
1713
  sessionId: string,
1499
1714
  event: ClientSessionEventInput,
1500
1715
  ): Promise<SessionEvent> {
1501
- return await this.requestJson<SessionEvent>(
1716
+ return await this.requestSessionCommand<SessionEvent>(
1502
1717
  "POST",
1503
1718
  `/v1/workspaces/${workspaceId}/sessions/${sessionId}/events`,
1504
1719
  event,
@@ -1511,6 +1726,7 @@ export class OpenGeniClient {
1511
1726
  message: string | SendMessageInput,
1512
1727
  ): Promise<SessionEvent> {
1513
1728
  const input = typeof message === "string" ? { text: message } : message;
1729
+ assertNoMessageTools(input);
1514
1730
  const { clientEventId, ...payload } = input;
1515
1731
  return await this.sendEvent(workspaceId, sessionId, {
1516
1732
  type: "user.message",
@@ -1656,7 +1872,7 @@ export class OpenGeniClient {
1656
1872
  async getQueue(workspaceId: string, sessionId: string): Promise<SessionQueueSnapshot> {
1657
1873
  const path = `/v1/workspaces/${workspaceId}/sessions/${sessionId}/queue`;
1658
1874
  return await this.singleFlightRead(path, () =>
1659
- this.requestJson<SessionQueueSnapshot>("GET", path),
1875
+ this.requestSessionCommand<SessionQueueSnapshot>("GET", path),
1660
1876
  );
1661
1877
  }
1662
1878
 
@@ -1666,7 +1882,7 @@ export class OpenGeniClient {
1666
1882
  turnId: string,
1667
1883
  request: MoveSessionQueueItemRequest,
1668
1884
  ): Promise<SessionQueueMutationResponse> {
1669
- return await this.requestJson<SessionQueueMutationResponse>(
1885
+ return await this.requestSessionCommand<SessionQueueMutationResponse>(
1670
1886
  "POST",
1671
1887
  `/v1/workspaces/${workspaceId}/sessions/${sessionId}/queue/${turnId}/move`,
1672
1888
  request,
@@ -1679,7 +1895,7 @@ export class OpenGeniClient {
1679
1895
  turnId: string,
1680
1896
  request: EditSessionQueueItemRequest,
1681
1897
  ): Promise<SessionQueueMutationResponse> {
1682
- return await this.requestJson<SessionQueueMutationResponse>(
1898
+ return await this.requestSessionCommand<SessionQueueMutationResponse>(
1683
1899
  "POST",
1684
1900
  `/v1/workspaces/${workspaceId}/sessions/${sessionId}/queue/${turnId}/edit`,
1685
1901
  request,
@@ -1692,7 +1908,7 @@ export class OpenGeniClient {
1692
1908
  turnId: string,
1693
1909
  request: SteerSessionQueueItemRequest,
1694
1910
  ): Promise<SessionQueueMutationResponse> {
1695
- return await this.requestJson<SessionQueueMutationResponse>(
1911
+ return await this.requestSessionCommand<SessionQueueMutationResponse>(
1696
1912
  "POST",
1697
1913
  `/v1/workspaces/${workspaceId}/sessions/${sessionId}/queue/${turnId}/steer`,
1698
1914
  request,
@@ -1705,7 +1921,7 @@ export class OpenGeniClient {
1705
1921
  turnId: string,
1706
1922
  request: DeleteSessionQueueItemRequest,
1707
1923
  ): Promise<SessionQueueMutationResponse> {
1708
- return await this.requestJson<SessionQueueMutationResponse>(
1924
+ return await this.requestSessionCommand<SessionQueueMutationResponse>(
1709
1925
  "POST",
1710
1926
  `/v1/workspaces/${workspaceId}/sessions/${sessionId}/queue/${turnId}/delete`,
1711
1927
  request,
@@ -1713,7 +1929,7 @@ export class OpenGeniClient {
1713
1929
  }
1714
1930
 
1715
1931
  async getComposerDraft(workspaceId: string, sessionId: string): Promise<ComposerDraft> {
1716
- return await this.requestJson<ComposerDraft>(
1932
+ return await this.requestSessionCommand<ComposerDraft>(
1717
1933
  "GET",
1718
1934
  `/v1/workspaces/${workspaceId}/sessions/${sessionId}/composer-draft`,
1719
1935
  );
@@ -1724,13 +1940,25 @@ export class OpenGeniClient {
1724
1940
  sessionId: string,
1725
1941
  request: SaveComposerDraftRequest,
1726
1942
  ): Promise<ComposerDraft> {
1727
- return await this.requestJson<ComposerDraft>(
1943
+ return await this.requestSessionCommand<ComposerDraft>(
1728
1944
  "PUT",
1729
1945
  `/v1/workspaces/${workspaceId}/sessions/${sessionId}/composer-draft`,
1730
1946
  request,
1731
1947
  );
1732
1948
  }
1733
1949
 
1950
+ async submitComposerDraft(
1951
+ workspaceId: string,
1952
+ sessionId: string,
1953
+ request: SubmitComposerDraftRequest,
1954
+ ): Promise<SubmitComposerDraftResponse> {
1955
+ return await this.requestSessionCommand<SubmitComposerDraftResponse>(
1956
+ "POST",
1957
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/composer-draft/submit`,
1958
+ request,
1959
+ );
1960
+ }
1961
+
1734
1962
  async controlSession(
1735
1963
  workspaceId: string,
1736
1964
  sessionId: string,
@@ -1741,7 +1969,7 @@ export class OpenGeniClient {
1741
1969
  expectedControlEtag?: string;
1742
1970
  },
1743
1971
  ): Promise<SessionControlResponse> {
1744
- return await this.requestJson<SessionControlResponse>(
1972
+ return await this.requestSessionCommand<SessionControlResponse>(
1745
1973
  "POST",
1746
1974
  `/v1/workspaces/${workspaceId}/sessions/${sessionId}/control`,
1747
1975
  request,
@@ -1966,7 +2194,8 @@ export class OpenGeniClient {
1966
2194
  message: string | SendMessageInput,
1967
2195
  ): Promise<SteerMessageResult> {
1968
2196
  const input = typeof message === "string" ? { text: message } : message;
1969
- return await this.requestJson<SteerMessageResult>(
2197
+ assertNoMessageTools(input);
2198
+ return await this.requestSessionCommand<SteerMessageResult>(
1970
2199
  "POST",
1971
2200
  `/v1/workspaces/${workspaceId}/sessions/${sessionId}/steer`,
1972
2201
  input,
@@ -2000,6 +2229,47 @@ export class OpenGeniClient {
2000
2229
  );
2001
2230
  }
2002
2231
 
2232
+ async listGoalRevisionPage(
2233
+ workspaceId: string,
2234
+ sessionId: string,
2235
+ options: ListSessionGoalRevisionsOptions = {},
2236
+ ): Promise<ListSessionGoalRevisionsResponse> {
2237
+ const query = new URLSearchParams();
2238
+ if (options.limit !== undefined) query.set("limit", String(options.limit));
2239
+ if (options.before !== undefined) query.set("before", options.before);
2240
+ const suffix = query.size > 0 ? `?${query.toString()}` : "";
2241
+ return await this.requestJson<ListSessionGoalRevisionsResponse>(
2242
+ "GET",
2243
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/goal/revisions/page${suffix}`,
2244
+ );
2245
+ }
2246
+
2247
+ async rejectGoalRevision(
2248
+ workspaceId: string,
2249
+ sessionId: string,
2250
+ revisionId: string,
2251
+ request: RejectSessionGoalRevisionRequest,
2252
+ ): Promise<RejectSessionGoalRevisionResponse> {
2253
+ return await this.requestJson<RejectSessionGoalRevisionResponse>(
2254
+ "POST",
2255
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/goal/revisions/${revisionId}/reject`,
2256
+ request,
2257
+ );
2258
+ }
2259
+
2260
+ async rollbackGoalRevision(
2261
+ workspaceId: string,
2262
+ sessionId: string,
2263
+ revisionId: string,
2264
+ request: RollbackSessionGoalRevisionRequest,
2265
+ ): Promise<SessionGoal> {
2266
+ return await this.requestJson<SessionGoal>(
2267
+ "POST",
2268
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/goal/revisions/${revisionId}/rollback`,
2269
+ request,
2270
+ );
2271
+ }
2272
+
2003
2273
  async applyGoalRevision(
2004
2274
  workspaceId: string,
2005
2275
  sessionId: string,
@@ -2116,6 +2386,22 @@ export class OpenGeniClient {
2116
2386
  );
2117
2387
  }
2118
2388
 
2389
+ /** Publish one exact sandbox file into permanent workspace artifact storage. */
2390
+ async publishSandboxFileArtifact(
2391
+ workspaceId: string,
2392
+ sessionId: string,
2393
+ request: PublishSandboxFileArtifactRequest,
2394
+ options: OpenGeniRequestOptions = {},
2395
+ ): Promise<SandboxFileArtifactReceipt> {
2396
+ return await this.requestJson<SandboxFileArtifactReceipt>(
2397
+ "POST",
2398
+ `/v1/workspaces/${workspaceId}/sessions/${sessionId}/artifacts/publish`,
2399
+ request,
2400
+ {},
2401
+ options,
2402
+ );
2403
+ }
2404
+
2119
2405
  /** FileSystem: write a file (last-writer-wins; emits fs.changed). */
2120
2406
  async fsWrite(
2121
2407
  workspaceId: string,
@@ -3384,6 +3670,26 @@ export class OpenGeniClient {
3384
3670
  );
3385
3671
  }
3386
3672
 
3673
+ /** Read the workspace's hard provider/model allowlist. */
3674
+ async getWorkspaceModelAccessPolicy(workspaceId: string): Promise<WorkspaceModelAccessPolicy> {
3675
+ return await this.requestJson<WorkspaceModelAccessPolicy>(
3676
+ "GET",
3677
+ `/v1/workspaces/${workspaceId}/model-policy`,
3678
+ );
3679
+ }
3680
+
3681
+ /** Fully replace the workspace's hard provider/model allowlist. */
3682
+ async updateWorkspaceModelAccessPolicy(
3683
+ workspaceId: string,
3684
+ request: UpdateWorkspaceModelAccessPolicyRequest,
3685
+ ): Promise<WorkspaceModelAccessPolicy> {
3686
+ return await this.requestJson<WorkspaceModelAccessPolicy>(
3687
+ "PUT",
3688
+ `/v1/workspaces/${workspaceId}/model-policy`,
3689
+ request,
3690
+ );
3691
+ }
3692
+
3387
3693
  /** Authenticated realtime voice models and credential readiness. */
3388
3694
  async getWorkspaceRealtimeModelCatalog(
3389
3695
  workspaceId: string,
@@ -3407,6 +3713,258 @@ export class OpenGeniClient {
3407
3713
  );
3408
3714
  }
3409
3715
 
3716
+ /** Bounded owner-only personal-resource authority page for one exact resource kind. */
3717
+ async listUserResourceAuthorities(
3718
+ workspaceId: string,
3719
+ options: ListUserResourceAuthoritiesOptions,
3720
+ ): Promise<ListUserResourceAuthoritiesResponse> {
3721
+ const query = new URLSearchParams({
3722
+ scope: "user",
3723
+ resourceKind: options.resourceKind,
3724
+ });
3725
+ if (options.cursor) query.set("cursor", options.cursor);
3726
+ if (options.limit !== undefined) query.set("limit", String(options.limit));
3727
+ return await this.requestJson<ListUserResourceAuthoritiesResponse>(
3728
+ "GET",
3729
+ `/v1/workspaces/${workspaceId}/user-resource-authorities?${query.toString()}`,
3730
+ );
3731
+ }
3732
+
3733
+ /** Issue an exact-session or standing personal-resource grant. */
3734
+ async issueUserResourceGrant(
3735
+ workspaceId: string,
3736
+ authorityId: string,
3737
+ request: IssueUserResourceGrantRequest,
3738
+ ): Promise<UserResourceGrantMutationResponse> {
3739
+ return await this.requestJson<UserResourceGrantMutationResponse>(
3740
+ "POST",
3741
+ `/v1/workspaces/${workspaceId}/user-resource-authorities/${authorityId}/grants`,
3742
+ request,
3743
+ );
3744
+ }
3745
+
3746
+ /** Revoke an owner grant through the exact workspace it targets. */
3747
+ async revokeUserResourceGrant(
3748
+ workspaceId: string,
3749
+ grantId: string,
3750
+ ): Promise<RevokeUserResourceGrantResponse> {
3751
+ return await this.requestJson<RevokeUserResourceGrantResponse>(
3752
+ "DELETE",
3753
+ `/v1/workspaces/${workspaceId}/user-resource-authorities/grants/${grantId}?scope=user`,
3754
+ );
3755
+ }
3756
+
3757
+ /** Create a new organization owned by the current managed human. */
3758
+ async createOrganization(
3759
+ request: CreateOrganizationRequest,
3760
+ ): Promise<CreateOrganizationResponse> {
3761
+ return await this.requestJson<CreateOrganizationResponse>("POST", "/v1/organizations", request);
3762
+ }
3763
+
3764
+ /** Pending and historical invitations addressed to the current managed human. */
3765
+ async listOrganizationInvitations(
3766
+ options: { cursor?: string; limit?: number } = {},
3767
+ ): Promise<ListOrganizationInvitationsPageResponse> {
3768
+ const query = new URLSearchParams();
3769
+ if (options.cursor) query.set("cursor", options.cursor);
3770
+ if (options.limit !== undefined) query.set("limit", String(options.limit));
3771
+ const suffix = query.size > 0 ? `?${query.toString()}` : "";
3772
+ return await this.requestJson<ListOrganizationInvitationsPageResponse>(
3773
+ "GET",
3774
+ `/v1/organization-invitations${suffix}`,
3775
+ );
3776
+ }
3777
+
3778
+ /** Admin-only deterministic page of invitations for one organization. */
3779
+ async listOrganizationInvitationsForOrganization(
3780
+ organizationId: string,
3781
+ options: { cursor?: string; limit?: number } = {},
3782
+ ): Promise<ListOrganizationInvitationsPageResponse> {
3783
+ const query = new URLSearchParams();
3784
+ if (options.cursor) query.set("cursor", options.cursor);
3785
+ if (options.limit !== undefined) query.set("limit", String(options.limit));
3786
+ const suffix = query.size > 0 ? `?${query.toString()}` : "";
3787
+ return await this.requestJson<ListOrganizationInvitationsPageResponse>(
3788
+ "GET",
3789
+ `/v1/organizations/${organizationId}/invitations${suffix}`,
3790
+ );
3791
+ }
3792
+
3793
+ async createOrganizationInvitation(
3794
+ organizationId: string,
3795
+ request: CreateOrganizationInvitationRequest,
3796
+ ): Promise<OrganizationInvitation> {
3797
+ return await this.requestJson<OrganizationInvitation>(
3798
+ "POST",
3799
+ `/v1/organizations/${organizationId}/invitations`,
3800
+ request,
3801
+ );
3802
+ }
3803
+
3804
+ async acceptOrganizationInvitation(
3805
+ invitationId: string,
3806
+ request: AcceptOrganizationInvitationRequest,
3807
+ ): Promise<AcceptOrganizationInvitationResponse> {
3808
+ return await this.requestJson<AcceptOrganizationInvitationResponse>(
3809
+ "POST",
3810
+ `/v1/organization-invitations/${invitationId}/accept`,
3811
+ request,
3812
+ );
3813
+ }
3814
+
3815
+ async revokeOrganizationInvitation(
3816
+ organizationId: string,
3817
+ invitationId: string,
3818
+ request: RevokeOrganizationInvitationRequest,
3819
+ ): Promise<OrganizationInvitation> {
3820
+ return await this.requestJson<OrganizationInvitation>(
3821
+ "POST",
3822
+ `/v1/organizations/${organizationId}/invitations/${invitationId}/revoke`,
3823
+ request,
3824
+ );
3825
+ }
3826
+
3827
+ async listOrganizationMembers(organizationId: string): Promise<ListOrganizationMembersResponse> {
3828
+ return await this.requestJson<ListOrganizationMembersResponse>(
3829
+ "GET",
3830
+ `/v1/organizations/${organizationId}/members`,
3831
+ );
3832
+ }
3833
+
3834
+ /** Canonical organization identity and every non-personal workspace access roster. */
3835
+ async getOrganizationAdministrationOverview(
3836
+ organizationId: string,
3837
+ ): Promise<OrganizationAdministrationOverview> {
3838
+ return await this.requestJson<OrganizationAdministrationOverview>(
3839
+ "GET",
3840
+ `/v1/organizations/${organizationId}/overview`,
3841
+ );
3842
+ }
3843
+
3844
+ /** Rename the organization under an exact optimistic-concurrency fence. */
3845
+ async updateOrganizationName(
3846
+ organizationId: string,
3847
+ request: UpdateOrganizationNameRequest,
3848
+ ): Promise<OrganizationSummary> {
3849
+ return await this.requestJson<OrganizationSummary>(
3850
+ "PATCH",
3851
+ `/v1/organizations/${organizationId}`,
3852
+ request,
3853
+ );
3854
+ }
3855
+
3856
+ /**
3857
+ * Organization control-plane update for a shared workspace. This does not
3858
+ * require or create operational workspace access for the organization admin.
3859
+ */
3860
+ async updateOrganizationWorkspace(
3861
+ organizationId: string,
3862
+ workspaceId: string,
3863
+ request: UpdateWorkspaceRequest,
3864
+ ): Promise<Workspace> {
3865
+ return await this.requestJson<Workspace>(
3866
+ "PATCH",
3867
+ `/v1/organizations/${organizationId}/workspaces/${workspaceId}`,
3868
+ request,
3869
+ );
3870
+ }
3871
+
3872
+ /** Create a shared workspace without implicitly granting the actor access. */
3873
+ async createOrganizationWorkspace(
3874
+ organizationId: string,
3875
+ request: CreateOrganizationWorkspaceRequest,
3876
+ ): Promise<Workspace> {
3877
+ return await this.requestJson<Workspace>(
3878
+ "POST",
3879
+ `/v1/organizations/${organizationId}/workspaces`,
3880
+ request,
3881
+ );
3882
+ }
3883
+
3884
+ async updateOrganizationWorkspaceSettings(
3885
+ organizationId: string,
3886
+ workspaceId: string,
3887
+ request: UpdateWorkspaceSettingsRequest,
3888
+ ): Promise<Workspace> {
3889
+ return await this.requestJson<Workspace>(
3890
+ "PATCH",
3891
+ `/v1/organizations/${organizationId}/workspaces/${workspaceId}/settings`,
3892
+ request,
3893
+ );
3894
+ }
3895
+
3896
+ async addOrganizationWorkspaceMember(
3897
+ organizationId: string,
3898
+ workspaceId: string,
3899
+ request: AddOrganizationWorkspaceMemberRequest,
3900
+ ): Promise<WorkspaceMember> {
3901
+ return await this.requestJson<WorkspaceMember>(
3902
+ "POST",
3903
+ `/v1/organizations/${organizationId}/workspaces/${workspaceId}/members`,
3904
+ request,
3905
+ );
3906
+ }
3907
+
3908
+ async updateOrganizationWorkspaceMember(
3909
+ organizationId: string,
3910
+ workspaceId: string,
3911
+ subjectId: string,
3912
+ request: UpdateWorkspaceMemberRequest,
3913
+ ): Promise<WorkspaceMember> {
3914
+ return await this.requestJson<WorkspaceMember>(
3915
+ "PATCH",
3916
+ `/v1/organizations/${organizationId}/workspaces/${workspaceId}/members/${encodeURIComponent(
3917
+ subjectId,
3918
+ )}`,
3919
+ request,
3920
+ );
3921
+ }
3922
+
3923
+ async removeOrganizationWorkspaceMember(
3924
+ organizationId: string,
3925
+ workspaceId: string,
3926
+ subjectId: string,
3927
+ ): Promise<void> {
3928
+ await this.requestVoid(
3929
+ "DELETE",
3930
+ `/v1/organizations/${organizationId}/workspaces/${workspaceId}/members/${encodeURIComponent(
3931
+ subjectId,
3932
+ )}`,
3933
+ );
3934
+ }
3935
+
3936
+ async updateOrganizationMember(
3937
+ organizationId: string,
3938
+ membershipId: string,
3939
+ request: UpdateOrganizationMemberRequest,
3940
+ ): Promise<OrganizationMember> {
3941
+ return await this.requestJson<OrganizationMember>(
3942
+ "PATCH",
3943
+ `/v1/organizations/${organizationId}/members/${membershipId}`,
3944
+ request,
3945
+ );
3946
+ }
3947
+
3948
+ async getOrganizationRetentionPolicy(
3949
+ organizationId: string,
3950
+ ): Promise<OrganizationRetentionPolicy> {
3951
+ return await this.requestJson<OrganizationRetentionPolicy>(
3952
+ "GET",
3953
+ `/v1/organizations/${organizationId}/retention-policy`,
3954
+ );
3955
+ }
3956
+
3957
+ async updateOrganizationRetentionPolicy(
3958
+ organizationId: string,
3959
+ request: UpdateOrganizationRetentionPolicyRequest,
3960
+ ): Promise<OrganizationRetentionPolicy> {
3961
+ return await this.requestJson<OrganizationRetentionPolicy>(
3962
+ "PATCH",
3963
+ `/v1/organizations/${organizationId}/retention-policy`,
3964
+ request,
3965
+ );
3966
+ }
3967
+
3410
3968
  async listWorkspaces(): Promise<Workspace[]> {
3411
3969
  return await this.requestJson<Workspace[]>("GET", "/v1/workspaces");
3412
3970
  }
@@ -3447,6 +4005,28 @@ export class OpenGeniClient {
3447
4005
  );
3448
4006
  }
3449
4007
 
4008
+ /** Permission-filtered Company Brain package with authorized guidance bodies. */
4009
+ getCompanyBrain(workspaceId: string): Promise<CompanyBrainOkfPackage> {
4010
+ return this.requestJson<CompanyBrainOkfPackage>(
4011
+ "GET",
4012
+ `/v1/workspaces/${workspaceId}/company-brain`,
4013
+ );
4014
+ }
4015
+
4016
+ /** Download the deterministic Markdown/YAML Company Brain package. */
4017
+ async exportCompanyBrainOkf(workspaceId: string): Promise<CompanyBrainOkfDownload> {
4018
+ const response = await this.requestResponse(
4019
+ "GET",
4020
+ `/v1/workspaces/${workspaceId}/company-brain/export`,
4021
+ );
4022
+ const headers = response.headers;
4023
+ return {
4024
+ content: await response.text(),
4025
+ contentType: headers.get("content-type") ?? "text/markdown",
4026
+ filename: headers.get("content-disposition")?.split('"')[1] ?? "company-brain.okf.md",
4027
+ };
4028
+ }
4029
+
3450
4030
  async updateWorkspace(workspaceId: string, request: UpdateWorkspaceRequest): Promise<Workspace> {
3451
4031
  return await this.requestJson<Workspace>("PATCH", `/v1/workspaces/${workspaceId}`, request);
3452
4032
  }
@@ -3471,6 +4051,66 @@ export class OpenGeniClient {
3471
4051
  );
3472
4052
  }
3473
4053
 
4054
+ /** Inspect the bounded, permission-filtered governed-learning timeline. */
4055
+ async getWorkspaceLearningHistory(
4056
+ workspaceId: string,
4057
+ options: WorkspaceLearningHistoryOptions = {},
4058
+ ): Promise<WorkspaceLearningHistoryResponse> {
4059
+ const params = new URLSearchParams();
4060
+ if (options.limit !== undefined) params.set("limit", String(options.limit));
4061
+ const query = params.toString();
4062
+ return await this.requestJson<WorkspaceLearningHistoryResponse>(
4063
+ "GET",
4064
+ `/v1/workspaces/${workspaceId}/learning${query ? `?${query}` : ""}`,
4065
+ );
4066
+ }
4067
+
4068
+ async createWorkspaceLearningPolicyRevision(
4069
+ workspaceId: string,
4070
+ request: CreateWorkspaceLearningPolicyRevisionRequest,
4071
+ ): Promise<WorkspaceLearningPolicyRevision> {
4072
+ return await this.requestJson<WorkspaceLearningPolicyRevision>(
4073
+ "POST",
4074
+ `/v1/workspaces/${workspaceId}/learning/revisions`,
4075
+ request,
4076
+ );
4077
+ }
4078
+
4079
+ async activateWorkspaceLearningPolicyRevision(
4080
+ workspaceId: string,
4081
+ revisionId: string,
4082
+ request: ActivateWorkspaceLearningPolicyRevisionRequest,
4083
+ ): Promise<WorkspaceLearningPolicyMutationResponse> {
4084
+ return await this.requestJson<WorkspaceLearningPolicyMutationResponse>(
4085
+ "POST",
4086
+ `/v1/workspaces/${workspaceId}/learning/revisions/${encodeURIComponent(revisionId)}/activate`,
4087
+ request,
4088
+ );
4089
+ }
4090
+
4091
+ async rollbackWorkspaceLearningPolicyRevision(
4092
+ workspaceId: string,
4093
+ request: RollbackWorkspaceLearningPolicyRevisionRequest,
4094
+ ): Promise<WorkspaceLearningPolicyMutationResponse> {
4095
+ return await this.requestJson<WorkspaceLearningPolicyMutationResponse>(
4096
+ "POST",
4097
+ `/v1/workspaces/${workspaceId}/learning/rollback`,
4098
+ request,
4099
+ );
4100
+ }
4101
+
4102
+ async undoGovernedLearningActivation(
4103
+ workspaceId: string,
4104
+ activationReceiptId: string,
4105
+ request: { operationId?: string } = {},
4106
+ ): Promise<GovernedLearningActivationUndoReceipt> {
4107
+ return await this.requestJson<GovernedLearningActivationUndoReceipt>(
4108
+ "POST",
4109
+ `/v1/workspaces/${workspaceId}/learning/activations/${encodeURIComponent(activationReceiptId)}/undo`,
4110
+ request,
4111
+ );
4112
+ }
4113
+
3474
4114
  async getWorkspaceInstructionPolicyRevision(
3475
4115
  workspaceId: string,
3476
4116
  revisionId: string,
@@ -4092,6 +4732,14 @@ export class OpenGeniClient {
4092
4732
  );
4093
4733
  }
4094
4734
 
4735
+ async reorderChannels(workspaceId: string, request: ReorderChannelsRequest): Promise<Channel[]> {
4736
+ return await this.requestJson<Channel[]>(
4737
+ "PUT",
4738
+ `/v1/workspaces/${workspaceId}/channels/order`,
4739
+ request,
4740
+ );
4741
+ }
4742
+
4095
4743
  async deleteChannel(workspaceId: string, channelId: string): Promise<void> {
4096
4744
  await this.requestJson<unknown>(
4097
4745
  "DELETE",
@@ -4460,24 +5108,24 @@ export class OpenGeniClient {
4460
5108
  );
4461
5109
  }
4462
5110
 
4463
- /** Assemble one permanent generated-image receipt from bounded authenticated ranges. */
5111
+ /** Assemble one permanent image or file artifact from bounded authenticated ranges. */
4464
5112
  async downloadRetainedArtifact(
4465
5113
  workspaceId: string,
4466
5114
  artifact: RetainedArtifactReference,
4467
5115
  options: RetainedArtifactDownloadOptions = {},
4468
5116
  ): Promise<RetainedArtifactDownload> {
4469
- assertRetainedGeneratedImageReceipt(workspaceId, artifact);
5117
+ assertRetainedWorkspaceArtifactReceipt(workspaceId, artifact);
4470
5118
  const bytes = await this.downloadRetainedArtifactBytes(artifact, options);
4471
5119
  return { artifact, bytes };
4472
5120
  }
4473
5121
 
4474
- /** Mint a short-lived, zero-copy browser source for a validated generated image. */
5122
+ /** Mint a short-lived, zero-copy browser source for a validated workspace artifact. */
4475
5123
  async createRetainedArtifactDownloadUrl(
4476
5124
  workspaceId: string,
4477
5125
  artifact: RetainedArtifactReference,
4478
5126
  options: OpenGeniRequestOptions = {},
4479
5127
  ): Promise<FileDownloadUrlResponse> {
4480
- assertRetainedGeneratedImageReceipt(workspaceId, artifact);
5128
+ assertRetainedWorkspaceArtifactReceipt(workspaceId, artifact);
4481
5129
  const download = await this.createFileDownloadUrl(workspaceId, artifact.artifactId, options);
4482
5130
  assertSafeArtifactDownloadUrl(download);
4483
5131
  return download;
@@ -4741,6 +5389,34 @@ export class OpenGeniClient {
4741
5389
  );
4742
5390
  }
4743
5391
 
5392
+ /**
5393
+ * List every Document the current human can manage from this workspace,
5394
+ * including portable personal and organization-scoped Documents whose
5395
+ * immutable ingestion workspace is different.
5396
+ */
5397
+ async listAccessibleDocuments(workspaceId: string): Promise<Document[]> {
5398
+ return await this.requestJson<Document[]>("GET", `/v1/workspaces/${workspaceId}/documents`);
5399
+ }
5400
+
5401
+ /** Read the immutable source file through the Document's effective authority. */
5402
+ async getDocumentOriginalFile(workspaceId: string, documentId: string): Promise<FileAsset> {
5403
+ return await this.requestJson<FileAsset>(
5404
+ "GET",
5405
+ `/v1/workspaces/${workspaceId}/documents/${documentId}/original-file`,
5406
+ );
5407
+ }
5408
+
5409
+ /** Mint a source-file URL through the Document's effective authority. */
5410
+ async createDocumentOriginalFileDownloadUrl(
5411
+ workspaceId: string,
5412
+ documentId: string,
5413
+ ): Promise<FileDownloadUrlResponse> {
5414
+ return await this.requestJson<FileDownloadUrlResponse>(
5415
+ "POST",
5416
+ `/v1/workspaces/${workspaceId}/documents/${documentId}/original-file/download-url`,
5417
+ );
5418
+ }
5419
+
4744
5420
  /**
4745
5421
  * Drop raw text or an already-uploaded file into the workspace's Default
4746
5422
  * base. When curation is enabled, it may name, summarize, categorize, and
@@ -4774,6 +5450,53 @@ export class OpenGeniClient {
4774
5450
  );
4775
5451
  }
4776
5452
 
5453
+ /**
5454
+ * Atomically reclassify a Document's authority and every indexed chunk.
5455
+ * The operation is replay-safe and rejects a stale expected authority tuple.
5456
+ */
5457
+ async reclassifyDocumentAuthority(
5458
+ workspaceId: string,
5459
+ documentId: string,
5460
+ request: ReclassifyDocumentAuthorityRequest,
5461
+ ): Promise<DocumentAuthorityReclassification> {
5462
+ return await this.requestJson<DocumentAuthorityReclassification>(
5463
+ "POST",
5464
+ `/v1/workspaces/${workspaceId}/documents/${documentId}/authority-reclassifications`,
5465
+ request,
5466
+ );
5467
+ }
5468
+
5469
+ /** List the current actor's durable authority-reclassification receipts. */
5470
+ async listDocumentAuthorityReclassifications(
5471
+ workspaceId: string,
5472
+ documentId: string,
5473
+ options: ListDocumentAuthorityReclassificationsOptions = {},
5474
+ ): Promise<ListDocumentAuthorityReclassificationsResponse> {
5475
+ const params = new URLSearchParams();
5476
+ if (options.limit !== undefined) params.set("limit", String(options.limit));
5477
+ if (options.cursor) params.set("cursor", options.cursor);
5478
+ const query = params.size > 0 ? `?${params.toString()}` : "";
5479
+ return await this.requestJson<ListDocumentAuthorityReclassificationsResponse>(
5480
+ "GET",
5481
+ `/v1/workspaces/${workspaceId}/documents/${documentId}/authority-reclassifications${query}`,
5482
+ );
5483
+ }
5484
+
5485
+ /**
5486
+ * Advance one resumable, organization-scoped Default collection backfill.
5487
+ * Reusing an operation ID is idempotent; keep the run ID across batches.
5488
+ */
5489
+ async runDocumentDefaultCollectionBackfill(
5490
+ workspaceId: string,
5491
+ request: RunDocumentDefaultCollectionBackfillRequest,
5492
+ ): Promise<DocumentDefaultCollectionBackfill> {
5493
+ return await this.requestJson<DocumentDefaultCollectionBackfill>(
5494
+ "POST",
5495
+ `/v1/workspaces/${workspaceId}/document-default-collection-backfills`,
5496
+ request,
5497
+ );
5498
+ }
5499
+
4777
5500
  /** Retry indexing for a failed document. */
4778
5501
  async reindexDocument(
4779
5502
  workspaceId: string,
@@ -5389,6 +6112,96 @@ export class OpenGeniClient {
5389
6112
  return response.connections;
5390
6113
  }
5391
6114
 
6115
+ /** Secret-free status for the caller's exact personal GitHub connection. */
6116
+ async personalGitHubStatus(workspaceId: string): Promise<PersonalGitHubConnectionStatusResponse> {
6117
+ return await this.requestJson<PersonalGitHubConnectionStatusResponse>(
6118
+ "GET",
6119
+ `/v1/workspaces/${workspaceId}/connections/github`,
6120
+ );
6121
+ }
6122
+
6123
+ /** Start the dedicated personal GitHub authorization-code + PKCE flow. */
6124
+ async startPersonalGitHubOAuth(
6125
+ workspaceId: string,
6126
+ request: Omit<PersonalGitHubOAuthStartRequest, "connectionId"> = {},
6127
+ ): Promise<PersonalGitHubOAuthStartResponse> {
6128
+ return await this.requestJson<PersonalGitHubOAuthStartResponse>(
6129
+ "POST",
6130
+ `/v1/workspaces/${workspaceId}/connections/github/oauth/start`,
6131
+ request,
6132
+ );
6133
+ }
6134
+
6135
+ /** Re-authorize one exact personal GitHub Connection generation in place. */
6136
+ async reconnectPersonalGitHub(
6137
+ workspaceId: string,
6138
+ connectionId: string,
6139
+ request: Omit<PersonalGitHubOAuthStartRequest, "connectionId"> = {},
6140
+ ): Promise<PersonalGitHubOAuthStartResponse> {
6141
+ return await this.requestJson<PersonalGitHubOAuthStartResponse>(
6142
+ "POST",
6143
+ `/v1/workspaces/${workspaceId}/connections/${connectionId}/github/reconnect`,
6144
+ request,
6145
+ );
6146
+ }
6147
+
6148
+ /** Revoke one exact generation through an idempotent owner-only disconnect. */
6149
+ async disconnectPersonalGitHub(
6150
+ workspaceId: string,
6151
+ connectionId: string,
6152
+ request: PersonalGitHubDisconnectRequest,
6153
+ ): Promise<ConnectionMetadata> {
6154
+ const response = await this.requestJson<ConnectionResponse>(
6155
+ "DELETE",
6156
+ `/v1/workspaces/${workspaceId}/connections/${connectionId}`,
6157
+ request,
6158
+ );
6159
+ return response.connection;
6160
+ }
6161
+
6162
+ /** Browse one bounded page of repositories visible to one exact owner connection. */
6163
+ async listPersonalGitHubRepositories(
6164
+ workspaceId: string,
6165
+ connectionId: string,
6166
+ options: ListPersonalGitHubRepositoriesOptions = {},
6167
+ ): Promise<ListPersonalGitHubRepositoriesResponse> {
6168
+ return await this.requestJson<ListPersonalGitHubRepositoriesResponse>(
6169
+ "GET",
6170
+ `/v1/workspaces/${workspaceId}/connections/${connectionId}/github/repositories`,
6171
+ undefined,
6172
+ {
6173
+ ...(options.cursor !== undefined ? { cursor: String(options.cursor) } : {}),
6174
+ ...(options.limit !== undefined ? { limit: String(options.limit) } : {}),
6175
+ },
6176
+ );
6177
+ }
6178
+
6179
+ /** Atomically replace the exact owner connection's selected repository set. */
6180
+ async replacePersonalGitHubRepositorySelections(
6181
+ workspaceId: string,
6182
+ connectionId: string,
6183
+ request: ReplacePersonalGitHubRepositorySelectionsRequest,
6184
+ ): Promise<PersonalGitHubRepositorySelectionState> {
6185
+ return await this.requestJson<PersonalGitHubRepositorySelectionState>(
6186
+ "PUT",
6187
+ `/v1/workspaces/${workspaceId}/connections/${connectionId}/github/repositories`,
6188
+ request,
6189
+ );
6190
+ }
6191
+
6192
+ /** Revalidate every selected repository without accepting provider URLs from the caller. */
6193
+ async verifyPersonalGitHubRepositorySelections(
6194
+ workspaceId: string,
6195
+ connectionId: string,
6196
+ request: VerifyPersonalGitHubRepositorySelectionsRequest,
6197
+ ): Promise<PersonalGitHubRepositorySelectionState> {
6198
+ return await this.requestJson<PersonalGitHubRepositorySelectionState>(
6199
+ "POST",
6200
+ `/v1/workspaces/${workspaceId}/connections/${connectionId}/github/repositories/verify`,
6201
+ request,
6202
+ );
6203
+ }
6204
+
5392
6205
  /** List the secret-free Slack team -> OpenGeni tenant routing authority. */
5393
6206
  async listSlackInstallationBindings(workspaceId: string): Promise<SlackInstallationBinding[]> {
5394
6207
  const response = await this.requestJson<ListSlackInstallationBindingsResponse>(
@@ -5705,6 +6518,17 @@ export class OpenGeniClient {
5705
6518
  return await this.requestJson<CreateCheckoutResponse>("POST", "/v1/billing/checkout", request);
5706
6519
  }
5707
6520
 
6521
+ /** Open Stripe's hosted portal for invoices and payment information. */
6522
+ async createBillingPortalSession(
6523
+ request: CreateBillingPortalRequest = {},
6524
+ ): Promise<CreateBillingPortalResponse> {
6525
+ return await this.requestJson<CreateBillingPortalResponse>(
6526
+ "POST",
6527
+ "/v1/billing/portal",
6528
+ request,
6529
+ );
6530
+ }
6531
+
5708
6532
  // --- Internals -------------------------------------------------------------
5709
6533
 
5710
6534
  private headers(correlationId?: string): Record<string, string> {
@@ -5988,6 +6812,19 @@ export class OpenGeniClient {
5988
6812
  }>("DELETE", `/v1/workspaces/${workspaceId}/supergrok/accounts/${accountId}`, {});
5989
6813
  }
5990
6814
 
6815
+ /** Contract-checked JSON transport shared by opt-in typed SDK clients. */
6816
+ private async requestSessionCommand<T>(method: string, path: string, body?: unknown): Promise<T> {
6817
+ return await this.requestJson<T>(
6818
+ method,
6819
+ path,
6820
+ body,
6821
+ {},
6822
+ {
6823
+ timeoutMs: this.sessionCommandTimeoutMs,
6824
+ },
6825
+ );
6826
+ }
6827
+
5991
6828
  /** Contract-checked JSON transport shared by opt-in typed SDK clients. */
5992
6829
  async requestJson<T>(
5993
6830
  method: string,
@@ -5997,36 +6834,46 @@ export class OpenGeniClient {
5997
6834
  options: OpenGeniRequestOptions = {},
5998
6835
  ): Promise<T> {
5999
6836
  const correlationId = crypto.randomUUID();
6000
- let response: Response;
6837
+ const abort = requestAbortSignal(options);
6001
6838
  try {
6002
- response = await this.fetchImpl(this.url(path, query), {
6003
- method,
6004
- headers: {
6005
- ...this.headers(correlationId),
6006
- Accept: "application/json",
6007
- ...(body !== undefined ? { "Content-Type": "application/json" } : {}),
6008
- },
6009
- ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
6010
- ...(options.signal ? { signal: options.signal } : {}),
6011
- });
6012
- } catch (error) {
6013
- if (isMutationMethod(method)) {
6014
- throw mutationTransportError(correlationId);
6839
+ let response: Response;
6840
+ try {
6841
+ response = await awaitWithAbort(
6842
+ this.fetchImpl(this.url(path, query), {
6843
+ method,
6844
+ headers: {
6845
+ ...this.headers(correlationId),
6846
+ Accept: "application/json",
6847
+ ...(body !== undefined ? { "Content-Type": "application/json" } : {}),
6848
+ },
6849
+ ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
6850
+ ...(abort.signal ? { signal: abort.signal } : {}),
6851
+ }),
6852
+ abort.signal,
6853
+ );
6854
+ } catch (error) {
6855
+ if (options.signal?.aborted) throw error;
6856
+ if (isMutationMethod(method)) {
6857
+ throw mutationTransportError(correlationId);
6858
+ }
6859
+ throw error;
6015
6860
  }
6016
- throw error;
6017
- }
6018
- assertApiContractResponse(response);
6019
- if (!response.ok) {
6020
- throw await apiErrorFromResponse(response, { method, correlationId });
6021
- }
6022
- await assertJsonResponse(response, { method, correlationId });
6023
- try {
6024
- return (await response.json()) as T;
6025
- } catch (error) {
6026
- if (isMutationMethod(method)) {
6027
- throw mutationTransportError(correlationId);
6861
+ assertApiContractResponse(response);
6862
+ if (!response.ok) {
6863
+ throw await apiErrorFromResponse(response, { method, correlationId });
6028
6864
  }
6029
- throw error;
6865
+ await assertJsonResponse(response, { method, correlationId });
6866
+ try {
6867
+ return (await response.json()) as T;
6868
+ } catch (error) {
6869
+ if (options.signal?.aborted) throw error;
6870
+ if (isMutationMethod(method)) {
6871
+ throw mutationTransportError(correlationId);
6872
+ }
6873
+ throw error;
6874
+ }
6875
+ } finally {
6876
+ abort.dispose();
6030
6877
  }
6031
6878
  }
6032
6879
 
@@ -6059,8 +6906,8 @@ export class OpenGeniClient {
6059
6906
  return response;
6060
6907
  }
6061
6908
 
6062
- /** Like `requestJson` for endpoints that respond with no body (204). */
6063
- private async requestVoid(method: string, path: string, body?: unknown): Promise<void> {
6909
+ /** Contract-checked transport shared by opt-in typed SDK clients for 204 responses. */
6910
+ async requestVoid(method: string, path: string, body?: unknown): Promise<void> {
6064
6911
  const correlationId = crypto.randomUUID();
6065
6912
  let response: Response;
6066
6913
  try {
@@ -6210,6 +7057,59 @@ function filenameForAudioMimeType(mimeType: string): string {
6210
7057
 
6211
7058
  const API_ERROR_MAX_BYTES = 16 * 1024;
6212
7059
 
7060
+ function requestAbortSignal(options: OpenGeniRequestOptions): {
7061
+ signal: AbortSignal | undefined;
7062
+ dispose: () => void;
7063
+ } {
7064
+ const timeoutMs = options.timeoutMs ?? 0;
7065
+ if (timeoutMs <= 0) {
7066
+ return { signal: options.signal, dispose: () => undefined };
7067
+ }
7068
+ const controller = new AbortController();
7069
+ const onCallerAbort = () => controller.abort(options.signal?.reason);
7070
+ if (options.signal?.aborted) {
7071
+ onCallerAbort();
7072
+ } else {
7073
+ options.signal?.addEventListener("abort", onCallerAbort, { once: true });
7074
+ }
7075
+ const timer = setTimeout(
7076
+ () => controller.abort(new DOMException("Request timed out", "TimeoutError")),
7077
+ timeoutMs,
7078
+ );
7079
+ return {
7080
+ signal: controller.signal,
7081
+ dispose: () => {
7082
+ clearTimeout(timer);
7083
+ options.signal?.removeEventListener("abort", onCallerAbort);
7084
+ },
7085
+ };
7086
+ }
7087
+
7088
+ async function awaitWithAbort<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {
7089
+ if (!signal) return await promise;
7090
+ if (signal.aborted) {
7091
+ throw signal.reason ?? new DOMException("Request aborted", "AbortError");
7092
+ }
7093
+ return await new Promise<T>((resolve, reject) => {
7094
+ const onAbort = () => {
7095
+ cleanup();
7096
+ reject(signal.reason ?? new DOMException("Request aborted", "AbortError"));
7097
+ };
7098
+ const cleanup = () => signal.removeEventListener("abort", onAbort);
7099
+ signal.addEventListener("abort", onAbort, { once: true });
7100
+ promise.then(
7101
+ (value) => {
7102
+ cleanup();
7103
+ resolve(value);
7104
+ },
7105
+ (cause) => {
7106
+ cleanup();
7107
+ reject(cause);
7108
+ },
7109
+ );
7110
+ });
7111
+ }
7112
+
6213
7113
  type ApiErrorRequestContext = {
6214
7114
  method: string;
6215
7115
  correlationId?: string | undefined;
@@ -6298,12 +7198,15 @@ async function cancelResponseBody(response: Response, reason: string): Promise<v
6298
7198
  await response.body?.cancel(reason).catch(() => undefined);
6299
7199
  }
6300
7200
 
6301
- function assertRetainedGeneratedImageReceipt(
7201
+ function assertRetainedWorkspaceArtifactReceipt(
6302
7202
  workspaceId: string,
6303
7203
  artifact: RetainedArtifactReference,
6304
7204
  ): void {
6305
- if (!parseRetainedGeneratedImageReference(artifact, workspaceId)) {
6306
- throw new OpenGeniApiError(502, "retained generated image receipt is invalid");
7205
+ if (
7206
+ !parseRetainedGeneratedImageReference(artifact, workspaceId) &&
7207
+ !parseRetainedWorkspaceFileReference(artifact, workspaceId)
7208
+ ) {
7209
+ throw new OpenGeniApiError(502, "retained workspace artifact receipt is invalid");
6307
7210
  }
6308
7211
  }
6309
7212