@opengeni/sdk 0.46.0 → 0.52.1
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.
- package/README.md +94 -2
- package/dist/artifact-client.d.ts +20 -2
- package/dist/artifacts.d.ts +4 -0
- package/dist/artifacts.js +11 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/chunk-FHI4DFIG.js +128 -0
- package/dist/chunk-FHI4DFIG.js.map +1 -0
- package/dist/chunk-FRJFNDIR.js +218 -0
- package/dist/chunk-FRJFNDIR.js.map +1 -0
- package/dist/{chunk-QKV5OCLJ.js → chunk-ILQZR5N6.js} +1380 -595
- package/dist/chunk-ILQZR5N6.js.map +1 -0
- package/dist/chunk-MZWTWOX6.js +661 -0
- package/dist/chunk-MZWTWOX6.js.map +1 -0
- package/dist/chunk-VWE2QIVO.js +1162 -0
- package/dist/chunk-VWE2QIVO.js.map +1 -0
- package/dist/chunk-VYCTL62C.js +230 -0
- package/dist/chunk-VYCTL62C.js.map +1 -0
- package/dist/client.d.ts +176 -20
- package/dist/codex-realtime-controller.d.ts +6 -6
- package/dist/codex-realtime-lifecycle.d.ts +1 -1
- package/dist/codex-realtime-v3.d.ts +3 -3
- package/dist/codex-realtime.d.ts +1 -1
- package/dist/company-profile.d.ts +100 -0
- package/dist/core.d.ts +5 -5
- package/dist/core.js +9 -4
- package/dist/desktop.d.ts +1 -1
- package/dist/editable-artifact-resources.d.ts +96 -0
- package/dist/editable-artifacts/browser-session.d.ts +35 -0
- package/dist/editable-artifacts/controller.d.ts +60 -0
- package/dist/editable-artifacts/errors.d.ts +23 -0
- package/dist/editable-artifacts/http-live-transport.d.ts +46 -0
- package/dist/editable-artifacts/index.d.ts +19 -0
- package/dist/editable-artifacts/pool.d.ts +15 -0
- package/dist/editable-artifacts/session.d.ts +96 -0
- package/dist/editable-artifacts/storage.d.ts +72 -0
- package/dist/editable-artifacts/types.d.ts +416 -0
- package/dist/editable-artifacts/worker/browser-client.d.ts +80 -0
- package/dist/editable-artifacts/worker/browser-entry.d.ts +6 -0
- package/dist/editable-artifacts/worker/kernel-adapter.d.ts +45 -0
- package/dist/editable-artifacts/worker/rpc-protocol.d.ts +92 -0
- package/dist/editable-artifacts/worker/runtime.d.ts +66 -0
- package/dist/editable-artifacts/worker/wire-codec.d.ts +52 -0
- package/dist/editable-artifacts-worker.d.ts +8 -0
- package/dist/editable-artifacts-worker.js +1708 -0
- package/dist/editable-artifacts-worker.js.map +1 -0
- package/dist/editable-artifacts.d.ts +6 -0
- package/dist/editable-artifacts.js +5954 -0
- package/dist/editable-artifacts.js.map +1 -0
- package/dist/gateway-realtime-transport.d.ts +1 -1
- package/dist/index.d.ts +41 -35
- package/dist/index.js +104 -68
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +885 -0
- package/dist/interaction.js +55 -0
- package/dist/interaction.js.map +1 -0
- package/dist/memory-slack-client.d.ts +13 -0
- package/dist/memory-slack-delivery.d.ts +99 -0
- package/dist/memory-slack.d.ts +4 -0
- package/dist/memory-slack.js +44 -0
- package/dist/memory-slack.js.map +1 -0
- package/dist/proxy.d.ts +3 -3
- package/dist/realtime.d.ts +12 -12
- package/dist/retained-artifacts.d.ts +12 -0
- package/dist/stream.d.ts +16 -1
- package/dist/terminal.d.ts +1 -1
- package/dist/transcription.d.ts +2 -2
- package/dist/types.d.ts +1203 -23
- package/dist/workspace-control-stream.d.ts +2 -2
- package/dist/workspace-state.d.ts +1 -1
- package/package.json +29 -3
- package/src/artifact-client.ts +129 -0
- package/src/artifacts.ts +17 -0
- package/src/client.ts +1801 -206
- package/src/company-profile.ts +92 -0
- package/src/editable-artifact-resources.ts +119 -0
- package/src/editable-artifacts/browser-session.ts +176 -0
- package/src/editable-artifacts/controller.ts +2632 -0
- package/src/editable-artifacts/errors.ts +52 -0
- package/src/editable-artifacts/http-live-transport.ts +1449 -0
- package/src/editable-artifacts/index.ts +175 -0
- package/src/editable-artifacts/pool.ts +81 -0
- package/src/editable-artifacts/session.ts +778 -0
- package/src/editable-artifacts/storage.ts +1718 -0
- package/src/editable-artifacts/types.ts +499 -0
- package/src/editable-artifacts/worker/browser-client.ts +1167 -0
- package/src/editable-artifacts/worker/browser-entry.ts +57 -0
- package/src/editable-artifacts/worker/kernel-adapter.ts +1039 -0
- package/src/editable-artifacts/worker/rpc-protocol.ts +622 -0
- package/src/editable-artifacts/worker/runtime.ts +1204 -0
- package/src/editable-artifacts/worker/wire-codec.ts +852 -0
- package/src/editable-artifacts-worker.ts +8 -0
- package/src/editable-artifacts.ts +6 -0
- package/src/index.ts +194 -0
- package/src/interaction.ts +1830 -0
- package/src/memory-slack-client.ts +71 -0
- package/src/memory-slack-delivery.ts +128 -0
- package/src/memory-slack.ts +19 -0
- package/src/retained-artifacts.ts +326 -0
- package/src/stream.ts +102 -4
- package/src/transcription.ts +2 -2
- package/src/types.ts +1430 -33
- package/src/workspace-control-stream.ts +15 -5
- package/dist/chunk-QKV5OCLJ.js.map +0 -1
package/src/client.ts
CHANGED
|
@@ -12,6 +12,48 @@ import {
|
|
|
12
12
|
streamWorkspaceControlEvents,
|
|
13
13
|
type WorkspaceControlStreamTransport,
|
|
14
14
|
} from "./workspace-control-stream";
|
|
15
|
+
import {
|
|
16
|
+
OpenGeniInteractionClient,
|
|
17
|
+
type AttachedBrowserDevice,
|
|
18
|
+
type AttachedBrowserDeviceListOptions,
|
|
19
|
+
type AttachedBrowserDeviceListResponse,
|
|
20
|
+
type BrowserActionReceipt,
|
|
21
|
+
type BrowserActionRequest,
|
|
22
|
+
type BrowserDiagnosticBatch,
|
|
23
|
+
type BrowserDiagnosticsOptions,
|
|
24
|
+
type BrowserIdentity,
|
|
25
|
+
type BrowserIdentityListOptions,
|
|
26
|
+
type BrowserIdentityListResponse,
|
|
27
|
+
type BrowserIdentityMutationResponse,
|
|
28
|
+
type BrowserObservation,
|
|
29
|
+
type BrowserOpenTargetRequest,
|
|
30
|
+
type BrowserSession,
|
|
31
|
+
type BrowserSessionAttachment,
|
|
32
|
+
type BrowserSessionAttachmentRequest,
|
|
33
|
+
type BrowserSessionHeartbeatResponse,
|
|
34
|
+
type BrowserSessionLifecycleRequest,
|
|
35
|
+
type BrowserSessionListResponse,
|
|
36
|
+
type BrowserSessionMutationResponse,
|
|
37
|
+
type BrowserTarget,
|
|
38
|
+
type BrowserTargetListResponse,
|
|
39
|
+
type BrowserRevisionListResponse,
|
|
40
|
+
type ComputerActionReceipt,
|
|
41
|
+
type ComputerActionRequest,
|
|
42
|
+
type ComputerObservation,
|
|
43
|
+
type ComputerSession,
|
|
44
|
+
type ComputerSessionAttachment,
|
|
45
|
+
type ComputerSessionAttachmentRequest,
|
|
46
|
+
type ComputerSessionHeartbeatResponse,
|
|
47
|
+
type ComputerSessionLifecycleRequest,
|
|
48
|
+
type ComputerSessionListResponse,
|
|
49
|
+
type ComputerSessionMutationResponse,
|
|
50
|
+
type ComputerTargetListResponse,
|
|
51
|
+
type CreateBrowserIdentityRequest,
|
|
52
|
+
type CreateBrowserSessionRequest,
|
|
53
|
+
type CreateComputerSessionRequest,
|
|
54
|
+
type PublishBrowserRevisionRequest,
|
|
55
|
+
type PublishBrowserRevisionResponse,
|
|
56
|
+
} from "./interaction";
|
|
15
57
|
import type {
|
|
16
58
|
AccessContext,
|
|
17
59
|
ActivateCodexRealtimeConnectionRequest,
|
|
@@ -41,6 +83,29 @@ import type {
|
|
|
41
83
|
CapabilityCatalogItem,
|
|
42
84
|
CapabilityCatalogResponse,
|
|
43
85
|
CapabilityInstallation,
|
|
86
|
+
ApiIntegrationPreview,
|
|
87
|
+
ApiIntegrationOAuthStartRequest,
|
|
88
|
+
ApiIntegrationUninstallPreview,
|
|
89
|
+
InstallApiIntegrationRequest,
|
|
90
|
+
InstalledApiIntegration,
|
|
91
|
+
IntegrationFeatureMutationResult,
|
|
92
|
+
IntegrationFeatureRemovalResult,
|
|
93
|
+
IntegrationInstanceFeaturesResponse,
|
|
94
|
+
ListApiIntegrationPresetsResponse,
|
|
95
|
+
ListApiIntegrationsResponse,
|
|
96
|
+
MutateIntegrationFeatureRequest,
|
|
97
|
+
PreviewApiIntegrationRequest,
|
|
98
|
+
UninstallApiIntegrationRequest,
|
|
99
|
+
UninstallApiIntegrationResult,
|
|
100
|
+
UpsertIntegrationFeatureRequest,
|
|
101
|
+
PreviewPluginRequest,
|
|
102
|
+
PluginPreview,
|
|
103
|
+
InstallPluginRequest,
|
|
104
|
+
InstalledPlugin,
|
|
105
|
+
ListInstalledPluginsResponse,
|
|
106
|
+
PluginUninstallPreview,
|
|
107
|
+
UninstallPluginRequest,
|
|
108
|
+
UninstallPluginResult,
|
|
44
109
|
AddDocumentRequest,
|
|
45
110
|
CreateKnowledgeDropRequest,
|
|
46
111
|
MoveDocumentRequest,
|
|
@@ -54,6 +119,8 @@ import type {
|
|
|
54
119
|
CreateApiKeyRequest,
|
|
55
120
|
CreateApiKeyResponse,
|
|
56
121
|
CreateCapabilityCatalogItemRequest,
|
|
122
|
+
InstallSkillRequest,
|
|
123
|
+
InstalledSkill,
|
|
57
124
|
CreateCheckoutRequest,
|
|
58
125
|
CreateCheckoutResponse,
|
|
59
126
|
OpenGeniSlackBotInstallRequest,
|
|
@@ -91,7 +158,9 @@ import type {
|
|
|
91
158
|
GetPackResponse,
|
|
92
159
|
GitHubAppInfo,
|
|
93
160
|
GitHubRepositoriesResponse,
|
|
161
|
+
GoogleDriveBrowseResponse,
|
|
94
162
|
GoogleDriveDisconnectRequest,
|
|
163
|
+
SaveGoogleDriveIntegrationSourceRequest,
|
|
95
164
|
GoogleDriveLifecycleActionRequest,
|
|
96
165
|
KnowledgeMemory,
|
|
97
166
|
KnowledgeMemorySearchRequest,
|
|
@@ -101,23 +170,48 @@ import type {
|
|
|
101
170
|
MachinesResponse,
|
|
102
171
|
MetricSample,
|
|
103
172
|
MachineMetricsSeriesResponse,
|
|
173
|
+
RemoveEnrollmentRequest,
|
|
174
|
+
RemoveEnrollmentResponse,
|
|
104
175
|
// Bring-your-own-compute: the user-authenticated active-sandbox swap (M7).
|
|
105
176
|
SwapActiveSandboxRequest,
|
|
106
177
|
SwapActiveSandboxResponse,
|
|
107
178
|
ListWorkspaceMembersResponse,
|
|
179
|
+
InstallPackRequest,
|
|
180
|
+
PackInstallationPreview,
|
|
181
|
+
ListSlackUserLinkAccessRequestsResponse,
|
|
182
|
+
PrepareSlackUserLinkAccessRequest,
|
|
183
|
+
SlackUserLinkAccessMutationRequest,
|
|
184
|
+
SlackUserLinkAccessRequest,
|
|
185
|
+
ApproveSlackUserLinkAccessRequest,
|
|
108
186
|
PackInstallation,
|
|
187
|
+
PackUninstallPreview,
|
|
109
188
|
LatencyMode,
|
|
110
189
|
ReasoningEffort,
|
|
190
|
+
RetainedScreenshotDownload,
|
|
191
|
+
RetainedScreenshotDownloadOptions,
|
|
192
|
+
RetainedArtifactDownload,
|
|
193
|
+
RetainedArtifactDownloadOptions,
|
|
194
|
+
RetainedArtifactReference,
|
|
111
195
|
RetainedArtifactContent,
|
|
112
196
|
RetainedArtifactContentOptions,
|
|
113
197
|
RetainedArtifactMetadata,
|
|
198
|
+
UpdateVideoGenerationPolicyRequest,
|
|
199
|
+
VideoArtifactPlaybackSource,
|
|
200
|
+
VideoGenerationOperationSummary,
|
|
201
|
+
VideoGenerationPolicy,
|
|
202
|
+
WorkspaceVideoGenerationSettings,
|
|
114
203
|
RegisterCapabilityPackRequest,
|
|
115
204
|
ResourceRef,
|
|
205
|
+
PreviewPackInstallationRequest,
|
|
206
|
+
PreviewSkillImportRequest,
|
|
116
207
|
ScheduledTask,
|
|
117
208
|
ScheduledTaskRun,
|
|
118
209
|
Session,
|
|
119
210
|
SessionListResponse,
|
|
211
|
+
AgentTopologyPageResponse,
|
|
120
212
|
UpdateSessionPinRequest,
|
|
213
|
+
UninstallPackRequest,
|
|
214
|
+
UninstallPackResult,
|
|
121
215
|
SessionEvent,
|
|
122
216
|
SessionEventCompactResult,
|
|
123
217
|
SessionEventCompactResultOptions,
|
|
@@ -131,6 +225,7 @@ import type {
|
|
|
131
225
|
SyncSessionRealtimeLedgerResponse,
|
|
132
226
|
RenewSessionRealtimeRequest,
|
|
133
227
|
SessionMcpCredentialUpdateInput,
|
|
228
|
+
SubmittedTimelineAnnotation,
|
|
134
229
|
UpdateSessionMcpApprovalPolicyRequest,
|
|
135
230
|
UpdateSessionMcpApprovalPolicyResponse,
|
|
136
231
|
SessionQueueSnapshot,
|
|
@@ -159,6 +254,8 @@ import type {
|
|
|
159
254
|
// Channel-A structured services (P4.4).
|
|
160
255
|
FsListRequest,
|
|
161
256
|
FsListResponse,
|
|
257
|
+
FsListBatchRequest,
|
|
258
|
+
FsListBatchResponse,
|
|
162
259
|
FsReadRequest,
|
|
163
260
|
FsReadResponse,
|
|
164
261
|
FsWriteRequest,
|
|
@@ -173,6 +270,8 @@ import type {
|
|
|
173
270
|
GitStatusResponse,
|
|
174
271
|
GitDiffRequest,
|
|
175
272
|
GitDiffResponse,
|
|
273
|
+
GitReadBatchRequest,
|
|
274
|
+
GitReadBatchResponse,
|
|
176
275
|
GitLogRequest,
|
|
177
276
|
GitLogResponse,
|
|
178
277
|
GitShowRequest,
|
|
@@ -206,6 +305,7 @@ import type {
|
|
|
206
305
|
SetWorkspaceDefaultRigRequest,
|
|
207
306
|
UploadFileInput,
|
|
208
307
|
VariableSet,
|
|
308
|
+
VariableSetSecret,
|
|
209
309
|
VariableSetVariableMetadata,
|
|
210
310
|
Rig,
|
|
211
311
|
RigVersion,
|
|
@@ -217,12 +317,20 @@ import type {
|
|
|
217
317
|
WorkspaceRegisteredPack,
|
|
218
318
|
Workspace,
|
|
219
319
|
ListConnectionsResponse,
|
|
320
|
+
ListSlackInstallationBindingsResponse,
|
|
321
|
+
SlackInstallationBinding,
|
|
220
322
|
ConnectionResponse,
|
|
221
323
|
OAuthStartRequest,
|
|
222
324
|
OAuthStartResponse,
|
|
223
325
|
SocialConnection,
|
|
224
326
|
SocialOAuthStartRequest,
|
|
327
|
+
SkillImportPreview,
|
|
328
|
+
SkillUninstallPreview,
|
|
329
|
+
UninstallSkillRequest,
|
|
330
|
+
UninstallSkillResult,
|
|
225
331
|
} from "./types";
|
|
332
|
+
import { GENERATED_VIDEO_MAX_BYTES } from "./types";
|
|
333
|
+
import { parseRetainedGeneratedImageReference } from "./retained-artifacts";
|
|
226
334
|
import type {
|
|
227
335
|
ActivateWorkspaceInstructionPolicyRequest,
|
|
228
336
|
CreateWorkspaceInstructionPolicyDraftRequest,
|
|
@@ -239,6 +347,17 @@ import type {
|
|
|
239
347
|
WorkspaceInstructionPolicyOnboardingProposalListResponse,
|
|
240
348
|
WorkspaceInstructionPolicyRevision,
|
|
241
349
|
} from "./workspace-instruction-policies";
|
|
350
|
+
import type {
|
|
351
|
+
ActivateCompanyProfileRevisionRequest,
|
|
352
|
+
CompanyProfileDiffRequest,
|
|
353
|
+
CompanyProfileDiffResponse,
|
|
354
|
+
CompanyProfileListOptions,
|
|
355
|
+
CompanyProfileListResponse,
|
|
356
|
+
CompanyProfileMutationResponse,
|
|
357
|
+
CompanyProfileRevision,
|
|
358
|
+
RollbackCompanyProfileRequest,
|
|
359
|
+
UpdateCompanyProfileRequest,
|
|
360
|
+
} from "./company-profile";
|
|
242
361
|
import type {
|
|
243
362
|
WorkspaceStateExportResponse,
|
|
244
363
|
WorkspaceStateGetOptions,
|
|
@@ -264,6 +383,7 @@ import {
|
|
|
264
383
|
OPENGENI_API_CONTRACT_HEADER,
|
|
265
384
|
OPENGENI_API_CONTRACT_REVISION,
|
|
266
385
|
OPENGENI_CORRELATION_HEADER,
|
|
386
|
+
COMPUTER_SCREENSHOT_MAX_BYTES,
|
|
267
387
|
RETAINED_OUTPUT_MAX_PAGE_BYTES,
|
|
268
388
|
} from "./types";
|
|
269
389
|
|
|
@@ -305,6 +425,7 @@ export type OpenGeniRequestOptions = {
|
|
|
305
425
|
|
|
306
426
|
export type SendMessageInput = {
|
|
307
427
|
text: string;
|
|
428
|
+
annotations?: SubmittedTimelineAnnotation[];
|
|
308
429
|
/** System instructions scoped to this exact turn; never visible timeline text. */
|
|
309
430
|
turnInstructions?: string;
|
|
310
431
|
resources?: ResourceRef[];
|
|
@@ -323,6 +444,10 @@ export type SteerMessageResult = {
|
|
|
323
444
|
accepted: SessionEvent;
|
|
324
445
|
/** The exact turn created for this message in the same server transaction. */
|
|
325
446
|
turn: SessionTurn;
|
|
447
|
+
/** Number of live attempts durably asked to stop by this atomic Steer. */
|
|
448
|
+
interruptionCount?: number;
|
|
449
|
+
/** True when this response came from the command's immutable idempotency receipt. */
|
|
450
|
+
replay?: boolean;
|
|
326
451
|
};
|
|
327
452
|
|
|
328
453
|
export type TranscribeAudioInput = {
|
|
@@ -363,12 +488,17 @@ export class OpenGeniClient {
|
|
|
363
488
|
private readonly baseUrl: string;
|
|
364
489
|
private readonly options: OpenGeniClientOptions;
|
|
365
490
|
private readonly fetchImpl: FetchLike;
|
|
491
|
+
private readonly readInFlight = new Map<string, Promise<unknown>>();
|
|
492
|
+
private readonly readTrailing = new Map<string, Promise<unknown>>();
|
|
493
|
+
/** Resource-oriented Browser/Computer facade over this exact authenticated client. */
|
|
494
|
+
readonly interaction: OpenGeniInteractionClient;
|
|
366
495
|
|
|
367
496
|
constructor(options: OpenGeniClientOptions) {
|
|
368
497
|
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
369
498
|
this.options = options;
|
|
370
499
|
// Bind lazily so variable sets that polyfill fetch after module load work.
|
|
371
500
|
this.fetchImpl = options.fetch ?? ((input, init) => fetch(input, init));
|
|
501
|
+
this.interaction = new OpenGeniInteractionClient(this);
|
|
372
502
|
}
|
|
373
503
|
|
|
374
504
|
// --- Session lifecycle ---------------------------------------------------
|
|
@@ -385,8 +515,12 @@ export class OpenGeniClient {
|
|
|
385
515
|
input.audio instanceof File
|
|
386
516
|
? input.audio
|
|
387
517
|
: input.audio instanceof Uint8Array
|
|
388
|
-
? new File([Uint8Array.from(input.audio)], filename, {
|
|
389
|
-
|
|
518
|
+
? new File([Uint8Array.from(input.audio)], filename, {
|
|
519
|
+
type: input.mimeType,
|
|
520
|
+
})
|
|
521
|
+
: new File([input.audio], filename, {
|
|
522
|
+
type: input.mimeType || input.audio.type,
|
|
523
|
+
});
|
|
390
524
|
form.append("audio", audio, filename);
|
|
391
525
|
form.append("mimeType", input.mimeType);
|
|
392
526
|
if (input.durationSeconds !== undefined) {
|
|
@@ -396,7 +530,10 @@ export class OpenGeniClient {
|
|
|
396
530
|
try {
|
|
397
531
|
response = await this.fetchImpl(this.url(`/v1/workspaces/${workspaceId}/transcriptions`), {
|
|
398
532
|
method: "POST",
|
|
399
|
-
headers: {
|
|
533
|
+
headers: {
|
|
534
|
+
...this.headers(correlationId),
|
|
535
|
+
Accept: "application/json",
|
|
536
|
+
},
|
|
400
537
|
body: form,
|
|
401
538
|
...(input.signal ? { signal: input.signal } : {}),
|
|
402
539
|
});
|
|
@@ -405,7 +542,11 @@ export class OpenGeniClient {
|
|
|
405
542
|
throw mutationTransportError(correlationId);
|
|
406
543
|
}
|
|
407
544
|
assertApiContractResponse(response);
|
|
408
|
-
if (!response.ok)
|
|
545
|
+
if (!response.ok)
|
|
546
|
+
throw await apiErrorFromResponse(response, {
|
|
547
|
+
method: "POST",
|
|
548
|
+
correlationId,
|
|
549
|
+
});
|
|
409
550
|
await assertJsonResponse(response, { method: "POST", correlationId });
|
|
410
551
|
let body: unknown;
|
|
411
552
|
try {
|
|
@@ -509,7 +650,11 @@ export class OpenGeniClient {
|
|
|
509
650
|
throw mutationTransportError(correlationId);
|
|
510
651
|
}
|
|
511
652
|
assertApiContractResponse(response);
|
|
512
|
-
if (!response.ok)
|
|
653
|
+
if (!response.ok)
|
|
654
|
+
throw await apiErrorFromResponse(response, {
|
|
655
|
+
method: "PUT",
|
|
656
|
+
correlationId,
|
|
657
|
+
});
|
|
513
658
|
await assertJsonResponse(response, { method: "PUT", correlationId });
|
|
514
659
|
const body = await response.json().catch(() => null);
|
|
515
660
|
if (!isUploadTranscriptionRecordingChunkResponse(body)) {
|
|
@@ -603,11 +748,13 @@ export class OpenGeniClient {
|
|
|
603
748
|
);
|
|
604
749
|
}
|
|
605
750
|
|
|
606
|
-
async getSession(
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
751
|
+
async getSession(
|
|
752
|
+
workspaceId: string,
|
|
753
|
+
sessionId: string,
|
|
754
|
+
options: { fresh?: boolean } = {},
|
|
755
|
+
): Promise<Session> {
|
|
756
|
+
const path = `/v1/workspaces/${workspaceId}/sessions/${sessionId}`;
|
|
757
|
+
return await this.singleFlightRead(path, () => this.requestJson<Session>("GET", path), options);
|
|
611
758
|
}
|
|
612
759
|
|
|
613
760
|
async updateSession(
|
|
@@ -740,6 +887,32 @@ export class OpenGeniClient {
|
|
|
740
887
|
return response;
|
|
741
888
|
}
|
|
742
889
|
|
|
890
|
+
/** Compact, bounded workspace agent hierarchy page. */
|
|
891
|
+
async listAgentTopology(
|
|
892
|
+
workspaceId: string,
|
|
893
|
+
options: {
|
|
894
|
+
limit?: number;
|
|
895
|
+
parentSessionId?: string | null;
|
|
896
|
+
cursor?: string;
|
|
897
|
+
search?: string;
|
|
898
|
+
} = {},
|
|
899
|
+
): Promise<AgentTopologyPageResponse> {
|
|
900
|
+
const search = options.search?.trim();
|
|
901
|
+
return await this.requestJson<AgentTopologyPageResponse>(
|
|
902
|
+
"GET",
|
|
903
|
+
`/v1/workspaces/${workspaceId}/agent-topology`,
|
|
904
|
+
undefined,
|
|
905
|
+
{
|
|
906
|
+
...(options.limit !== undefined ? { limit: String(options.limit) } : {}),
|
|
907
|
+
...(options.parentSessionId === undefined
|
|
908
|
+
? {}
|
|
909
|
+
: { parentSessionId: options.parentSessionId ?? "null" }),
|
|
910
|
+
...(options.cursor ? { cursor: options.cursor } : {}),
|
|
911
|
+
...(search ? { search } : {}),
|
|
912
|
+
},
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
|
|
743
916
|
/** Set this authenticated member's personal workspace pin for a session. */
|
|
744
917
|
async updateSessionPin(
|
|
745
918
|
workspaceId: string,
|
|
@@ -754,12 +927,40 @@ export class OpenGeniClient {
|
|
|
754
927
|
}
|
|
755
928
|
|
|
756
929
|
async getSessionLineage(workspaceId: string, sessionId: string): Promise<SessionLineageResponse> {
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
930
|
+
const path = `/v1/workspaces/${workspaceId}/sessions/${sessionId}/lineage`;
|
|
931
|
+
return await this.singleFlightRead(path, () =>
|
|
932
|
+
this.requestJson<SessionLineageResponse>("GET", path),
|
|
760
933
|
);
|
|
761
934
|
}
|
|
762
935
|
|
|
936
|
+
private singleFlightRead<T>(
|
|
937
|
+
key: string,
|
|
938
|
+
read: () => Promise<T>,
|
|
939
|
+
options: { fresh?: boolean } = {},
|
|
940
|
+
): Promise<T> {
|
|
941
|
+
const existing = this.readInFlight.get(key);
|
|
942
|
+
if (existing) {
|
|
943
|
+
if (!options.fresh) return existing as Promise<T>;
|
|
944
|
+
const queued = this.readTrailing.get(key);
|
|
945
|
+
if (queued) return queued as Promise<T>;
|
|
946
|
+
const trailing = existing.then(
|
|
947
|
+
() => this.singleFlightRead(key, read),
|
|
948
|
+
() => this.singleFlightRead(key, read),
|
|
949
|
+
);
|
|
950
|
+
this.readTrailing.set(key, trailing);
|
|
951
|
+
const clear = () => {
|
|
952
|
+
if (this.readTrailing.get(key) === trailing) this.readTrailing.delete(key);
|
|
953
|
+
};
|
|
954
|
+
void trailing.then(clear, clear);
|
|
955
|
+
return trailing;
|
|
956
|
+
}
|
|
957
|
+
const promise = read().finally(() => {
|
|
958
|
+
if (this.readInFlight.get(key) === promise) this.readInFlight.delete(key);
|
|
959
|
+
});
|
|
960
|
+
this.readInFlight.set(key, promise);
|
|
961
|
+
return promise;
|
|
962
|
+
}
|
|
963
|
+
|
|
763
964
|
/** Negotiate one server-mediated connected-Codex GPT-Live V3 WebRTC call. */
|
|
764
965
|
async negotiateCodexRealtimeWebrtc(
|
|
765
966
|
workspaceId: string,
|
|
@@ -883,7 +1084,9 @@ export class OpenGeniClient {
|
|
|
883
1084
|
|
|
884
1085
|
/** Newest turn that durably emitted `turn.started`, or null before any admission. */
|
|
885
1086
|
async getLatestStartedTurn(workspaceId: string, sessionId: string): Promise<SessionTurn | null> {
|
|
886
|
-
const turns = await this.listTurns(workspaceId, sessionId, {
|
|
1087
|
+
const turns = await this.listTurns(workspaceId, sessionId, {
|
|
1088
|
+
latestStarted: true,
|
|
1089
|
+
});
|
|
887
1090
|
return turns[0] ?? null;
|
|
888
1091
|
}
|
|
889
1092
|
|
|
@@ -928,6 +1131,24 @@ export class OpenGeniClient {
|
|
|
928
1131
|
return response.samples;
|
|
929
1132
|
}
|
|
930
1133
|
|
|
1134
|
+
/**
|
|
1135
|
+
* Remove one connected self-hosted machine enrollment. The control-plane
|
|
1136
|
+
* operation works while the agent is offline, revokes future reconnects,
|
|
1137
|
+
* retains history, and returns a typed blocker when active route/lease or
|
|
1138
|
+
* recovery dependencies make removal unsafe. `idempotencyKey` is replay-safe.
|
|
1139
|
+
*/
|
|
1140
|
+
async removeEnrollment(
|
|
1141
|
+
workspaceId: string,
|
|
1142
|
+
enrollmentId: string,
|
|
1143
|
+
request: RemoveEnrollmentRequest = {},
|
|
1144
|
+
): Promise<RemoveEnrollmentResponse> {
|
|
1145
|
+
return await this.requestJson<RemoveEnrollmentResponse>(
|
|
1146
|
+
"POST",
|
|
1147
|
+
`/v1/workspaces/${workspaceId}/enrollments/${enrollmentId}/revoke`,
|
|
1148
|
+
request,
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
1151
|
+
|
|
931
1152
|
// --- Self-hosted enrollment UX (design 11) --------------------------------
|
|
932
1153
|
|
|
933
1154
|
/**
|
|
@@ -1350,9 +1571,9 @@ export class OpenGeniClient {
|
|
|
1350
1571
|
// --- Turn queue ------------------------------------------------------------
|
|
1351
1572
|
|
|
1352
1573
|
async getQueue(workspaceId: string, sessionId: string): Promise<SessionQueueSnapshot> {
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1574
|
+
const path = `/v1/workspaces/${workspaceId}/sessions/${sessionId}/queue`;
|
|
1575
|
+
return await this.singleFlightRead(path, () =>
|
|
1576
|
+
this.requestJson<SessionQueueSnapshot>("GET", path),
|
|
1356
1577
|
);
|
|
1357
1578
|
}
|
|
1358
1579
|
|
|
@@ -1469,7 +1690,11 @@ export class OpenGeniClient {
|
|
|
1469
1690
|
async cancelSession(
|
|
1470
1691
|
workspaceId: string,
|
|
1471
1692
|
sessionId: string,
|
|
1472
|
-
options: {
|
|
1693
|
+
options: {
|
|
1694
|
+
reason?: string;
|
|
1695
|
+
clientEventId?: string;
|
|
1696
|
+
expectedControlEtag?: string;
|
|
1697
|
+
} = {},
|
|
1473
1698
|
): Promise<SessionControlResponse> {
|
|
1474
1699
|
return await this.controlSession(workspaceId, sessionId, {
|
|
1475
1700
|
action: "cancel",
|
|
@@ -1614,10 +1839,8 @@ export class OpenGeniClient {
|
|
|
1614
1839
|
|
|
1615
1840
|
/** The session's goal. 404s when the session never had one. */
|
|
1616
1841
|
async getGoal(workspaceId: string, sessionId: string): Promise<SessionGoal> {
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
`/v1/workspaces/${workspaceId}/sessions/${sessionId}/goal`,
|
|
1620
|
-
);
|
|
1842
|
+
const path = `/v1/workspaces/${workspaceId}/sessions/${sessionId}/goal`;
|
|
1843
|
+
return await this.singleFlightRead(path, () => this.requestJson<SessionGoal>("GET", path));
|
|
1621
1844
|
}
|
|
1622
1845
|
|
|
1623
1846
|
async updateGoal(
|
|
@@ -1703,6 +1926,22 @@ export class OpenGeniClient {
|
|
|
1703
1926
|
);
|
|
1704
1927
|
}
|
|
1705
1928
|
|
|
1929
|
+
/** FileSystem: hydrate several independent directories behind one sandbox lease. */
|
|
1930
|
+
async fsListBatch(
|
|
1931
|
+
workspaceId: string,
|
|
1932
|
+
sessionId: string,
|
|
1933
|
+
request: FsListBatchRequest,
|
|
1934
|
+
options: OpenGeniRequestOptions = {},
|
|
1935
|
+
): Promise<FsListBatchResponse> {
|
|
1936
|
+
return await this.requestJson<FsListBatchResponse>(
|
|
1937
|
+
"POST",
|
|
1938
|
+
`/v1/workspaces/${workspaceId}/sessions/${sessionId}/fs/list-batch`,
|
|
1939
|
+
request,
|
|
1940
|
+
{},
|
|
1941
|
+
options,
|
|
1942
|
+
);
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1706
1945
|
/** FileSystem: read a file (text or base64; binary-safe, size-capped). */
|
|
1707
1946
|
async fsRead(
|
|
1708
1947
|
workspaceId: string,
|
|
@@ -1803,6 +2042,22 @@ export class OpenGeniClient {
|
|
|
1803
2042
|
);
|
|
1804
2043
|
}
|
|
1805
2044
|
|
|
2045
|
+
/** Git: read status and optional diffs for several repositories behind one sandbox lease. */
|
|
2046
|
+
async gitReadBatch(
|
|
2047
|
+
workspaceId: string,
|
|
2048
|
+
sessionId: string,
|
|
2049
|
+
request: GitReadBatchRequest,
|
|
2050
|
+
options: OpenGeniRequestOptions = {},
|
|
2051
|
+
): Promise<GitReadBatchResponse> {
|
|
2052
|
+
return await this.requestJson<GitReadBatchResponse>(
|
|
2053
|
+
"POST",
|
|
2054
|
+
`/v1/workspaces/${workspaceId}/sessions/${sessionId}/git/read-batch`,
|
|
2055
|
+
request,
|
|
2056
|
+
{},
|
|
2057
|
+
options,
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
2060
|
+
|
|
1806
2061
|
/** Git: commit log. */
|
|
1807
2062
|
async gitLog(
|
|
1808
2063
|
workspaceId: string,
|
|
@@ -1976,13 +2231,11 @@ export class OpenGeniClient {
|
|
|
1976
2231
|
}
|
|
1977
2232
|
|
|
1978
2233
|
/** Attach a viewer holder (refcounted liveness — keeps the box warm while
|
|
1979
|
-
* watched/used), spinning the box up in-process when cold
|
|
1980
|
-
*
|
|
1981
|
-
*
|
|
1982
|
-
*
|
|
1983
|
-
*
|
|
1984
|
-
* (`desktop` omitted/false) warms the box + mints the pty-ws terminal cell with
|
|
1985
|
-
* NO consent gate. An omitted `viewerId` mints a fresh one. */
|
|
2234
|
+
* watched/used), spinning the box up in-process when cold. Exact plane flags
|
|
2235
|
+
* mint only the requested short-lived credentials and enforce that plane's
|
|
2236
|
+
* permission. `desktop:true` alone carries the un-redacted/shared consent
|
|
2237
|
+
* gate. An entirely omitted plane set retains the legacy terminal-only
|
|
2238
|
+
* meaning; current clients should send all three flags. */
|
|
1986
2239
|
async attachViewer(
|
|
1987
2240
|
workspaceId: string,
|
|
1988
2241
|
sessionId: string,
|
|
@@ -2019,184 +2272,669 @@ export class OpenGeniClient {
|
|
|
2019
2272
|
);
|
|
2020
2273
|
}
|
|
2021
2274
|
|
|
2022
|
-
// ---
|
|
2023
|
-
|
|
2024
|
-
/**
|
|
2025
|
-
* The deployment's public client bootstrap config: the host-exposed models
|
|
2026
|
-
* (provider-grouped in `models`, flat in `allowedModels` for back-compat),
|
|
2027
|
-
* reasoning efforts, MCP servers, file-upload limits, and how the client is
|
|
2028
|
-
* expected to authenticate. Drives a composer's model picker without prior
|
|
2029
|
-
* knowledge of the host setup; safe to call before any auth is established.
|
|
2030
|
-
*/
|
|
2031
|
-
async getClientConfig(): Promise<ClientConfig> {
|
|
2032
|
-
const config = await this.requestJson<ClientConfig>("GET", "/v1/config/client");
|
|
2033
|
-
if (config.apiContractRevision !== OPENGENI_API_CONTRACT_REVISION) {
|
|
2034
|
-
throw new OpenGeniApiContractMismatchError(
|
|
2035
|
-
OPENGENI_API_CONTRACT_REVISION,
|
|
2036
|
-
String(config.apiContractRevision || "(missing)"),
|
|
2037
|
-
);
|
|
2038
|
-
}
|
|
2039
|
-
return config;
|
|
2040
|
-
}
|
|
2275
|
+
// --- Browser / Computer interaction resources --------------------------------
|
|
2041
2276
|
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2277
|
+
async listAttachedBrowsers(
|
|
2278
|
+
workspaceId: string,
|
|
2279
|
+
options: AttachedBrowserDeviceListOptions = {},
|
|
2280
|
+
): Promise<AttachedBrowserDeviceListResponse> {
|
|
2281
|
+
return await this.requestJson<AttachedBrowserDeviceListResponse>(
|
|
2045
2282
|
"GET",
|
|
2046
|
-
`/v1/workspaces/${workspaceId}/
|
|
2283
|
+
`/v1/workspaces/${workspaceId}/attached-browsers`,
|
|
2284
|
+
undefined,
|
|
2285
|
+
options.includeDisconnected ? { includeDisconnected: "true" } : {},
|
|
2286
|
+
options,
|
|
2047
2287
|
);
|
|
2048
2288
|
}
|
|
2049
2289
|
|
|
2050
|
-
|
|
2051
|
-
async getWorkspaceRealtimeModelCatalog(
|
|
2290
|
+
async getAttachedBrowser(
|
|
2052
2291
|
workspaceId: string,
|
|
2053
|
-
|
|
2054
|
-
|
|
2292
|
+
deviceId: string,
|
|
2293
|
+
options: OpenGeniRequestOptions = {},
|
|
2294
|
+
): Promise<AttachedBrowserDevice> {
|
|
2295
|
+
return await this.requestJson<AttachedBrowserDevice>(
|
|
2055
2296
|
"GET",
|
|
2056
|
-
`/v1/workspaces/${workspaceId}/
|
|
2297
|
+
`/v1/workspaces/${workspaceId}/attached-browsers/${encodeURIComponent(deviceId)}`,
|
|
2298
|
+
undefined,
|
|
2299
|
+
{},
|
|
2300
|
+
options,
|
|
2057
2301
|
);
|
|
2058
2302
|
}
|
|
2059
2303
|
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
}
|
|
2072
|
-
|
|
2073
|
-
async getWorkspace(workspaceId: string): Promise<Workspace> {
|
|
2074
|
-
return await this.requestJson<Workspace>("GET", `/v1/workspaces/${workspaceId}`);
|
|
2304
|
+
async listBrowserIdentities(
|
|
2305
|
+
workspaceId: string,
|
|
2306
|
+
options: BrowserIdentityListOptions = {},
|
|
2307
|
+
): Promise<BrowserIdentityListResponse> {
|
|
2308
|
+
return await this.requestJson<BrowserIdentityListResponse>(
|
|
2309
|
+
"GET",
|
|
2310
|
+
`/v1/workspaces/${workspaceId}/browser-identities`,
|
|
2311
|
+
undefined,
|
|
2312
|
+
options.includeArchived ? { includeArchived: "true" } : {},
|
|
2313
|
+
options,
|
|
2314
|
+
);
|
|
2075
2315
|
}
|
|
2076
2316
|
|
|
2077
|
-
|
|
2078
|
-
async getWorkspaceState(
|
|
2317
|
+
async getBrowserIdentity(
|
|
2079
2318
|
workspaceId: string,
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
2085
|
-
return await this.requestJson<WorkspaceStateResponse>(
|
|
2319
|
+
identityId: string,
|
|
2320
|
+
options: OpenGeniRequestOptions = {},
|
|
2321
|
+
): Promise<BrowserIdentity> {
|
|
2322
|
+
return await this.requestJson<BrowserIdentity>(
|
|
2086
2323
|
"GET",
|
|
2087
|
-
`/v1/workspaces/${workspaceId}/
|
|
2324
|
+
`/v1/workspaces/${workspaceId}/browser-identities/${encodeURIComponent(identityId)}`,
|
|
2325
|
+
undefined,
|
|
2326
|
+
{},
|
|
2327
|
+
options,
|
|
2088
2328
|
);
|
|
2089
2329
|
}
|
|
2090
2330
|
|
|
2091
|
-
|
|
2092
|
-
async exportWorkspaceState(
|
|
2331
|
+
async createBrowserIdentity(
|
|
2093
2332
|
workspaceId: string,
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2333
|
+
request: CreateBrowserIdentityRequest,
|
|
2334
|
+
options: OpenGeniRequestOptions = {},
|
|
2335
|
+
): Promise<BrowserIdentityMutationResponse> {
|
|
2336
|
+
return await this.requestJson<BrowserIdentityMutationResponse>(
|
|
2337
|
+
"POST",
|
|
2338
|
+
`/v1/workspaces/${workspaceId}/browser-identities`,
|
|
2339
|
+
request,
|
|
2340
|
+
{},
|
|
2341
|
+
options,
|
|
2102
2342
|
);
|
|
2103
2343
|
}
|
|
2104
2344
|
|
|
2105
|
-
async
|
|
2106
|
-
|
|
2345
|
+
async listBrowserRevisions(
|
|
2346
|
+
workspaceId: string,
|
|
2347
|
+
identityId: string,
|
|
2348
|
+
options: OpenGeniRequestOptions = {},
|
|
2349
|
+
): Promise<BrowserRevisionListResponse> {
|
|
2350
|
+
return await this.requestJson<BrowserRevisionListResponse>(
|
|
2351
|
+
"GET",
|
|
2352
|
+
`/v1/workspaces/${workspaceId}/browser-identities/${encodeURIComponent(identityId)}/revisions`,
|
|
2353
|
+
undefined,
|
|
2354
|
+
{},
|
|
2355
|
+
options,
|
|
2356
|
+
);
|
|
2107
2357
|
}
|
|
2108
2358
|
|
|
2109
|
-
/**
|
|
2110
|
-
|
|
2359
|
+
/** Workspace-wide BrowserSession inventory. Associations express relevance,
|
|
2360
|
+
* not access: peers and child agents intentionally remain discoverable. */
|
|
2361
|
+
async listBrowserSessions(
|
|
2111
2362
|
workspaceId: string,
|
|
2112
|
-
options:
|
|
2113
|
-
): Promise<
|
|
2114
|
-
|
|
2115
|
-
if (options.kind !== undefined) params.set("kind", options.kind);
|
|
2116
|
-
if (options.scope !== undefined) params.set("scope", options.scope);
|
|
2117
|
-
if (options.roleKey !== undefined) params.set("roleKey", options.roleKey);
|
|
2118
|
-
if (options.afterRevision !== undefined) {
|
|
2119
|
-
params.set("afterRevision", String(options.afterRevision));
|
|
2120
|
-
}
|
|
2121
|
-
if (options.limit !== undefined) params.set("limit", String(options.limit));
|
|
2122
|
-
const query = params.toString();
|
|
2123
|
-
return await this.requestJson<WorkspaceInstructionPolicyListResponse>(
|
|
2363
|
+
options: OpenGeniRequestOptions = {},
|
|
2364
|
+
): Promise<BrowserSessionListResponse> {
|
|
2365
|
+
return await this.requestJson<BrowserSessionListResponse>(
|
|
2124
2366
|
"GET",
|
|
2125
|
-
`/v1/workspaces/${workspaceId}/
|
|
2367
|
+
`/v1/workspaces/${workspaceId}/browser-sessions`,
|
|
2368
|
+
undefined,
|
|
2369
|
+
{},
|
|
2370
|
+
options,
|
|
2126
2371
|
);
|
|
2127
2372
|
}
|
|
2128
2373
|
|
|
2129
|
-
async
|
|
2374
|
+
async getBrowserSession(
|
|
2130
2375
|
workspaceId: string,
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2376
|
+
browserSessionId: string,
|
|
2377
|
+
options: OpenGeniRequestOptions = {},
|
|
2378
|
+
): Promise<BrowserSession> {
|
|
2379
|
+
return await this.requestJson<BrowserSession>(
|
|
2134
2380
|
"GET",
|
|
2135
|
-
`/v1/workspaces/${workspaceId}/
|
|
2381
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}`,
|
|
2382
|
+
undefined,
|
|
2383
|
+
{},
|
|
2384
|
+
options,
|
|
2136
2385
|
);
|
|
2137
2386
|
}
|
|
2138
2387
|
|
|
2139
|
-
async
|
|
2388
|
+
async createBrowserSession(
|
|
2140
2389
|
workspaceId: string,
|
|
2141
|
-
request:
|
|
2142
|
-
|
|
2143
|
-
|
|
2390
|
+
request: CreateBrowserSessionRequest,
|
|
2391
|
+
options: OpenGeniRequestOptions = {},
|
|
2392
|
+
): Promise<BrowserSessionMutationResponse> {
|
|
2393
|
+
return await this.requestJson<BrowserSessionMutationResponse>(
|
|
2144
2394
|
"POST",
|
|
2145
|
-
`/v1/workspaces/${workspaceId}/
|
|
2395
|
+
`/v1/workspaces/${workspaceId}/browser-sessions`,
|
|
2146
2396
|
request,
|
|
2397
|
+
{},
|
|
2398
|
+
options,
|
|
2147
2399
|
);
|
|
2148
2400
|
}
|
|
2149
2401
|
|
|
2150
|
-
|
|
2151
|
-
async listWorkspaceInstructionPolicyOnboardingProposals(
|
|
2402
|
+
async listBrowserTargets(
|
|
2152
2403
|
workspaceId: string,
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
const query = params.toString();
|
|
2158
|
-
return await this.requestJson<WorkspaceInstructionPolicyOnboardingProposalListResponse>(
|
|
2404
|
+
browserSessionId: string,
|
|
2405
|
+
options: OpenGeniRequestOptions = {},
|
|
2406
|
+
): Promise<BrowserTargetListResponse> {
|
|
2407
|
+
return await this.requestJson<BrowserTargetListResponse>(
|
|
2159
2408
|
"GET",
|
|
2160
|
-
`/v1/workspaces/${workspaceId}/
|
|
2409
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/targets`,
|
|
2410
|
+
undefined,
|
|
2411
|
+
{},
|
|
2412
|
+
options,
|
|
2161
2413
|
);
|
|
2162
2414
|
}
|
|
2163
2415
|
|
|
2164
|
-
|
|
2165
|
-
async createWorkspaceInstructionPolicyOnboardingProposal(
|
|
2416
|
+
async openBrowserTarget(
|
|
2166
2417
|
workspaceId: string,
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2418
|
+
browserSessionId: string,
|
|
2419
|
+
request: BrowserOpenTargetRequest = {},
|
|
2420
|
+
options: OpenGeniRequestOptions = {},
|
|
2421
|
+
): Promise<BrowserTarget> {
|
|
2422
|
+
return await this.requestJson<BrowserTarget>(
|
|
2170
2423
|
"POST",
|
|
2171
|
-
`/v1/workspaces/${workspaceId}/
|
|
2424
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/targets`,
|
|
2172
2425
|
request,
|
|
2426
|
+
{},
|
|
2427
|
+
options,
|
|
2173
2428
|
);
|
|
2174
2429
|
}
|
|
2175
2430
|
|
|
2176
|
-
|
|
2177
|
-
async importLegacyWorkspaceInstructionPolicyDraft(
|
|
2431
|
+
async selectBrowserTarget(
|
|
2178
2432
|
workspaceId: string,
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2433
|
+
browserSessionId: string,
|
|
2434
|
+
targetId: string,
|
|
2435
|
+
options: OpenGeniRequestOptions = {},
|
|
2436
|
+
): Promise<BrowserTarget> {
|
|
2437
|
+
return await this.requestJson<BrowserTarget>(
|
|
2182
2438
|
"POST",
|
|
2183
|
-
`/v1/workspaces/${workspaceId}/
|
|
2184
|
-
|
|
2439
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/targets/${encodeURIComponent(targetId)}/select`,
|
|
2440
|
+
{},
|
|
2441
|
+
{},
|
|
2442
|
+
options,
|
|
2185
2443
|
);
|
|
2186
2444
|
}
|
|
2187
2445
|
|
|
2188
|
-
async
|
|
2446
|
+
async closeBrowserTarget(
|
|
2189
2447
|
workspaceId: string,
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2448
|
+
browserSessionId: string,
|
|
2449
|
+
targetId: string,
|
|
2450
|
+
options: OpenGeniRequestOptions = {},
|
|
2451
|
+
): Promise<BrowserTargetListResponse> {
|
|
2452
|
+
return await this.requestJson<BrowserTargetListResponse>(
|
|
2453
|
+
"DELETE",
|
|
2454
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/targets/${encodeURIComponent(targetId)}`,
|
|
2455
|
+
undefined,
|
|
2456
|
+
{},
|
|
2457
|
+
options,
|
|
2458
|
+
);
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
async observeBrowserTarget(
|
|
2462
|
+
workspaceId: string,
|
|
2463
|
+
browserSessionId: string,
|
|
2464
|
+
targetId: string,
|
|
2465
|
+
options: OpenGeniRequestOptions = {},
|
|
2466
|
+
): Promise<BrowserObservation> {
|
|
2467
|
+
return await this.requestJson<BrowserObservation>(
|
|
2468
|
+
"GET",
|
|
2469
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/targets/${encodeURIComponent(targetId)}/observation`,
|
|
2470
|
+
undefined,
|
|
2471
|
+
{},
|
|
2472
|
+
options,
|
|
2473
|
+
);
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
async actInBrowser(
|
|
2477
|
+
workspaceId: string,
|
|
2478
|
+
browserSessionId: string,
|
|
2479
|
+
request: BrowserActionRequest,
|
|
2480
|
+
options: OpenGeniRequestOptions = {},
|
|
2481
|
+
): Promise<BrowserActionReceipt> {
|
|
2482
|
+
return await this.requestJson<BrowserActionReceipt>(
|
|
2483
|
+
"POST",
|
|
2484
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/actions`,
|
|
2485
|
+
request,
|
|
2486
|
+
{},
|
|
2487
|
+
options,
|
|
2488
|
+
);
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
async getBrowserActionReceipt(
|
|
2492
|
+
workspaceId: string,
|
|
2493
|
+
browserSessionId: string,
|
|
2494
|
+
operationId: string,
|
|
2495
|
+
options: OpenGeniRequestOptions = {},
|
|
2496
|
+
): Promise<BrowserActionReceipt> {
|
|
2497
|
+
return await this.requestJson<BrowserActionReceipt>(
|
|
2498
|
+
"GET",
|
|
2499
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/operations/${encodeURIComponent(operationId)}`,
|
|
2500
|
+
undefined,
|
|
2501
|
+
{},
|
|
2502
|
+
options,
|
|
2503
|
+
);
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
async listBrowserDiagnostics(
|
|
2507
|
+
workspaceId: string,
|
|
2508
|
+
browserSessionId: string,
|
|
2509
|
+
targetId: string,
|
|
2510
|
+
options: BrowserDiagnosticsOptions = {},
|
|
2511
|
+
): Promise<BrowserDiagnosticBatch> {
|
|
2512
|
+
return await this.requestJson<BrowserDiagnosticBatch>(
|
|
2513
|
+
"GET",
|
|
2514
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/targets/${encodeURIComponent(targetId)}/diagnostics`,
|
|
2515
|
+
undefined,
|
|
2516
|
+
{
|
|
2517
|
+
...(options.kinds?.length ? { kinds: options.kinds.join(",") } : {}),
|
|
2518
|
+
...(options.after !== undefined ? { after: String(options.after) } : {}),
|
|
2519
|
+
...(options.limit !== undefined ? { limit: String(options.limit) } : {}),
|
|
2520
|
+
},
|
|
2521
|
+
options.signal ? { signal: options.signal } : {},
|
|
2522
|
+
);
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
async attachBrowserSession(
|
|
2526
|
+
workspaceId: string,
|
|
2527
|
+
browserSessionId: string,
|
|
2528
|
+
request: BrowserSessionAttachmentRequest,
|
|
2529
|
+
options: OpenGeniRequestOptions = {},
|
|
2530
|
+
): Promise<BrowserSessionAttachment> {
|
|
2531
|
+
return await this.requestJson<BrowserSessionAttachment>(
|
|
2532
|
+
"POST",
|
|
2533
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/attachments`,
|
|
2534
|
+
request,
|
|
2535
|
+
{},
|
|
2536
|
+
options,
|
|
2537
|
+
);
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
async heartbeatBrowserSession(
|
|
2541
|
+
workspaceId: string,
|
|
2542
|
+
browserSessionId: string,
|
|
2543
|
+
options: OpenGeniRequestOptions = {},
|
|
2544
|
+
): Promise<BrowserSessionHeartbeatResponse> {
|
|
2545
|
+
return await this.requestJson<BrowserSessionHeartbeatResponse>(
|
|
2546
|
+
"POST",
|
|
2547
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/heartbeat`,
|
|
2548
|
+
{},
|
|
2549
|
+
{},
|
|
2550
|
+
options,
|
|
2551
|
+
);
|
|
2552
|
+
}
|
|
2553
|
+
|
|
2554
|
+
async publishBrowserRevision(
|
|
2555
|
+
workspaceId: string,
|
|
2556
|
+
browserSessionId: string,
|
|
2557
|
+
request: PublishBrowserRevisionRequest,
|
|
2558
|
+
options: OpenGeniRequestOptions = {},
|
|
2559
|
+
): Promise<PublishBrowserRevisionResponse> {
|
|
2560
|
+
return await this.requestJson<PublishBrowserRevisionResponse>(
|
|
2561
|
+
"POST",
|
|
2562
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/revisions`,
|
|
2563
|
+
request,
|
|
2564
|
+
{},
|
|
2565
|
+
options,
|
|
2566
|
+
);
|
|
2567
|
+
}
|
|
2568
|
+
|
|
2569
|
+
async suspendBrowserSession(
|
|
2570
|
+
workspaceId: string,
|
|
2571
|
+
browserSessionId: string,
|
|
2572
|
+
request: BrowserSessionLifecycleRequest,
|
|
2573
|
+
options: OpenGeniRequestOptions = {},
|
|
2574
|
+
): Promise<BrowserSessionMutationResponse> {
|
|
2575
|
+
return await this.requestJson<BrowserSessionMutationResponse>(
|
|
2576
|
+
"POST",
|
|
2577
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/suspend`,
|
|
2578
|
+
request,
|
|
2579
|
+
{},
|
|
2580
|
+
options,
|
|
2581
|
+
);
|
|
2582
|
+
}
|
|
2583
|
+
|
|
2584
|
+
async resumeBrowserSession(
|
|
2585
|
+
workspaceId: string,
|
|
2586
|
+
browserSessionId: string,
|
|
2587
|
+
request: BrowserSessionLifecycleRequest,
|
|
2588
|
+
options: OpenGeniRequestOptions = {},
|
|
2589
|
+
): Promise<BrowserSessionMutationResponse> {
|
|
2590
|
+
return await this.requestJson<BrowserSessionMutationResponse>(
|
|
2591
|
+
"POST",
|
|
2592
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/resume`,
|
|
2593
|
+
request,
|
|
2594
|
+
{},
|
|
2595
|
+
options,
|
|
2596
|
+
);
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
async endBrowserSession(
|
|
2600
|
+
workspaceId: string,
|
|
2601
|
+
browserSessionId: string,
|
|
2602
|
+
request: BrowserSessionLifecycleRequest,
|
|
2603
|
+
options: OpenGeniRequestOptions = {},
|
|
2604
|
+
): Promise<BrowserSessionMutationResponse> {
|
|
2605
|
+
return await this.requestJson<BrowserSessionMutationResponse>(
|
|
2606
|
+
"POST",
|
|
2607
|
+
`/v1/workspaces/${workspaceId}/browser-sessions/${encodeURIComponent(browserSessionId)}/end`,
|
|
2608
|
+
request,
|
|
2609
|
+
{},
|
|
2610
|
+
options,
|
|
2611
|
+
);
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2614
|
+
/** Workspace-wide ComputerSession inventory. Associations express
|
|
2615
|
+
* relevance, not access; peer sessions intentionally remain discoverable. */
|
|
2616
|
+
async listComputerSessions(
|
|
2617
|
+
workspaceId: string,
|
|
2618
|
+
options: OpenGeniRequestOptions = {},
|
|
2619
|
+
): Promise<ComputerSessionListResponse> {
|
|
2620
|
+
return await this.requestJson<ComputerSessionListResponse>(
|
|
2621
|
+
"GET",
|
|
2622
|
+
`/v1/workspaces/${workspaceId}/computer-sessions`,
|
|
2623
|
+
undefined,
|
|
2624
|
+
{},
|
|
2625
|
+
options,
|
|
2626
|
+
);
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
async getComputerSession(
|
|
2630
|
+
workspaceId: string,
|
|
2631
|
+
computerSessionId: string,
|
|
2632
|
+
options: OpenGeniRequestOptions = {},
|
|
2633
|
+
): Promise<ComputerSession> {
|
|
2634
|
+
return await this.requestJson<ComputerSession>(
|
|
2635
|
+
"GET",
|
|
2636
|
+
`/v1/workspaces/${workspaceId}/computer-sessions/${encodeURIComponent(computerSessionId)}`,
|
|
2637
|
+
undefined,
|
|
2638
|
+
{},
|
|
2639
|
+
options,
|
|
2640
|
+
);
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
async createComputerSession(
|
|
2644
|
+
workspaceId: string,
|
|
2645
|
+
request: CreateComputerSessionRequest,
|
|
2646
|
+
options: OpenGeniRequestOptions = {},
|
|
2647
|
+
): Promise<ComputerSessionMutationResponse> {
|
|
2648
|
+
return await this.requestJson<ComputerSessionMutationResponse>(
|
|
2649
|
+
"POST",
|
|
2650
|
+
`/v1/workspaces/${workspaceId}/computer-sessions`,
|
|
2651
|
+
request,
|
|
2652
|
+
{},
|
|
2653
|
+
options,
|
|
2654
|
+
);
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2657
|
+
async listComputerTargets(
|
|
2658
|
+
workspaceId: string,
|
|
2659
|
+
computerSessionId: string,
|
|
2660
|
+
options: OpenGeniRequestOptions = {},
|
|
2661
|
+
): Promise<ComputerTargetListResponse> {
|
|
2662
|
+
return await this.requestJson<ComputerTargetListResponse>(
|
|
2663
|
+
"GET",
|
|
2664
|
+
`/v1/workspaces/${workspaceId}/computer-sessions/${encodeURIComponent(computerSessionId)}/targets`,
|
|
2665
|
+
undefined,
|
|
2666
|
+
{},
|
|
2667
|
+
options,
|
|
2668
|
+
);
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
async observeComputerTarget(
|
|
2672
|
+
workspaceId: string,
|
|
2673
|
+
computerSessionId: string,
|
|
2674
|
+
targetId: string,
|
|
2675
|
+
options: OpenGeniRequestOptions = {},
|
|
2676
|
+
): Promise<ComputerObservation> {
|
|
2677
|
+
return await this.requestJson<ComputerObservation>(
|
|
2678
|
+
"GET",
|
|
2679
|
+
`/v1/workspaces/${workspaceId}/computer-sessions/${encodeURIComponent(computerSessionId)}/targets/${encodeURIComponent(targetId)}/observation`,
|
|
2680
|
+
undefined,
|
|
2681
|
+
{},
|
|
2682
|
+
options,
|
|
2683
|
+
);
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
async actInComputer(
|
|
2687
|
+
workspaceId: string,
|
|
2688
|
+
computerSessionId: string,
|
|
2689
|
+
request: ComputerActionRequest,
|
|
2690
|
+
options: OpenGeniRequestOptions = {},
|
|
2691
|
+
): Promise<ComputerActionReceipt> {
|
|
2692
|
+
return await this.requestJson<ComputerActionReceipt>(
|
|
2693
|
+
"POST",
|
|
2694
|
+
`/v1/workspaces/${workspaceId}/computer-sessions/${encodeURIComponent(computerSessionId)}/actions`,
|
|
2695
|
+
request,
|
|
2696
|
+
{},
|
|
2697
|
+
options,
|
|
2698
|
+
);
|
|
2699
|
+
}
|
|
2700
|
+
|
|
2701
|
+
async getComputerActionReceipt(
|
|
2702
|
+
workspaceId: string,
|
|
2703
|
+
computerSessionId: string,
|
|
2704
|
+
operationId: string,
|
|
2705
|
+
options: OpenGeniRequestOptions = {},
|
|
2706
|
+
): Promise<ComputerActionReceipt> {
|
|
2707
|
+
return await this.requestJson<ComputerActionReceipt>(
|
|
2708
|
+
"GET",
|
|
2709
|
+
`/v1/workspaces/${workspaceId}/computer-sessions/${encodeURIComponent(computerSessionId)}/operations/${encodeURIComponent(operationId)}`,
|
|
2710
|
+
undefined,
|
|
2711
|
+
{},
|
|
2712
|
+
options,
|
|
2713
|
+
);
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
async attachComputerSession(
|
|
2717
|
+
workspaceId: string,
|
|
2718
|
+
computerSessionId: string,
|
|
2719
|
+
request: ComputerSessionAttachmentRequest,
|
|
2720
|
+
options: OpenGeniRequestOptions = {},
|
|
2721
|
+
): Promise<ComputerSessionAttachment> {
|
|
2722
|
+
return await this.requestJson<ComputerSessionAttachment>(
|
|
2723
|
+
"POST",
|
|
2724
|
+
`/v1/workspaces/${workspaceId}/computer-sessions/${encodeURIComponent(computerSessionId)}/attachments`,
|
|
2725
|
+
request,
|
|
2726
|
+
{},
|
|
2727
|
+
options,
|
|
2728
|
+
);
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2731
|
+
async heartbeatComputerSession(
|
|
2732
|
+
workspaceId: string,
|
|
2733
|
+
computerSessionId: string,
|
|
2734
|
+
options: OpenGeniRequestOptions = {},
|
|
2735
|
+
): Promise<ComputerSessionHeartbeatResponse> {
|
|
2736
|
+
return await this.requestJson<ComputerSessionHeartbeatResponse>(
|
|
2737
|
+
"POST",
|
|
2738
|
+
`/v1/workspaces/${workspaceId}/computer-sessions/${encodeURIComponent(computerSessionId)}/heartbeat`,
|
|
2739
|
+
{},
|
|
2740
|
+
{},
|
|
2741
|
+
options,
|
|
2742
|
+
);
|
|
2743
|
+
}
|
|
2744
|
+
|
|
2745
|
+
async endComputerSession(
|
|
2746
|
+
workspaceId: string,
|
|
2747
|
+
computerSessionId: string,
|
|
2748
|
+
request: ComputerSessionLifecycleRequest,
|
|
2749
|
+
options: OpenGeniRequestOptions = {},
|
|
2750
|
+
): Promise<ComputerSessionMutationResponse> {
|
|
2751
|
+
return await this.requestJson<ComputerSessionMutationResponse>(
|
|
2752
|
+
"POST",
|
|
2753
|
+
`/v1/workspaces/${workspaceId}/computer-sessions/${encodeURIComponent(computerSessionId)}/end`,
|
|
2754
|
+
request,
|
|
2755
|
+
{},
|
|
2756
|
+
options,
|
|
2757
|
+
);
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
// --- Access + workspaces -----------------------------------------------------
|
|
2761
|
+
|
|
2762
|
+
/**
|
|
2763
|
+
* The deployment's public client bootstrap config: the host-exposed models
|
|
2764
|
+
* (provider-grouped in `models`, flat in `allowedModels` for back-compat),
|
|
2765
|
+
* reasoning efforts, MCP servers, file-upload limits, and how the client is
|
|
2766
|
+
* expected to authenticate. Drives a composer's model picker without prior
|
|
2767
|
+
* knowledge of the host setup; safe to call before any auth is established.
|
|
2768
|
+
*/
|
|
2769
|
+
async getClientConfig(): Promise<ClientConfig> {
|
|
2770
|
+
const config = await this.requestJson<ClientConfig>("GET", "/v1/config/client");
|
|
2771
|
+
if (config.apiContractRevision !== OPENGENI_API_CONTRACT_REVISION) {
|
|
2772
|
+
throw new OpenGeniApiContractMismatchError(
|
|
2773
|
+
OPENGENI_API_CONTRACT_REVISION,
|
|
2774
|
+
String(config.apiContractRevision || "(missing)"),
|
|
2775
|
+
);
|
|
2776
|
+
}
|
|
2777
|
+
return config;
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
/** Authenticated model definitions plus workspace-specific selectability. */
|
|
2781
|
+
async getWorkspaceModelCatalog(workspaceId: string): Promise<WorkspaceModelCatalogResponse> {
|
|
2782
|
+
return await this.requestJson<WorkspaceModelCatalogResponse>(
|
|
2783
|
+
"GET",
|
|
2784
|
+
`/v1/workspaces/${workspaceId}/model-catalog`,
|
|
2785
|
+
);
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
/** Authenticated realtime voice models and credential readiness. */
|
|
2789
|
+
async getWorkspaceRealtimeModelCatalog(
|
|
2790
|
+
workspaceId: string,
|
|
2791
|
+
): Promise<WorkspaceRealtimeModelCatalogResponse> {
|
|
2792
|
+
return await this.requestJson<WorkspaceRealtimeModelCatalogResponse>(
|
|
2793
|
+
"GET",
|
|
2794
|
+
`/v1/workspaces/${workspaceId}/realtime-model-catalog`,
|
|
2795
|
+
);
|
|
2796
|
+
}
|
|
2797
|
+
|
|
2798
|
+
/** The caller's access context: subject, account + workspace grants, defaults. */
|
|
2799
|
+
async getAccessContext(): Promise<AccessContext> {
|
|
2800
|
+
return await this.requestJson<AccessContext>("GET", "/v1/access/me");
|
|
2801
|
+
}
|
|
2802
|
+
|
|
2803
|
+
async listWorkspaces(): Promise<Workspace[]> {
|
|
2804
|
+
return await this.requestJson<Workspace[]>("GET", "/v1/workspaces");
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2807
|
+
async createWorkspace(request: CreateWorkspaceRequest): Promise<Workspace> {
|
|
2808
|
+
return await this.requestJson<Workspace>("POST", "/v1/workspaces", request);
|
|
2809
|
+
}
|
|
2810
|
+
|
|
2811
|
+
async getWorkspace(workspaceId: string): Promise<Workspace> {
|
|
2812
|
+
return await this.requestJson<Workspace>("GET", `/v1/workspaces/${workspaceId}`);
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
/** Read-time, secret-safe inventory of policy heads and visible workspace knowledge. */
|
|
2816
|
+
async getWorkspaceState(
|
|
2817
|
+
workspaceId: string,
|
|
2818
|
+
options: WorkspaceStateGetOptions = {},
|
|
2819
|
+
): Promise<WorkspaceStateResponse> {
|
|
2820
|
+
const params = new URLSearchParams();
|
|
2821
|
+
if (options.attemptId) params.set("attemptId", options.attemptId);
|
|
2822
|
+
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
2823
|
+
return await this.requestJson<WorkspaceStateResponse>(
|
|
2824
|
+
"GET",
|
|
2825
|
+
`/v1/workspaces/${workspaceId}/workspace-state${query}`,
|
|
2826
|
+
);
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2829
|
+
/** Download the canonical, explicitly sanitized Workspace State export. */
|
|
2830
|
+
async exportWorkspaceState(
|
|
2831
|
+
workspaceId: string,
|
|
2832
|
+
options: WorkspaceStateGetOptions = {},
|
|
2833
|
+
): Promise<WorkspaceStateExportResponse> {
|
|
2834
|
+
const params = new URLSearchParams();
|
|
2835
|
+
if (options.attemptId) params.set("attemptId", options.attemptId);
|
|
2836
|
+
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
2837
|
+
return await this.requestJson<WorkspaceStateExportResponse>(
|
|
2838
|
+
"GET",
|
|
2839
|
+
`/v1/workspaces/${workspaceId}/workspace-state/export${query}`,
|
|
2840
|
+
);
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
async updateWorkspace(workspaceId: string, request: UpdateWorkspaceRequest): Promise<Workspace> {
|
|
2844
|
+
return await this.requestJson<Workspace>("PATCH", `/v1/workspaces/${workspaceId}`, request);
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
/** Inspect immutable instruction-policy history, active heads, and activation audit evidence. */
|
|
2848
|
+
async listWorkspaceInstructionPolicies(
|
|
2849
|
+
workspaceId: string,
|
|
2850
|
+
options: WorkspaceInstructionPolicyListOptions = {},
|
|
2851
|
+
): Promise<WorkspaceInstructionPolicyListResponse> {
|
|
2852
|
+
const params = new URLSearchParams();
|
|
2853
|
+
if (options.kind !== undefined) params.set("kind", options.kind);
|
|
2854
|
+
if (options.scope !== undefined) params.set("scope", options.scope);
|
|
2855
|
+
if (options.roleKey !== undefined) params.set("roleKey", options.roleKey);
|
|
2856
|
+
if (options.afterRevision !== undefined) {
|
|
2857
|
+
params.set("afterRevision", String(options.afterRevision));
|
|
2858
|
+
}
|
|
2859
|
+
if (options.limit !== undefined) params.set("limit", String(options.limit));
|
|
2860
|
+
const query = params.toString();
|
|
2861
|
+
return await this.requestJson<WorkspaceInstructionPolicyListResponse>(
|
|
2862
|
+
"GET",
|
|
2863
|
+
`/v1/workspaces/${workspaceId}/instruction-policies${query ? `?${query}` : ""}`,
|
|
2864
|
+
);
|
|
2865
|
+
}
|
|
2866
|
+
|
|
2867
|
+
async getWorkspaceInstructionPolicyRevision(
|
|
2868
|
+
workspaceId: string,
|
|
2869
|
+
revisionId: string,
|
|
2870
|
+
): Promise<WorkspaceInstructionPolicyRevision> {
|
|
2871
|
+
return await this.requestJson<WorkspaceInstructionPolicyRevision>(
|
|
2872
|
+
"GET",
|
|
2873
|
+
`/v1/workspaces/${workspaceId}/instruction-policies/${encodeURIComponent(revisionId)}`,
|
|
2874
|
+
);
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2877
|
+
async createWorkspaceInstructionPolicyDraft(
|
|
2878
|
+
workspaceId: string,
|
|
2879
|
+
request: CreateWorkspaceInstructionPolicyDraftRequest,
|
|
2880
|
+
): Promise<WorkspaceInstructionPolicyRevision> {
|
|
2881
|
+
return await this.requestJson<WorkspaceInstructionPolicyRevision>(
|
|
2882
|
+
"POST",
|
|
2883
|
+
`/v1/workspaces/${workspaceId}/instruction-policies/drafts`,
|
|
2884
|
+
request,
|
|
2885
|
+
);
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2888
|
+
/** List the newest immutable onboarding proposals and their inactive policy drafts. */
|
|
2889
|
+
async listWorkspaceInstructionPolicyOnboardingProposals(
|
|
2890
|
+
workspaceId: string,
|
|
2891
|
+
options: WorkspaceInstructionPolicyOnboardingProposalListOptions = {},
|
|
2892
|
+
): Promise<WorkspaceInstructionPolicyOnboardingProposalListResponse> {
|
|
2893
|
+
const params = new URLSearchParams();
|
|
2894
|
+
if (options.limit !== undefined) params.set("limit", String(options.limit));
|
|
2895
|
+
const query = params.toString();
|
|
2896
|
+
return await this.requestJson<WorkspaceInstructionPolicyOnboardingProposalListResponse>(
|
|
2897
|
+
"GET",
|
|
2898
|
+
`/v1/workspaces/${workspaceId}/instruction-policies/onboarding-proposals${query ? `?${query}` : ""}`,
|
|
2899
|
+
);
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2902
|
+
/** Create one draft-only proposal against an exact active-policy baseline. */
|
|
2903
|
+
async createWorkspaceInstructionPolicyOnboardingProposal(
|
|
2904
|
+
workspaceId: string,
|
|
2905
|
+
request: CreateWorkspaceInstructionPolicyOnboardingProposalRequest,
|
|
2906
|
+
): Promise<WorkspaceInstructionPolicyOnboardingProposal> {
|
|
2907
|
+
return await this.requestJson<WorkspaceInstructionPolicyOnboardingProposal>(
|
|
2908
|
+
"POST",
|
|
2909
|
+
`/v1/workspaces/${workspaceId}/instruction-policies/onboarding-proposals`,
|
|
2910
|
+
request,
|
|
2911
|
+
);
|
|
2912
|
+
}
|
|
2913
|
+
|
|
2914
|
+
/** Import the stored legacy workspace override as an inactive charter draft. */
|
|
2915
|
+
async importLegacyWorkspaceInstructionPolicyDraft(
|
|
2916
|
+
workspaceId: string,
|
|
2917
|
+
request: ImportLegacyWorkspaceInstructionPolicyDraftRequest = {},
|
|
2918
|
+
): Promise<WorkspaceInstructionPolicyRevision> {
|
|
2919
|
+
return await this.requestJson<WorkspaceInstructionPolicyRevision>(
|
|
2920
|
+
"POST",
|
|
2921
|
+
`/v1/workspaces/${workspaceId}/instruction-policies/import-legacy`,
|
|
2922
|
+
request,
|
|
2923
|
+
);
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
async diffWorkspaceInstructionPolicyRevisions(
|
|
2927
|
+
workspaceId: string,
|
|
2928
|
+
request: WorkspaceInstructionPolicyDiffRequest,
|
|
2929
|
+
): Promise<WorkspaceInstructionPolicyDiffResponse> {
|
|
2930
|
+
const params = new URLSearchParams({
|
|
2931
|
+
fromRevisionId: request.fromRevisionId,
|
|
2932
|
+
toRevisionId: request.toRevisionId,
|
|
2933
|
+
});
|
|
2934
|
+
return await this.requestJson<WorkspaceInstructionPolicyDiffResponse>(
|
|
2935
|
+
"GET",
|
|
2936
|
+
`/v1/workspaces/${workspaceId}/instruction-policies/diff?${params}`,
|
|
2937
|
+
);
|
|
2200
2938
|
}
|
|
2201
2939
|
|
|
2202
2940
|
async activateWorkspaceInstructionPolicyRevision(
|
|
@@ -2222,6 +2960,77 @@ export class OpenGeniClient {
|
|
|
2222
2960
|
);
|
|
2223
2961
|
}
|
|
2224
2962
|
|
|
2963
|
+
/** Read the current organization profile plus immutable revision and activation history. */
|
|
2964
|
+
async listCompanyProfile(
|
|
2965
|
+
workspaceId: string,
|
|
2966
|
+
options: CompanyProfileListOptions = {},
|
|
2967
|
+
): Promise<CompanyProfileListResponse> {
|
|
2968
|
+
const params = new URLSearchParams();
|
|
2969
|
+
if (options.afterRevision !== undefined)
|
|
2970
|
+
params.set("afterRevision", String(options.afterRevision));
|
|
2971
|
+
if (options.limit !== undefined) params.set("limit", String(options.limit));
|
|
2972
|
+
const query = params.toString();
|
|
2973
|
+
return await this.requestJson<CompanyProfileListResponse>(
|
|
2974
|
+
"GET",
|
|
2975
|
+
`/v1/workspaces/${workspaceId}/company-profile${query ? `?${query}` : ""}`,
|
|
2976
|
+
);
|
|
2977
|
+
}
|
|
2978
|
+
|
|
2979
|
+
async getCompanyProfileRevision(
|
|
2980
|
+
workspaceId: string,
|
|
2981
|
+
revisionId: string,
|
|
2982
|
+
): Promise<CompanyProfileRevision> {
|
|
2983
|
+
return await this.requestJson<CompanyProfileRevision>(
|
|
2984
|
+
"GET",
|
|
2985
|
+
`/v1/workspaces/${workspaceId}/company-profile/revisions/${encodeURIComponent(revisionId)}`,
|
|
2986
|
+
);
|
|
2987
|
+
}
|
|
2988
|
+
|
|
2989
|
+
async updateCompanyProfile(
|
|
2990
|
+
workspaceId: string,
|
|
2991
|
+
request: UpdateCompanyProfileRequest,
|
|
2992
|
+
): Promise<CompanyProfileMutationResponse> {
|
|
2993
|
+
return await this.requestJson<CompanyProfileMutationResponse>(
|
|
2994
|
+
"PUT",
|
|
2995
|
+
`/v1/workspaces/${workspaceId}/company-profile`,
|
|
2996
|
+
request,
|
|
2997
|
+
);
|
|
2998
|
+
}
|
|
2999
|
+
|
|
3000
|
+
async diffCompanyProfileRevisions(
|
|
3001
|
+
workspaceId: string,
|
|
3002
|
+
request: CompanyProfileDiffRequest,
|
|
3003
|
+
): Promise<CompanyProfileDiffResponse> {
|
|
3004
|
+
const params = new URLSearchParams(request);
|
|
3005
|
+
return await this.requestJson<CompanyProfileDiffResponse>(
|
|
3006
|
+
"GET",
|
|
3007
|
+
`/v1/workspaces/${workspaceId}/company-profile/diff?${params}`,
|
|
3008
|
+
);
|
|
3009
|
+
}
|
|
3010
|
+
|
|
3011
|
+
async activateCompanyProfileRevision(
|
|
3012
|
+
workspaceId: string,
|
|
3013
|
+
revisionId: string,
|
|
3014
|
+
request: ActivateCompanyProfileRevisionRequest,
|
|
3015
|
+
): Promise<CompanyProfileMutationResponse> {
|
|
3016
|
+
return await this.requestJson<CompanyProfileMutationResponse>(
|
|
3017
|
+
"POST",
|
|
3018
|
+
`/v1/workspaces/${workspaceId}/company-profile/revisions/${encodeURIComponent(revisionId)}/activate`,
|
|
3019
|
+
request,
|
|
3020
|
+
);
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
async rollbackCompanyProfile(
|
|
3024
|
+
workspaceId: string,
|
|
3025
|
+
request: RollbackCompanyProfileRequest,
|
|
3026
|
+
): Promise<CompanyProfileMutationResponse> {
|
|
3027
|
+
return await this.requestJson<CompanyProfileMutationResponse>(
|
|
3028
|
+
"POST",
|
|
3029
|
+
`/v1/workspaces/${workspaceId}/company-profile/rollback`,
|
|
3030
|
+
request,
|
|
3031
|
+
);
|
|
3032
|
+
}
|
|
3033
|
+
|
|
2225
3034
|
async listPreferenceRegistry(
|
|
2226
3035
|
workspaceId: string,
|
|
2227
3036
|
options: PreferenceRegistryListOptions = {},
|
|
@@ -2405,6 +3214,86 @@ export class OpenGeniClient {
|
|
|
2405
3214
|
);
|
|
2406
3215
|
}
|
|
2407
3216
|
|
|
3217
|
+
/** Exchange one signed Slack bearer for durable, token-free continuation state. */
|
|
3218
|
+
async prepareSlackUserLinkAccess(
|
|
3219
|
+
workspaceId: string,
|
|
3220
|
+
request: PrepareSlackUserLinkAccessRequest,
|
|
3221
|
+
): Promise<SlackUserLinkAccessRequest> {
|
|
3222
|
+
return await this.requestJson<SlackUserLinkAccessRequest>(
|
|
3223
|
+
"POST",
|
|
3224
|
+
`/v1/workspaces/${workspaceId}/integrations/slack/user-link-intents`,
|
|
3225
|
+
request,
|
|
3226
|
+
);
|
|
3227
|
+
}
|
|
3228
|
+
|
|
3229
|
+
async getSlackUserLinkAccess(
|
|
3230
|
+
workspaceId: string,
|
|
3231
|
+
requestId: string,
|
|
3232
|
+
): Promise<SlackUserLinkAccessRequest> {
|
|
3233
|
+
return await this.requestJson<SlackUserLinkAccessRequest>(
|
|
3234
|
+
"GET",
|
|
3235
|
+
`/v1/workspaces/${workspaceId}/integrations/slack/user-link-intents/${requestId}`,
|
|
3236
|
+
);
|
|
3237
|
+
}
|
|
3238
|
+
|
|
3239
|
+
async requestSlackUserLinkWorkspaceAccess(
|
|
3240
|
+
workspaceId: string,
|
|
3241
|
+
requestId: string,
|
|
3242
|
+
request: SlackUserLinkAccessMutationRequest,
|
|
3243
|
+
): Promise<SlackUserLinkAccessRequest> {
|
|
3244
|
+
return await this.requestJson<SlackUserLinkAccessRequest>(
|
|
3245
|
+
"POST",
|
|
3246
|
+
`/v1/workspaces/${workspaceId}/integrations/slack/user-link-intents/${requestId}/request-access`,
|
|
3247
|
+
request,
|
|
3248
|
+
);
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
async cancelSlackUserLinkAccess(
|
|
3252
|
+
workspaceId: string,
|
|
3253
|
+
requestId: string,
|
|
3254
|
+
request: SlackUserLinkAccessMutationRequest,
|
|
3255
|
+
): Promise<SlackUserLinkAccessRequest> {
|
|
3256
|
+
return await this.requestJson<SlackUserLinkAccessRequest>(
|
|
3257
|
+
"POST",
|
|
3258
|
+
`/v1/workspaces/${workspaceId}/integrations/slack/user-link-intents/${requestId}/cancel`,
|
|
3259
|
+
request,
|
|
3260
|
+
);
|
|
3261
|
+
}
|
|
3262
|
+
|
|
3263
|
+
async listSlackUserLinkAccessRequests(
|
|
3264
|
+
workspaceId: string,
|
|
3265
|
+
): Promise<SlackUserLinkAccessRequest[]> {
|
|
3266
|
+
const response = await this.requestJson<ListSlackUserLinkAccessRequestsResponse>(
|
|
3267
|
+
"GET",
|
|
3268
|
+
`/v1/workspaces/${workspaceId}/members/access-requests/slack`,
|
|
3269
|
+
);
|
|
3270
|
+
return response.requests;
|
|
3271
|
+
}
|
|
3272
|
+
|
|
3273
|
+
async approveSlackUserLinkAccessRequest(
|
|
3274
|
+
workspaceId: string,
|
|
3275
|
+
requestId: string,
|
|
3276
|
+
request: ApproveSlackUserLinkAccessRequest,
|
|
3277
|
+
): Promise<SlackUserLinkAccessRequest> {
|
|
3278
|
+
return await this.requestJson<SlackUserLinkAccessRequest>(
|
|
3279
|
+
"POST",
|
|
3280
|
+
`/v1/workspaces/${workspaceId}/members/access-requests/slack/${requestId}/approve`,
|
|
3281
|
+
request,
|
|
3282
|
+
);
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3285
|
+
async denySlackUserLinkAccessRequest(
|
|
3286
|
+
workspaceId: string,
|
|
3287
|
+
requestId: string,
|
|
3288
|
+
request: SlackUserLinkAccessMutationRequest,
|
|
3289
|
+
): Promise<SlackUserLinkAccessRequest> {
|
|
3290
|
+
return await this.requestJson<SlackUserLinkAccessRequest>(
|
|
3291
|
+
"POST",
|
|
3292
|
+
`/v1/workspaces/${workspaceId}/members/access-requests/slack/${requestId}/deny`,
|
|
3293
|
+
request,
|
|
3294
|
+
);
|
|
3295
|
+
}
|
|
3296
|
+
|
|
2408
3297
|
// --- Scheduled tasks (write + runs) -------------------------------------------
|
|
2409
3298
|
|
|
2410
3299
|
async createScheduledTask(
|
|
@@ -2484,7 +3373,8 @@ export class OpenGeniClient {
|
|
|
2484
3373
|
}
|
|
2485
3374
|
|
|
2486
3375
|
// --- VariableSets --------------------------------------------------------------
|
|
2487
|
-
//
|
|
3376
|
+
// Generic reads return name/version metadata only. Plaintext uses one
|
|
3377
|
+
// dedicated permissioned endpoint.
|
|
2488
3378
|
|
|
2489
3379
|
async listVariableSets(workspaceId: string): Promise<VariableSet[]> {
|
|
2490
3380
|
return await this.requestJson<VariableSet[]>(
|
|
@@ -2511,6 +3401,17 @@ export class OpenGeniClient {
|
|
|
2511
3401
|
);
|
|
2512
3402
|
}
|
|
2513
3403
|
|
|
3404
|
+
async getVariableSetVariable(
|
|
3405
|
+
workspaceId: string,
|
|
3406
|
+
variableSetId: string,
|
|
3407
|
+
name: string,
|
|
3408
|
+
): Promise<VariableSetSecret> {
|
|
3409
|
+
return await this.requestJson<VariableSetSecret>(
|
|
3410
|
+
"GET",
|
|
3411
|
+
`/v1/workspaces/${workspaceId}/variable-sets/${variableSetId}/variables/${encodeURIComponent(name)}`,
|
|
3412
|
+
);
|
|
3413
|
+
}
|
|
3414
|
+
|
|
2514
3415
|
async updateVariableSet(
|
|
2515
3416
|
workspaceId: string,
|
|
2516
3417
|
variableSetId: string,
|
|
@@ -2530,7 +3431,7 @@ export class OpenGeniClient {
|
|
|
2530
3431
|
);
|
|
2531
3432
|
}
|
|
2532
3433
|
|
|
2533
|
-
/** Create or rotate a variable.
|
|
3434
|
+
/** Create or rotate a variable. Generic reads never return its value. */
|
|
2534
3435
|
async setVariableSetVariable(
|
|
2535
3436
|
workspaceId: string,
|
|
2536
3437
|
variableSetId: string,
|
|
@@ -2726,19 +3627,29 @@ export class OpenGeniClient {
|
|
|
2726
3627
|
async beginFileUpload(
|
|
2727
3628
|
workspaceId: string,
|
|
2728
3629
|
request: CreateFileUploadRequest,
|
|
3630
|
+
options: OpenGeniRequestOptions = {},
|
|
2729
3631
|
): Promise<CreateFileUploadResponse> {
|
|
2730
3632
|
return await this.requestJson<CreateFileUploadResponse>(
|
|
2731
3633
|
"POST",
|
|
2732
3634
|
`/v1/workspaces/${workspaceId}/files/uploads`,
|
|
2733
3635
|
request,
|
|
3636
|
+
{},
|
|
3637
|
+
options,
|
|
2734
3638
|
);
|
|
2735
3639
|
}
|
|
2736
3640
|
|
|
2737
3641
|
/** Step 3 of the upload flow: server verifies the object and marks it ready. */
|
|
2738
|
-
async completeFileUpload(
|
|
3642
|
+
async completeFileUpload(
|
|
3643
|
+
workspaceId: string,
|
|
3644
|
+
uploadId: string,
|
|
3645
|
+
options: OpenGeniRequestOptions = {},
|
|
3646
|
+
): Promise<FileAsset> {
|
|
2739
3647
|
const response = await this.requestJson<CompleteFileUploadResponse>(
|
|
2740
3648
|
"POST",
|
|
2741
3649
|
`/v1/workspaces/${workspaceId}/files/uploads/${uploadId}/complete`,
|
|
3650
|
+
undefined,
|
|
3651
|
+
{},
|
|
3652
|
+
options,
|
|
2742
3653
|
);
|
|
2743
3654
|
return response.file;
|
|
2744
3655
|
}
|
|
@@ -2749,6 +3660,30 @@ export class OpenGeniClient {
|
|
|
2749
3660
|
* -> complete. Returns the ready `FileAsset`.
|
|
2750
3661
|
*/
|
|
2751
3662
|
async uploadFile(workspaceId: string, input: UploadFileInput): Promise<FileAsset> {
|
|
3663
|
+
if (
|
|
3664
|
+
input.timeoutMs !== undefined &&
|
|
3665
|
+
(!Number.isFinite(input.timeoutMs) || input.timeoutMs <= 0)
|
|
3666
|
+
) {
|
|
3667
|
+
throw new Error("File upload timeout must be a positive number");
|
|
3668
|
+
}
|
|
3669
|
+
const withTimeout = async <T>(
|
|
3670
|
+
timeoutMs: number,
|
|
3671
|
+
operation: (signal: AbortSignal) => Promise<T>,
|
|
3672
|
+
): Promise<T> => {
|
|
3673
|
+
const controller = new AbortController();
|
|
3674
|
+
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
3675
|
+
const timedOut = new Promise<never>((_resolve, reject) => {
|
|
3676
|
+
timeout = setTimeout(() => {
|
|
3677
|
+
controller.abort();
|
|
3678
|
+
reject(new Error("File upload timed out. Retry the upload."));
|
|
3679
|
+
}, timeoutMs);
|
|
3680
|
+
});
|
|
3681
|
+
try {
|
|
3682
|
+
return await Promise.race([operation(controller.signal), timedOut]);
|
|
3683
|
+
} finally {
|
|
3684
|
+
if (timeout !== undefined) clearTimeout(timeout);
|
|
3685
|
+
}
|
|
3686
|
+
};
|
|
2752
3687
|
// Snapshot mutable inputs before hashing so the digest always describes the
|
|
2753
3688
|
// exact bytes later sent to object storage. Copy Uint8Array views into a
|
|
2754
3689
|
// Blob so byte offsets/shared buffers can't leak surrounding bytes.
|
|
@@ -2765,32 +3700,52 @@ export class OpenGeniClient {
|
|
|
2765
3700
|
? body.size
|
|
2766
3701
|
: body.byteLength;
|
|
2767
3702
|
const sha256 = input.sha256 ?? (await sha256ForUpload(body));
|
|
2768
|
-
const upload = await
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
3703
|
+
const upload = await withTimeout(
|
|
3704
|
+
30_000,
|
|
3705
|
+
async (signal) =>
|
|
3706
|
+
await this.beginFileUpload(
|
|
3707
|
+
workspaceId,
|
|
3708
|
+
{
|
|
3709
|
+
filename: input.filename,
|
|
3710
|
+
contentType: input.contentType,
|
|
3711
|
+
sizeBytes,
|
|
3712
|
+
sha256,
|
|
3713
|
+
},
|
|
3714
|
+
{ signal },
|
|
3715
|
+
),
|
|
3716
|
+
);
|
|
3717
|
+
// Give large valid uploads enough time at a conservative 256 KiB/s while
|
|
3718
|
+
// still bounding an object-storage request that never settles.
|
|
3719
|
+
const transferTimeoutMs =
|
|
3720
|
+
input.timeoutMs ?? Math.max(120_000, Math.ceil(sizeBytes / (256 * 1024)) * 1_000);
|
|
3721
|
+
const putResponse = await withTimeout(
|
|
3722
|
+
transferTimeoutMs,
|
|
3723
|
+
async (signal) =>
|
|
3724
|
+
await this.fetchImpl(upload.putUrl, {
|
|
3725
|
+
method: "PUT",
|
|
3726
|
+
// Signed object-storage URLs carry their own short-lived authority.
|
|
3727
|
+
// Browser cookies and HTTP auth must never accompany this cross-origin
|
|
3728
|
+
// request: credentialed fetches are incompatible with wildcard CORS and
|
|
3729
|
+
// can leak ambient credentials to a caller-selected storage endpoint.
|
|
3730
|
+
credentials: "omit",
|
|
3731
|
+
// The backend's requiredHeaders already carry the canonical lowercase
|
|
3732
|
+
// `content-type` for every storage backend (Azure/S3/GCS). Do NOT also set
|
|
3733
|
+
// a `Content-Type` key here: WHATWG Headers treats the two casings as the
|
|
3734
|
+
// same header and comma-joins their values (e.g. "text/plain, text/plain"),
|
|
3735
|
+
// which the object store persists verbatim and COMPLETE then rejects (422),
|
|
3736
|
+
// and which breaks S3's presigned-URL signature.
|
|
3737
|
+
headers: { ...upload.requiredHeaders },
|
|
3738
|
+
body,
|
|
3739
|
+
signal,
|
|
3740
|
+
}),
|
|
3741
|
+
);
|
|
2790
3742
|
if (!putResponse.ok) {
|
|
2791
3743
|
throw await apiErrorFromResponse(putResponse, { method: "PUT" });
|
|
2792
3744
|
}
|
|
2793
|
-
return await
|
|
3745
|
+
return await withTimeout(
|
|
3746
|
+
30_000,
|
|
3747
|
+
async (signal) => await this.completeFileUpload(workspaceId, upload.uploadId, { signal }),
|
|
3748
|
+
);
|
|
2794
3749
|
}
|
|
2795
3750
|
|
|
2796
3751
|
async getFile(workspaceId: string, fileId: string): Promise<FileAsset> {
|
|
@@ -2819,23 +3774,150 @@ export class OpenGeniClient {
|
|
|
2819
3774
|
workspaceId: string,
|
|
2820
3775
|
artifactId: string,
|
|
2821
3776
|
options: RetainedArtifactContentOptions = {},
|
|
3777
|
+
): Promise<RetainedArtifactContent> {
|
|
3778
|
+
return await this.getRetainedArtifactContentAtPath(
|
|
3779
|
+
`/v1/workspaces/${workspaceId}/artifacts/${artifactId}/content`,
|
|
3780
|
+
options,
|
|
3781
|
+
);
|
|
3782
|
+
}
|
|
3783
|
+
|
|
3784
|
+
async getSessionRetainedArtifact(
|
|
3785
|
+
workspaceId: string,
|
|
3786
|
+
sessionId: string,
|
|
3787
|
+
artifactId: string,
|
|
3788
|
+
): Promise<RetainedArtifactMetadata> {
|
|
3789
|
+
return await this.requestJson<RetainedArtifactMetadata>(
|
|
3790
|
+
"GET",
|
|
3791
|
+
`/v1/workspaces/${workspaceId}/sessions/${sessionId}/artifacts/${artifactId}`,
|
|
3792
|
+
);
|
|
3793
|
+
}
|
|
3794
|
+
|
|
3795
|
+
async getSessionRetainedArtifactContent(
|
|
3796
|
+
workspaceId: string,
|
|
3797
|
+
sessionId: string,
|
|
3798
|
+
artifactId: string,
|
|
3799
|
+
options: RetainedArtifactContentOptions = {},
|
|
3800
|
+
): Promise<RetainedArtifactContent> {
|
|
3801
|
+
return await this.getRetainedArtifactContentAtPath(
|
|
3802
|
+
`/v1/workspaces/${workspaceId}/sessions/${sessionId}/artifacts/${artifactId}/content`,
|
|
3803
|
+
options,
|
|
3804
|
+
);
|
|
3805
|
+
}
|
|
3806
|
+
|
|
3807
|
+
/** Assemble one permanent generated-image receipt from bounded authenticated ranges. */
|
|
3808
|
+
async downloadRetainedArtifact(
|
|
3809
|
+
workspaceId: string,
|
|
3810
|
+
artifact: RetainedArtifactReference,
|
|
3811
|
+
options: RetainedArtifactDownloadOptions = {},
|
|
3812
|
+
): Promise<RetainedArtifactDownload> {
|
|
3813
|
+
assertRetainedGeneratedImageReceipt(workspaceId, artifact);
|
|
3814
|
+
const bytes = await this.downloadRetainedArtifactBytes(artifact, options);
|
|
3815
|
+
return { artifact, bytes };
|
|
3816
|
+
}
|
|
3817
|
+
|
|
3818
|
+
/** Mint a short-lived, zero-copy browser source for a validated generated image. */
|
|
3819
|
+
async createRetainedArtifactDownloadUrl(
|
|
3820
|
+
workspaceId: string,
|
|
3821
|
+
artifact: RetainedArtifactReference,
|
|
3822
|
+
options: OpenGeniRequestOptions = {},
|
|
3823
|
+
): Promise<FileDownloadUrlResponse> {
|
|
3824
|
+
assertRetainedGeneratedImageReceipt(workspaceId, artifact);
|
|
3825
|
+
const download = await this.createFileDownloadUrl(workspaceId, artifact.artifactId, options);
|
|
3826
|
+
assertSafeArtifactDownloadUrl(download);
|
|
3827
|
+
return download;
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
/** Assemble one retained screenshot from bounded authenticated API ranges. */
|
|
3831
|
+
async downloadRetainedScreenshot(
|
|
3832
|
+
workspaceId: string,
|
|
3833
|
+
sessionId: string,
|
|
3834
|
+
artifactId: string,
|
|
3835
|
+
options: RetainedScreenshotDownloadOptions = {},
|
|
3836
|
+
): Promise<RetainedScreenshotDownload> {
|
|
3837
|
+
const metadata = await this.getSessionRetainedArtifact(workspaceId, sessionId, artifactId);
|
|
3838
|
+
if (!metadata.available) return { metadata, bytes: null };
|
|
3839
|
+
if (
|
|
3840
|
+
metadata.kind !== "computer_screenshot" ||
|
|
3841
|
+
metadata.contentType !== "image/png" ||
|
|
3842
|
+
!metadata.dimensions ||
|
|
3843
|
+
metadata.originalBytes <= 0 ||
|
|
3844
|
+
metadata.originalBytes > COMPUTER_SCREENSHOT_MAX_BYTES
|
|
3845
|
+
) {
|
|
3846
|
+
throw new OpenGeniApiError(502, "retained screenshot metadata is invalid");
|
|
3847
|
+
}
|
|
3848
|
+
const bytes = await this.downloadRetainedArtifactBytes(metadata, options);
|
|
3849
|
+
return { metadata, bytes };
|
|
3850
|
+
}
|
|
3851
|
+
|
|
3852
|
+
private async downloadRetainedArtifactBytes(
|
|
3853
|
+
artifact: RetainedArtifactReference,
|
|
3854
|
+
options: RetainedArtifactDownloadOptions,
|
|
3855
|
+
): Promise<Uint8Array> {
|
|
3856
|
+
const maxRetries = options.maxRetries ?? 2;
|
|
3857
|
+
if (!Number.isInteger(maxRetries) || maxRetries < 0 || maxRetries > 3) {
|
|
3858
|
+
throw new RangeError("retained artifact maxRetries must be an integer from 0 to 3");
|
|
3859
|
+
}
|
|
3860
|
+
const bytes = new Uint8Array(artifact.originalBytes);
|
|
3861
|
+
const pageBytes = Math.min(artifact.retrieval.maxRangeBytes, RETAINED_OUTPUT_MAX_PAGE_BYTES);
|
|
3862
|
+
if (!Number.isSafeInteger(pageBytes) || pageBytes <= 0) {
|
|
3863
|
+
throw new OpenGeniApiError(502, "retained artifact range metadata is invalid");
|
|
3864
|
+
}
|
|
3865
|
+
for (let start = 0; start < bytes.byteLength; start += pageBytes) {
|
|
3866
|
+
options.signal?.throwIfAborted();
|
|
3867
|
+
const end = Math.min(start + pageBytes, bytes.byteLength) - 1;
|
|
3868
|
+
let page: RetainedArtifactContent | null = null;
|
|
3869
|
+
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
|
|
3870
|
+
try {
|
|
3871
|
+
page = await this.getRetainedArtifactContentAtPath(artifact.retrieval.path, {
|
|
3872
|
+
range: `bytes=${start}-${end}`,
|
|
3873
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
3874
|
+
});
|
|
3875
|
+
break;
|
|
3876
|
+
} catch (error) {
|
|
3877
|
+
options.signal?.throwIfAborted();
|
|
3878
|
+
if (
|
|
3879
|
+
attempt >= maxRetries ||
|
|
3880
|
+
(error instanceof OpenGeniApiError && error.status >= 400 && error.status < 500)
|
|
3881
|
+
) {
|
|
3882
|
+
throw error;
|
|
3883
|
+
}
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
if (!page) throw new OpenGeniApiError(502, "retained artifact range retry exhausted");
|
|
3887
|
+
const expectedLength = end - start + 1;
|
|
3888
|
+
if (
|
|
3889
|
+
page.status !== 206 ||
|
|
3890
|
+
page.contentType !== artifact.contentType ||
|
|
3891
|
+
page.contentLength !== expectedLength ||
|
|
3892
|
+
page.contentRange !== `bytes ${start}-${end}/${artifact.originalBytes}`
|
|
3893
|
+
) {
|
|
3894
|
+
throw new OpenGeniApiError(502, "retained artifact range response is invalid");
|
|
3895
|
+
}
|
|
3896
|
+
bytes.set(page.bytes, start);
|
|
3897
|
+
}
|
|
3898
|
+
if ((await sha256Hex(bytes)) !== artifact.sha256) {
|
|
3899
|
+
throw new OpenGeniApiError(502, "retained artifact checksum mismatch");
|
|
3900
|
+
}
|
|
3901
|
+
return bytes;
|
|
3902
|
+
}
|
|
3903
|
+
|
|
3904
|
+
private async getRetainedArtifactContentAtPath(
|
|
3905
|
+
path: string,
|
|
3906
|
+
options: RetainedArtifactContentOptions,
|
|
2822
3907
|
): Promise<RetainedArtifactContent> {
|
|
2823
3908
|
if (options.range && (options.range.length > 128 || /[^\x20-\x7e]/.test(options.range))) {
|
|
2824
3909
|
throw new RangeError("retained artifact range must be at most 128 printable ASCII bytes");
|
|
2825
3910
|
}
|
|
2826
3911
|
const correlationId = crypto.randomUUID();
|
|
2827
|
-
const response = await this.fetchImpl(
|
|
2828
|
-
|
|
2829
|
-
{
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
Accept: "application/octet-stream",
|
|
2834
|
-
...(options.range ? { Range: options.range } : {}),
|
|
2835
|
-
},
|
|
2836
|
-
...(options.signal ? { signal: options.signal } : {}),
|
|
3912
|
+
const response = await this.fetchImpl(this.url(path), {
|
|
3913
|
+
method: "GET",
|
|
3914
|
+
headers: {
|
|
3915
|
+
...this.headers(correlationId),
|
|
3916
|
+
Accept: "application/octet-stream",
|
|
3917
|
+
...(options.range ? { Range: options.range } : {}),
|
|
2837
3918
|
},
|
|
2838
|
-
|
|
3919
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
3920
|
+
});
|
|
2839
3921
|
try {
|
|
2840
3922
|
assertApiContractResponse(response);
|
|
2841
3923
|
} catch (error) {
|
|
@@ -2868,25 +3950,92 @@ export class OpenGeniClient {
|
|
|
2868
3950
|
RETAINED_OUTPUT_MAX_PAGE_BYTES,
|
|
2869
3951
|
declaredLength,
|
|
2870
3952
|
);
|
|
2871
|
-
return {
|
|
2872
|
-
bytes,
|
|
2873
|
-
status: response.status,
|
|
2874
|
-
contentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
2875
|
-
contentLength: bytes.byteLength,
|
|
2876
|
-
contentRange: response.headers.get("content-range"),
|
|
2877
|
-
acceptRanges: "bytes",
|
|
2878
|
-
};
|
|
3953
|
+
return {
|
|
3954
|
+
bytes,
|
|
3955
|
+
status: response.status,
|
|
3956
|
+
contentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
3957
|
+
contentLength: bytes.byteLength,
|
|
3958
|
+
contentRange: response.headers.get("content-range"),
|
|
3959
|
+
acceptRanges: "bytes",
|
|
3960
|
+
};
|
|
3961
|
+
}
|
|
3962
|
+
|
|
3963
|
+
/** Mint a short-lived signed download URL for a ready file. */
|
|
3964
|
+
async createFileDownloadUrl(
|
|
3965
|
+
workspaceId: string,
|
|
3966
|
+
fileId: string,
|
|
3967
|
+
options: OpenGeniRequestOptions = {},
|
|
3968
|
+
): Promise<FileDownloadUrlResponse> {
|
|
3969
|
+
return await this.requestJson<FileDownloadUrlResponse>(
|
|
3970
|
+
"POST",
|
|
3971
|
+
`/v1/workspaces/${workspaceId}/files/${fileId}/download-url`,
|
|
3972
|
+
undefined,
|
|
3973
|
+
{},
|
|
3974
|
+
options,
|
|
3975
|
+
);
|
|
3976
|
+
}
|
|
3977
|
+
|
|
3978
|
+
// --- Video generation ---------------------------------------------------------------
|
|
3979
|
+
|
|
3980
|
+
/** Read the effective workspace policy and executable Seedance capabilities. */
|
|
3981
|
+
async getVideoGenerationSettings(
|
|
3982
|
+
workspaceId: string,
|
|
3983
|
+
options: OpenGeniRequestOptions = {},
|
|
3984
|
+
): Promise<WorkspaceVideoGenerationSettings> {
|
|
3985
|
+
return await this.requestJson<WorkspaceVideoGenerationSettings>(
|
|
3986
|
+
"GET",
|
|
3987
|
+
`/v1/workspaces/${workspaceId}/video-generation`,
|
|
3988
|
+
undefined,
|
|
3989
|
+
{},
|
|
3990
|
+
options,
|
|
3991
|
+
);
|
|
3992
|
+
}
|
|
3993
|
+
|
|
3994
|
+
/** Replace the enabled video models/default under optimistic policy revision control. */
|
|
3995
|
+
async updateVideoGenerationPolicy(
|
|
3996
|
+
workspaceId: string,
|
|
3997
|
+
request: UpdateVideoGenerationPolicyRequest,
|
|
3998
|
+
options: OpenGeniRequestOptions = {},
|
|
3999
|
+
): Promise<VideoGenerationPolicy> {
|
|
4000
|
+
return await this.requestJson<VideoGenerationPolicy>(
|
|
4001
|
+
"PUT",
|
|
4002
|
+
`/v1/workspaces/${workspaceId}/video-generation/policy`,
|
|
4003
|
+
request,
|
|
4004
|
+
{},
|
|
4005
|
+
options,
|
|
4006
|
+
);
|
|
2879
4007
|
}
|
|
2880
4008
|
|
|
2881
|
-
/**
|
|
2882
|
-
async
|
|
4009
|
+
/** Read durable progress for one accepted video generation operation. */
|
|
4010
|
+
async getVideoGenerationOperation(
|
|
2883
4011
|
workspaceId: string,
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
4012
|
+
operationId: string,
|
|
4013
|
+
options: OpenGeniRequestOptions = {},
|
|
4014
|
+
): Promise<VideoGenerationOperationSummary> {
|
|
4015
|
+
return await this.requestJson<VideoGenerationOperationSummary>(
|
|
4016
|
+
"GET",
|
|
4017
|
+
`/v1/workspaces/${workspaceId}/video-generation/operations/${operationId}`,
|
|
4018
|
+
undefined,
|
|
4019
|
+
{},
|
|
4020
|
+
options,
|
|
4021
|
+
);
|
|
4022
|
+
}
|
|
4023
|
+
|
|
4024
|
+
/** Mint a short-lived zero-copy URL for native Range-based video playback. */
|
|
4025
|
+
async createVideoArtifactPlaybackSource(
|
|
4026
|
+
workspaceId: string,
|
|
4027
|
+
artifactId: string,
|
|
4028
|
+
options: OpenGeniRequestOptions = {},
|
|
4029
|
+
): Promise<VideoArtifactPlaybackSource> {
|
|
4030
|
+
const source = await this.requestJson<VideoArtifactPlaybackSource>(
|
|
2887
4031
|
"POST",
|
|
2888
|
-
`/v1/workspaces/${workspaceId}/
|
|
4032
|
+
`/v1/workspaces/${workspaceId}/artifacts/${artifactId}/playback-source`,
|
|
4033
|
+
undefined,
|
|
4034
|
+
{},
|
|
4035
|
+
options,
|
|
2889
4036
|
);
|
|
4037
|
+
assertSafeVideoArtifactPlaybackSource(source, artifactId);
|
|
4038
|
+
return source;
|
|
2890
4039
|
}
|
|
2891
4040
|
|
|
2892
4041
|
// --- Documents ----------------------------------------------------------------------
|
|
@@ -3135,6 +4284,53 @@ export class OpenGeniClient {
|
|
|
3135
4284
|
);
|
|
3136
4285
|
}
|
|
3137
4286
|
|
|
4287
|
+
/** Resolve pinned components, Variable Set, and Rig requirements before installation. */
|
|
4288
|
+
async previewPackInstallation(
|
|
4289
|
+
workspaceId: string,
|
|
4290
|
+
packId: string,
|
|
4291
|
+
request: PreviewPackInstallationRequest = {},
|
|
4292
|
+
): Promise<PackInstallationPreview> {
|
|
4293
|
+
return await this.requestJson<PackInstallationPreview>(
|
|
4294
|
+
"POST",
|
|
4295
|
+
`/v1/workspaces/${workspaceId}/packs/${encodeURIComponent(packId)}/installation-preview`,
|
|
4296
|
+
request,
|
|
4297
|
+
);
|
|
4298
|
+
}
|
|
4299
|
+
|
|
4300
|
+
/** Install, update, or repair a Pack from an exact previewed manifest. */
|
|
4301
|
+
async installPack(
|
|
4302
|
+
workspaceId: string,
|
|
4303
|
+
packId: string,
|
|
4304
|
+
request: InstallPackRequest,
|
|
4305
|
+
): Promise<PackInstallation> {
|
|
4306
|
+
return await this.requestJson<PackInstallation>(
|
|
4307
|
+
"POST",
|
|
4308
|
+
`/v1/workspaces/${workspaceId}/packs/${encodeURIComponent(packId)}/install`,
|
|
4309
|
+
request,
|
|
4310
|
+
);
|
|
4311
|
+
}
|
|
4312
|
+
|
|
4313
|
+
/** Preview which Pack-owned components will be retained by other owners. */
|
|
4314
|
+
async previewPackUninstall(workspaceId: string, packId: string): Promise<PackUninstallPreview> {
|
|
4315
|
+
return await this.requestJson<PackUninstallPreview>(
|
|
4316
|
+
"GET",
|
|
4317
|
+
`/v1/workspaces/${workspaceId}/packs/${encodeURIComponent(packId)}/uninstall-preview`,
|
|
4318
|
+
);
|
|
4319
|
+
}
|
|
4320
|
+
|
|
4321
|
+
/** Safely release Pack ownership and disable only now-ownerless components. */
|
|
4322
|
+
async uninstallPack(
|
|
4323
|
+
workspaceId: string,
|
|
4324
|
+
packId: string,
|
|
4325
|
+
request: UninstallPackRequest,
|
|
4326
|
+
): Promise<UninstallPackResult> {
|
|
4327
|
+
return await this.requestJson<UninstallPackResult>(
|
|
4328
|
+
"DELETE",
|
|
4329
|
+
`/v1/workspaces/${workspaceId}/packs/${encodeURIComponent(packId)}/installation`,
|
|
4330
|
+
request,
|
|
4331
|
+
);
|
|
4332
|
+
}
|
|
4333
|
+
|
|
3138
4334
|
/** Unregister a workspace-scoped pack (built-in packs cannot be deleted). */
|
|
3139
4335
|
async deletePack(workspaceId: string, packId: string): Promise<void> {
|
|
3140
4336
|
await this.requestVoid(
|
|
@@ -3209,6 +4405,298 @@ export class OpenGeniClient {
|
|
|
3209
4405
|
);
|
|
3210
4406
|
}
|
|
3211
4407
|
|
|
4408
|
+
/** List installed protocol-neutral OpenAPI and GraphQL Integrations. */
|
|
4409
|
+
async listApiIntegrations(workspaceId: string): Promise<ListApiIntegrationsResponse> {
|
|
4410
|
+
return await this.requestJson<ListApiIntegrationsResponse>(
|
|
4411
|
+
"GET",
|
|
4412
|
+
`/v1/workspaces/${workspaceId}/integrations`,
|
|
4413
|
+
);
|
|
4414
|
+
}
|
|
4415
|
+
|
|
4416
|
+
/** List curated provider presets without exposing deployment OAuth credentials. */
|
|
4417
|
+
async listApiIntegrationPresets(workspaceId: string): Promise<ListApiIntegrationPresetsResponse> {
|
|
4418
|
+
return await this.requestJson<ListApiIntegrationPresetsResponse>(
|
|
4419
|
+
"GET",
|
|
4420
|
+
`/v1/workspaces/${workspaceId}/integrations/presets`,
|
|
4421
|
+
);
|
|
4422
|
+
}
|
|
4423
|
+
|
|
4424
|
+
/** Detect and compile an Integration without mutating workspace state. */
|
|
4425
|
+
async previewApiIntegration(
|
|
4426
|
+
workspaceId: string,
|
|
4427
|
+
request: PreviewApiIntegrationRequest,
|
|
4428
|
+
): Promise<ApiIntegrationPreview> {
|
|
4429
|
+
return await this.requestJson<ApiIntegrationPreview>(
|
|
4430
|
+
"POST",
|
|
4431
|
+
`/v1/workspaces/${workspaceId}/integrations/preview`,
|
|
4432
|
+
request,
|
|
4433
|
+
);
|
|
4434
|
+
}
|
|
4435
|
+
|
|
4436
|
+
/** Start a signed PKCE OAuth flow for a built-in Google or Microsoft preset. */
|
|
4437
|
+
async startApiIntegrationOAuth(
|
|
4438
|
+
workspaceId: string,
|
|
4439
|
+
request: ApiIntegrationOAuthStartRequest,
|
|
4440
|
+
): Promise<OAuthStartResponse> {
|
|
4441
|
+
return await this.requestJson<OAuthStartResponse>(
|
|
4442
|
+
"POST",
|
|
4443
|
+
`/v1/workspaces/${workspaceId}/integrations/oauth/start`,
|
|
4444
|
+
request,
|
|
4445
|
+
);
|
|
4446
|
+
}
|
|
4447
|
+
|
|
4448
|
+
/** Install only the exact immutable revision and digest accepted in preview. */
|
|
4449
|
+
async installApiIntegration(
|
|
4450
|
+
workspaceId: string,
|
|
4451
|
+
request: InstallApiIntegrationRequest,
|
|
4452
|
+
): Promise<InstalledApiIntegration> {
|
|
4453
|
+
return await this.requestJson<InstalledApiIntegration>(
|
|
4454
|
+
"POST",
|
|
4455
|
+
`/v1/workspaces/${workspaceId}/integrations/install`,
|
|
4456
|
+
request,
|
|
4457
|
+
);
|
|
4458
|
+
}
|
|
4459
|
+
|
|
4460
|
+
async previewApiIntegrationUninstall(
|
|
4461
|
+
workspaceId: string,
|
|
4462
|
+
capabilityId: string,
|
|
4463
|
+
instanceKey: string,
|
|
4464
|
+
): Promise<ApiIntegrationUninstallPreview> {
|
|
4465
|
+
return await this.requestJson<ApiIntegrationUninstallPreview>(
|
|
4466
|
+
"GET",
|
|
4467
|
+
`/v1/workspaces/${workspaceId}/integrations/${encodeURIComponent(capabilityId)}/instances/${encodeURIComponent(instanceKey)}/uninstall-preview`,
|
|
4468
|
+
);
|
|
4469
|
+
}
|
|
4470
|
+
|
|
4471
|
+
/** Remove one Integration instance without deleting its Connection or sibling instances. */
|
|
4472
|
+
async uninstallApiIntegration(
|
|
4473
|
+
workspaceId: string,
|
|
4474
|
+
capabilityId: string,
|
|
4475
|
+
instanceKey: string,
|
|
4476
|
+
request: UninstallApiIntegrationRequest,
|
|
4477
|
+
): Promise<UninstallApiIntegrationResult> {
|
|
4478
|
+
return await this.requestJson<UninstallApiIntegrationResult>(
|
|
4479
|
+
"DELETE",
|
|
4480
|
+
`/v1/workspaces/${workspaceId}/integrations/${encodeURIComponent(capabilityId)}/instances/${encodeURIComponent(instanceKey)}`,
|
|
4481
|
+
request,
|
|
4482
|
+
);
|
|
4483
|
+
}
|
|
4484
|
+
|
|
4485
|
+
/** List immutable provider facets and their exact per-account bindings. */
|
|
4486
|
+
async listIntegrationFeatures(
|
|
4487
|
+
workspaceId: string,
|
|
4488
|
+
capabilityId: string,
|
|
4489
|
+
instanceKey: string,
|
|
4490
|
+
): Promise<IntegrationInstanceFeaturesResponse> {
|
|
4491
|
+
return await this.requestJson<IntegrationInstanceFeaturesResponse>(
|
|
4492
|
+
"GET",
|
|
4493
|
+
`/v1/workspaces/${workspaceId}/integrations/${encodeURIComponent(capabilityId)}/instances/${encodeURIComponent(instanceKey)}/features`,
|
|
4494
|
+
);
|
|
4495
|
+
}
|
|
4496
|
+
|
|
4497
|
+
/** Configure or OCC-update one adapter-owned feature on an Integration instance. */
|
|
4498
|
+
async configureIntegrationFeature(
|
|
4499
|
+
workspaceId: string,
|
|
4500
|
+
capabilityId: string,
|
|
4501
|
+
instanceKey: string,
|
|
4502
|
+
featureKey: string,
|
|
4503
|
+
request: UpsertIntegrationFeatureRequest,
|
|
4504
|
+
): Promise<IntegrationFeatureMutationResult> {
|
|
4505
|
+
return await this.requestJson<IntegrationFeatureMutationResult>(
|
|
4506
|
+
"PUT",
|
|
4507
|
+
`/v1/workspaces/${workspaceId}/integrations/${encodeURIComponent(capabilityId)}/instances/${encodeURIComponent(instanceKey)}/features/${encodeURIComponent(featureKey)}`,
|
|
4508
|
+
request,
|
|
4509
|
+
);
|
|
4510
|
+
}
|
|
4511
|
+
|
|
4512
|
+
/** Browse source metadata through one exact Google Drive Integration instance. */
|
|
4513
|
+
async browseGoogleDriveIntegrationSource(
|
|
4514
|
+
workspaceId: string,
|
|
4515
|
+
capabilityId: string,
|
|
4516
|
+
instanceKey: string,
|
|
4517
|
+
featureKey: string,
|
|
4518
|
+
options: { parentId?: string | undefined; pageToken?: string | undefined } = {},
|
|
4519
|
+
): Promise<GoogleDriveBrowseResponse> {
|
|
4520
|
+
const query = new URLSearchParams();
|
|
4521
|
+
if (options.parentId) query.set("parentId", options.parentId);
|
|
4522
|
+
if (options.pageToken) query.set("pageToken", options.pageToken);
|
|
4523
|
+
const suffix = query.size > 0 ? `?${query}` : "";
|
|
4524
|
+
return await this.requestJson<GoogleDriveBrowseResponse>(
|
|
4525
|
+
"GET",
|
|
4526
|
+
`/v1/workspaces/${workspaceId}/integrations/${encodeURIComponent(capabilityId)}/instances/${encodeURIComponent(instanceKey)}/features/${encodeURIComponent(featureKey)}/browse${suffix}`,
|
|
4527
|
+
);
|
|
4528
|
+
}
|
|
4529
|
+
|
|
4530
|
+
/** Verify and bind document sources to one exact Google Drive Integration instance. */
|
|
4531
|
+
async saveGoogleDriveIntegrationSource(
|
|
4532
|
+
workspaceId: string,
|
|
4533
|
+
capabilityId: string,
|
|
4534
|
+
instanceKey: string,
|
|
4535
|
+
featureKey: string,
|
|
4536
|
+
request: SaveGoogleDriveIntegrationSourceRequest,
|
|
4537
|
+
): Promise<IntegrationFeatureMutationResult> {
|
|
4538
|
+
return await this.requestJson<IntegrationFeatureMutationResult>(
|
|
4539
|
+
"PUT",
|
|
4540
|
+
`/v1/workspaces/${workspaceId}/integrations/${encodeURIComponent(capabilityId)}/instances/${encodeURIComponent(instanceKey)}/features/${encodeURIComponent(featureKey)}/source`,
|
|
4541
|
+
request,
|
|
4542
|
+
);
|
|
4543
|
+
}
|
|
4544
|
+
|
|
4545
|
+
async pauseIntegrationFeature(
|
|
4546
|
+
workspaceId: string,
|
|
4547
|
+
capabilityId: string,
|
|
4548
|
+
instanceKey: string,
|
|
4549
|
+
featureKey: string,
|
|
4550
|
+
request: MutateIntegrationFeatureRequest,
|
|
4551
|
+
): Promise<IntegrationFeatureMutationResult> {
|
|
4552
|
+
return await this.mutateIntegrationFeatureLifecycle(
|
|
4553
|
+
workspaceId,
|
|
4554
|
+
capabilityId,
|
|
4555
|
+
instanceKey,
|
|
4556
|
+
featureKey,
|
|
4557
|
+
"pause",
|
|
4558
|
+
request,
|
|
4559
|
+
);
|
|
4560
|
+
}
|
|
4561
|
+
|
|
4562
|
+
async resumeIntegrationFeature(
|
|
4563
|
+
workspaceId: string,
|
|
4564
|
+
capabilityId: string,
|
|
4565
|
+
instanceKey: string,
|
|
4566
|
+
featureKey: string,
|
|
4567
|
+
request: MutateIntegrationFeatureRequest,
|
|
4568
|
+
): Promise<IntegrationFeatureMutationResult> {
|
|
4569
|
+
return await this.mutateIntegrationFeatureLifecycle(
|
|
4570
|
+
workspaceId,
|
|
4571
|
+
capabilityId,
|
|
4572
|
+
instanceKey,
|
|
4573
|
+
featureKey,
|
|
4574
|
+
"resume",
|
|
4575
|
+
request,
|
|
4576
|
+
);
|
|
4577
|
+
}
|
|
4578
|
+
|
|
4579
|
+
async removeIntegrationFeature(
|
|
4580
|
+
workspaceId: string,
|
|
4581
|
+
capabilityId: string,
|
|
4582
|
+
instanceKey: string,
|
|
4583
|
+
featureKey: string,
|
|
4584
|
+
request: MutateIntegrationFeatureRequest,
|
|
4585
|
+
): Promise<IntegrationFeatureRemovalResult> {
|
|
4586
|
+
return await this.requestJson<IntegrationFeatureRemovalResult>(
|
|
4587
|
+
"DELETE",
|
|
4588
|
+
`/v1/workspaces/${workspaceId}/integrations/${encodeURIComponent(capabilityId)}/instances/${encodeURIComponent(instanceKey)}/features/${encodeURIComponent(featureKey)}`,
|
|
4589
|
+
request,
|
|
4590
|
+
);
|
|
4591
|
+
}
|
|
4592
|
+
|
|
4593
|
+
private async mutateIntegrationFeatureLifecycle(
|
|
4594
|
+
workspaceId: string,
|
|
4595
|
+
capabilityId: string,
|
|
4596
|
+
instanceKey: string,
|
|
4597
|
+
featureKey: string,
|
|
4598
|
+
action: "pause" | "resume",
|
|
4599
|
+
request: MutateIntegrationFeatureRequest,
|
|
4600
|
+
): Promise<IntegrationFeatureMutationResult> {
|
|
4601
|
+
return await this.requestJson<IntegrationFeatureMutationResult>(
|
|
4602
|
+
"POST",
|
|
4603
|
+
`/v1/workspaces/${workspaceId}/integrations/${encodeURIComponent(capabilityId)}/instances/${encodeURIComponent(instanceKey)}/features/${encodeURIComponent(featureKey)}/${action}`,
|
|
4604
|
+
request,
|
|
4605
|
+
);
|
|
4606
|
+
}
|
|
4607
|
+
|
|
4608
|
+
async previewPlugin(workspaceId: string, request: PreviewPluginRequest): Promise<PluginPreview> {
|
|
4609
|
+
return await this.requestJson<PluginPreview>(
|
|
4610
|
+
"POST",
|
|
4611
|
+
`/v1/workspaces/${workspaceId}/plugins/preview`,
|
|
4612
|
+
request,
|
|
4613
|
+
);
|
|
4614
|
+
}
|
|
4615
|
+
|
|
4616
|
+
async listInstalledPlugins(workspaceId: string): Promise<ListInstalledPluginsResponse> {
|
|
4617
|
+
return await this.requestJson<ListInstalledPluginsResponse>(
|
|
4618
|
+
"GET",
|
|
4619
|
+
`/v1/workspaces/${workspaceId}/plugins`,
|
|
4620
|
+
);
|
|
4621
|
+
}
|
|
4622
|
+
|
|
4623
|
+
async installPlugin(
|
|
4624
|
+
workspaceId: string,
|
|
4625
|
+
request: InstallPluginRequest,
|
|
4626
|
+
): Promise<InstalledPlugin> {
|
|
4627
|
+
return await this.requestJson<InstalledPlugin>(
|
|
4628
|
+
"POST",
|
|
4629
|
+
`/v1/workspaces/${workspaceId}/plugins/install`,
|
|
4630
|
+
request,
|
|
4631
|
+
);
|
|
4632
|
+
}
|
|
4633
|
+
|
|
4634
|
+
async previewPluginUninstall(
|
|
4635
|
+
workspaceId: string,
|
|
4636
|
+
pluginKey: string,
|
|
4637
|
+
): Promise<PluginUninstallPreview> {
|
|
4638
|
+
return await this.requestJson<PluginUninstallPreview>(
|
|
4639
|
+
"GET",
|
|
4640
|
+
`/v1/workspaces/${workspaceId}/plugins/${encodeURIComponent(pluginKey)}/uninstall-preview`,
|
|
4641
|
+
);
|
|
4642
|
+
}
|
|
4643
|
+
|
|
4644
|
+
async uninstallPlugin(
|
|
4645
|
+
workspaceId: string,
|
|
4646
|
+
pluginKey: string,
|
|
4647
|
+
request: UninstallPluginRequest,
|
|
4648
|
+
): Promise<UninstallPluginResult> {
|
|
4649
|
+
return await this.requestJson<UninstallPluginResult>(
|
|
4650
|
+
"DELETE",
|
|
4651
|
+
`/v1/workspaces/${workspaceId}/plugins/${encodeURIComponent(pluginKey)}`,
|
|
4652
|
+
request,
|
|
4653
|
+
);
|
|
4654
|
+
}
|
|
4655
|
+
|
|
4656
|
+
/** Resolve one public skills.sh or GitHub Skill folder to an immutable review preview. */
|
|
4657
|
+
async previewSkillImport(
|
|
4658
|
+
workspaceId: string,
|
|
4659
|
+
request: PreviewSkillImportRequest,
|
|
4660
|
+
): Promise<SkillImportPreview> {
|
|
4661
|
+
return await this.requestJson<SkillImportPreview>(
|
|
4662
|
+
"POST",
|
|
4663
|
+
`/v1/workspaces/${workspaceId}/skills/preview`,
|
|
4664
|
+
request,
|
|
4665
|
+
);
|
|
4666
|
+
}
|
|
4667
|
+
|
|
4668
|
+
/** Install only the exact commit and full-content digest accepted during preview. */
|
|
4669
|
+
async installSkill(workspaceId: string, request: InstallSkillRequest): Promise<InstalledSkill> {
|
|
4670
|
+
return await this.requestJson<InstalledSkill>(
|
|
4671
|
+
"POST",
|
|
4672
|
+
`/v1/workspaces/${workspaceId}/skills/install`,
|
|
4673
|
+
request,
|
|
4674
|
+
);
|
|
4675
|
+
}
|
|
4676
|
+
|
|
4677
|
+
async previewSkillUninstall(
|
|
4678
|
+
workspaceId: string,
|
|
4679
|
+
capabilityId: string,
|
|
4680
|
+
): Promise<SkillUninstallPreview> {
|
|
4681
|
+
return await this.requestJson<SkillUninstallPreview>(
|
|
4682
|
+
"GET",
|
|
4683
|
+
`/v1/workspaces/${workspaceId}/skills/${encodeURIComponent(capabilityId)}/uninstall-preview`,
|
|
4684
|
+
);
|
|
4685
|
+
}
|
|
4686
|
+
|
|
4687
|
+
/** Remove the direct owner under an optimistic installation-version fence. */
|
|
4688
|
+
async uninstallSkill(
|
|
4689
|
+
workspaceId: string,
|
|
4690
|
+
capabilityId: string,
|
|
4691
|
+
request: UninstallSkillRequest,
|
|
4692
|
+
): Promise<UninstallSkillResult> {
|
|
4693
|
+
return await this.requestJson<UninstallSkillResult>(
|
|
4694
|
+
"DELETE",
|
|
4695
|
+
`/v1/workspaces/${workspaceId}/skills/${encodeURIComponent(capabilityId)}`,
|
|
4696
|
+
request,
|
|
4697
|
+
);
|
|
4698
|
+
}
|
|
4699
|
+
|
|
3212
4700
|
// --- Connections -------------------------------------------------------------------------------
|
|
3213
4701
|
|
|
3214
4702
|
async listConnections(workspaceId: string): Promise<ConnectionMetadata[]> {
|
|
@@ -3219,6 +4707,15 @@ export class OpenGeniClient {
|
|
|
3219
4707
|
return response.connections;
|
|
3220
4708
|
}
|
|
3221
4709
|
|
|
4710
|
+
/** List the secret-free Slack team -> OpenGeni tenant routing authority. */
|
|
4711
|
+
async listSlackInstallationBindings(workspaceId: string): Promise<SlackInstallationBinding[]> {
|
|
4712
|
+
const response = await this.requestJson<ListSlackInstallationBindingsResponse>(
|
|
4713
|
+
"GET",
|
|
4714
|
+
`/v1/workspaces/${workspaceId}/connections/slack-bot/bindings`,
|
|
4715
|
+
);
|
|
4716
|
+
return response.bindings;
|
|
4717
|
+
}
|
|
4718
|
+
|
|
3222
4719
|
async createConnection(
|
|
3223
4720
|
workspaceId: string,
|
|
3224
4721
|
request: CreateConnectionRequest,
|
|
@@ -3361,8 +4858,16 @@ export class OpenGeniClient {
|
|
|
3361
4858
|
// --- GitHub ----------------------------------------------------------------------------------
|
|
3362
4859
|
|
|
3363
4860
|
/** GitHub App server configuration plus truthful workspace binding status. */
|
|
3364
|
-
async getGitHubApp(
|
|
3365
|
-
|
|
4861
|
+
async getGitHubApp(
|
|
4862
|
+
workspaceId: string,
|
|
4863
|
+
options: { returnPath?: string } = {},
|
|
4864
|
+
): Promise<GitHubAppInfo> {
|
|
4865
|
+
return await this.requestJson<GitHubAppInfo>(
|
|
4866
|
+
"GET",
|
|
4867
|
+
`/v1/workspaces/${workspaceId}/github/app`,
|
|
4868
|
+
undefined,
|
|
4869
|
+
options.returnPath ? { returnPath: options.returnPath } : undefined,
|
|
4870
|
+
);
|
|
3366
4871
|
}
|
|
3367
4872
|
|
|
3368
4873
|
/** Build the GitHub owner-consent entry URL for fresh workspace-bound state. */
|
|
@@ -3682,7 +5187,8 @@ export class OpenGeniClient {
|
|
|
3682
5187
|
);
|
|
3683
5188
|
}
|
|
3684
5189
|
|
|
3685
|
-
|
|
5190
|
+
/** Contract-checked JSON transport shared by opt-in typed SDK clients. */
|
|
5191
|
+
async requestJson<T>(
|
|
3686
5192
|
method: string,
|
|
3687
5193
|
path: string,
|
|
3688
5194
|
body?: unknown,
|
|
@@ -3723,6 +5229,35 @@ export class OpenGeniClient {
|
|
|
3723
5229
|
}
|
|
3724
5230
|
}
|
|
3725
5231
|
|
|
5232
|
+
/** Authenticated, contract-checked response for bounded streaming downloads. */
|
|
5233
|
+
protected async requestResponse(
|
|
5234
|
+
method: string,
|
|
5235
|
+
path: string,
|
|
5236
|
+
query: Record<string, string> = {},
|
|
5237
|
+
options: OpenGeniRequestOptions = {},
|
|
5238
|
+
): Promise<Response> {
|
|
5239
|
+
const correlationId = crypto.randomUUID();
|
|
5240
|
+
let response: Response;
|
|
5241
|
+
try {
|
|
5242
|
+
response = await this.fetchImpl(this.url(path, query), {
|
|
5243
|
+
method,
|
|
5244
|
+
headers: {
|
|
5245
|
+
...this.headers(correlationId),
|
|
5246
|
+
Accept: "application/octet-stream",
|
|
5247
|
+
},
|
|
5248
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
5249
|
+
});
|
|
5250
|
+
} catch (error) {
|
|
5251
|
+
if (isMutationMethod(method)) throw mutationTransportError(correlationId);
|
|
5252
|
+
throw error;
|
|
5253
|
+
}
|
|
5254
|
+
assertApiContractResponse(response);
|
|
5255
|
+
if (!response.ok) {
|
|
5256
|
+
throw await apiErrorFromResponse(response, { method, correlationId });
|
|
5257
|
+
}
|
|
5258
|
+
return response;
|
|
5259
|
+
}
|
|
5260
|
+
|
|
3726
5261
|
/** Like `requestJson` for endpoints that respond with no body (204). */
|
|
3727
5262
|
private async requestVoid(method: string, path: string, body?: unknown): Promise<void> {
|
|
3728
5263
|
const correlationId = crypto.randomUUID();
|
|
@@ -3772,7 +5307,12 @@ function isUploadTranscriptionRecordingChunkResponse(
|
|
|
3772
5307
|
): value is UploadTranscriptionRecordingChunkResponse {
|
|
3773
5308
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
3774
5309
|
const record = value as Record<string, unknown>;
|
|
3775
|
-
if (
|
|
5310
|
+
if (
|
|
5311
|
+
!isTranscriptionRecordingResponse({
|
|
5312
|
+
recording: record.recording,
|
|
5313
|
+
segments: [],
|
|
5314
|
+
})
|
|
5315
|
+
) {
|
|
3776
5316
|
return false;
|
|
3777
5317
|
}
|
|
3778
5318
|
if (!record.chunk || typeof record.chunk !== "object" || Array.isArray(record.chunk)) {
|
|
@@ -3947,10 +5487,65 @@ async function sha256ForUpload(body: Blob | ArrayBuffer | string): Promise<strin
|
|
|
3947
5487
|
return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
3948
5488
|
}
|
|
3949
5489
|
|
|
5490
|
+
async function sha256Hex(bytes: Uint8Array): Promise<string> {
|
|
5491
|
+
const owned = Uint8Array.from(bytes);
|
|
5492
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", owned.buffer);
|
|
5493
|
+
return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
5494
|
+
}
|
|
5495
|
+
|
|
3950
5496
|
async function cancelResponseBody(response: Response, reason: string): Promise<void> {
|
|
3951
5497
|
await response.body?.cancel(reason).catch(() => undefined);
|
|
3952
5498
|
}
|
|
3953
5499
|
|
|
5500
|
+
function assertRetainedGeneratedImageReceipt(
|
|
5501
|
+
workspaceId: string,
|
|
5502
|
+
artifact: RetainedArtifactReference,
|
|
5503
|
+
): void {
|
|
5504
|
+
if (!parseRetainedGeneratedImageReference(artifact, workspaceId)) {
|
|
5505
|
+
throw new OpenGeniApiError(502, "retained generated image receipt is invalid");
|
|
5506
|
+
}
|
|
5507
|
+
}
|
|
5508
|
+
|
|
5509
|
+
function assertSafeArtifactDownloadUrl(value: FileDownloadUrlResponse): void {
|
|
5510
|
+
if (
|
|
5511
|
+
!value ||
|
|
5512
|
+
typeof value.url !== "string" ||
|
|
5513
|
+
typeof value.expiresAt !== "string" ||
|
|
5514
|
+
!Number.isFinite(Date.parse(value.expiresAt))
|
|
5515
|
+
) {
|
|
5516
|
+
throw new OpenGeniApiError(502, "retained artifact download URL is invalid");
|
|
5517
|
+
}
|
|
5518
|
+
let parsed: URL;
|
|
5519
|
+
try {
|
|
5520
|
+
parsed = new URL(value.url);
|
|
5521
|
+
} catch {
|
|
5522
|
+
throw new OpenGeniApiError(502, "retained artifact download URL is invalid");
|
|
5523
|
+
}
|
|
5524
|
+
if (!["http:", "https:"].includes(parsed.protocol) || parsed.username || parsed.password) {
|
|
5525
|
+
throw new OpenGeniApiError(502, "retained artifact download URL is unsafe");
|
|
5526
|
+
}
|
|
5527
|
+
}
|
|
5528
|
+
|
|
5529
|
+
function assertSafeVideoArtifactPlaybackSource(
|
|
5530
|
+
value: VideoArtifactPlaybackSource,
|
|
5531
|
+
expectedArtifactId: string,
|
|
5532
|
+
): void {
|
|
5533
|
+
if (
|
|
5534
|
+
!value ||
|
|
5535
|
+
value.schemaVersion !== 1 ||
|
|
5536
|
+
value.artifactId !== expectedArtifactId ||
|
|
5537
|
+
value.contentType !== "video/mp4" ||
|
|
5538
|
+
value.acceptRanges !== "bytes" ||
|
|
5539
|
+
!Number.isSafeInteger(value.sizeBytes) ||
|
|
5540
|
+
value.sizeBytes <= 0 ||
|
|
5541
|
+
value.sizeBytes > GENERATED_VIDEO_MAX_BYTES ||
|
|
5542
|
+
!/^[0-9a-f]{64}$/.test(value.sha256)
|
|
5543
|
+
) {
|
|
5544
|
+
throw new OpenGeniApiError(502, "generated-video playback source is invalid");
|
|
5545
|
+
}
|
|
5546
|
+
assertSafeArtifactDownloadUrl({ url: value.url, expiresAt: value.expiresAt });
|
|
5547
|
+
}
|
|
5548
|
+
|
|
3954
5549
|
function parseBoundedContentLength(value: string | null): number | null {
|
|
3955
5550
|
if (value === null) return null;
|
|
3956
5551
|
if (!/^\d+$/.test(value)) {
|