@opengeni/sdk 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -1
- package/dist/index.d.ts +390 -7
- package/dist/index.js +149 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +209 -0
- package/src/index.ts +37 -0
- package/src/types.ts +345 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Framework-agnostic TypeScript SDK for the OpenGeni API: typed client, session lifecycle, SSE event streaming with reconnect + replay-by-sequence, and proxy re-streaming helpers.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
package/src/client.ts
CHANGED
|
@@ -5,6 +5,14 @@ import type {
|
|
|
5
5
|
AddWorkspaceMemberRequest,
|
|
6
6
|
ApiKey,
|
|
7
7
|
BillingEntitlementsResponse,
|
|
8
|
+
CodexAccount,
|
|
9
|
+
CodexAccountsResponse,
|
|
10
|
+
CodexRotationSettings,
|
|
11
|
+
CodexConnectionStatus,
|
|
12
|
+
CodexConnectPoll,
|
|
13
|
+
CodexConnectStart,
|
|
14
|
+
CodexUsage,
|
|
15
|
+
CodexUsageMap,
|
|
8
16
|
BillingSummary,
|
|
9
17
|
BillingUsageResponse,
|
|
10
18
|
CapabilityCatalogItem,
|
|
@@ -28,6 +36,12 @@ import type {
|
|
|
28
36
|
CreateSessionRequest,
|
|
29
37
|
CreateWorkspaceEnvironmentRequest,
|
|
30
38
|
CreateWorkspaceRequest,
|
|
39
|
+
// Enrollment UX (design 11): the click-Grant approve-page lookup/deny + headless
|
|
40
|
+
// enroll-token mint.
|
|
41
|
+
DeviceEnrollmentApproveResponse,
|
|
42
|
+
DeviceEnrollmentDenyResponse,
|
|
43
|
+
DeviceEnrollmentLookupResponse,
|
|
44
|
+
MintEnrollTokenResponse,
|
|
31
45
|
DiscoverMcpCapabilitiesResponse,
|
|
32
46
|
Document,
|
|
33
47
|
DocumentBase,
|
|
@@ -41,6 +55,14 @@ import type {
|
|
|
41
55
|
GitHubRepositoriesResponse,
|
|
42
56
|
ListApiKeysResponse,
|
|
43
57
|
ListPacksResponse,
|
|
58
|
+
// Bring-your-own-compute: the Machines dashboard + per-machine metrics (M10).
|
|
59
|
+
MachinesResponse,
|
|
60
|
+
MachineView,
|
|
61
|
+
MetricSample,
|
|
62
|
+
MachineMetricsSeriesResponse,
|
|
63
|
+
// Bring-your-own-compute: the user-authenticated active-sandbox swap (M7).
|
|
64
|
+
SwapActiveSandboxRequest,
|
|
65
|
+
SwapActiveSandboxResponse,
|
|
44
66
|
ListWorkspaceMembersResponse,
|
|
45
67
|
PackInstallation,
|
|
46
68
|
ReasoningEffort,
|
|
@@ -91,6 +113,7 @@ import type {
|
|
|
91
113
|
ToolRef,
|
|
92
114
|
UpdateScheduledTaskRequest,
|
|
93
115
|
UpdateSessionGoalRequest,
|
|
116
|
+
UpdateSessionRequest,
|
|
94
117
|
UpdateSessionTurnRequest,
|
|
95
118
|
UpdateWorkspaceEnvironmentRequest,
|
|
96
119
|
UpdateWorkspaceMemberRequest,
|
|
@@ -165,6 +188,10 @@ export class OpenGeniClient {
|
|
|
165
188
|
return await this.requestJson<Session>("GET", `/v1/workspaces/${workspaceId}/sessions/${sessionId}`);
|
|
166
189
|
}
|
|
167
190
|
|
|
191
|
+
async updateSession(workspaceId: string, sessionId: string, request: UpdateSessionRequest): Promise<Session> {
|
|
192
|
+
return await this.requestJson<Session>("PATCH", `/v1/workspaces/${workspaceId}/sessions/${sessionId}`, request);
|
|
193
|
+
}
|
|
194
|
+
|
|
168
195
|
async listSessions(workspaceId: string, options: { limit?: number } = {}): Promise<Session[]> {
|
|
169
196
|
return await this.requestJson<Session[]>("GET", `/v1/workspaces/${workspaceId}/sessions`, undefined, {
|
|
170
197
|
...(options.limit !== undefined ? { limit: String(options.limit) } : {}),
|
|
@@ -177,6 +204,118 @@ export class OpenGeniClient {
|
|
|
177
204
|
});
|
|
178
205
|
}
|
|
179
206
|
|
|
207
|
+
// --- Bring-your-own-compute: Machines dashboard + metrics (M10) ------------
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* List the workspace's machines (the Machines dashboard). Each enrolled
|
|
211
|
+
* selfhosted machine carries its derived state + latest metrics +
|
|
212
|
+
* sharedSessionCount. Pass `sessionId` for an in-session view, which adds the
|
|
213
|
+
* session's synthetic Modal group box + the active-sandbox pointer.
|
|
214
|
+
*/
|
|
215
|
+
async listMachines(workspaceId: string, options: { sessionId?: string } = {}): Promise<MachinesResponse> {
|
|
216
|
+
return await this.requestJson<MachinesResponse>("GET", `/v1/workspaces/${workspaceId}/machines`, undefined, {
|
|
217
|
+
...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Read the downsampled (~1/min) metrics series for ONE machine over a time
|
|
223
|
+
* window (default 1h). The samples are oldest-first (a left-to-right chart).
|
|
224
|
+
*/
|
|
225
|
+
async machineMetricsSeries(
|
|
226
|
+
workspaceId: string,
|
|
227
|
+
enrollmentId: string,
|
|
228
|
+
options: { window?: "15m" | "1h" | "6h" | "24h" } = {},
|
|
229
|
+
): Promise<MetricSample[]> {
|
|
230
|
+
const response = await this.requestJson<MachineMetricsSeriesResponse>(
|
|
231
|
+
"GET",
|
|
232
|
+
`/v1/workspaces/${workspaceId}/machines/${enrollmentId}/metrics/series`,
|
|
233
|
+
undefined,
|
|
234
|
+
{ ...(options.window !== undefined ? { window: options.window } : {}) },
|
|
235
|
+
);
|
|
236
|
+
return response.samples;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// --- Self-hosted enrollment UX (design 11) --------------------------------
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Resolve a pending device-enrollment flow by its user_code for the click-Grant
|
|
243
|
+
* approve page (EnrollmentConsent). NO workspace in the path — the server
|
|
244
|
+
* resolves the workspace from the (globally-unique-among-pending) code, then
|
|
245
|
+
* authorizes the caller against it (enrollments:read). Rejects (404) when the
|
|
246
|
+
* code is unknown/expired OR the caller lacks the grant — the two are
|
|
247
|
+
* indistinguishable by design (no cross-workspace disclosure). Does not consume
|
|
248
|
+
* the request.
|
|
249
|
+
*/
|
|
250
|
+
async lookupDeviceEnrollment(userCode: string): Promise<DeviceEnrollmentLookupResponse> {
|
|
251
|
+
return await this.requestJson<DeviceEnrollmentLookupResponse>("POST", "/v1/enrollments/device/lookup", { userCode });
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Approve a pending device-enrollment flow (the LOUD consent step). `allowScreenControl`
|
|
256
|
+
* is the authoritative screen-control consent (whole-machine is mandatory/implicit).
|
|
257
|
+
* Lands an enrollment + a selfhosted sandbox and unblocks the agent's poll.
|
|
258
|
+
*/
|
|
259
|
+
async approveDeviceEnrollment(
|
|
260
|
+
workspaceId: string,
|
|
261
|
+
request: { userCode: string; allowScreenControl?: boolean },
|
|
262
|
+
): Promise<DeviceEnrollmentApproveResponse> {
|
|
263
|
+
return await this.requestJson<DeviceEnrollmentApproveResponse>(
|
|
264
|
+
"POST",
|
|
265
|
+
`/v1/workspaces/${workspaceId}/enrollments/device/approve`,
|
|
266
|
+
{ userCode: request.userCode, allowScreenControl: request.allowScreenControl ?? false },
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** Deny a pending device-enrollment flow (the explicit "no" at the approve page). */
|
|
271
|
+
async denyDeviceEnrollment(
|
|
272
|
+
workspaceId: string,
|
|
273
|
+
request: { userCode: string },
|
|
274
|
+
): Promise<DeviceEnrollmentDenyResponse> {
|
|
275
|
+
return await this.requestJson<DeviceEnrollmentDenyResponse>(
|
|
276
|
+
"POST",
|
|
277
|
+
`/v1/workspaces/${workspaceId}/enrollments/device/deny`,
|
|
278
|
+
{ userCode: request.userCode },
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Mint a short-TTL headless enroll token (the `oget_` token) for the fleet /
|
|
284
|
+
* non-interactive enroll path. The returned `token` is SECRET — surface it once
|
|
285
|
+
* with a copy-now warning; it cannot be re-read. `allowScreenControl` bakes the
|
|
286
|
+
* screen-control consent into the token.
|
|
287
|
+
*/
|
|
288
|
+
async mintEnrollToken(
|
|
289
|
+
workspaceId: string,
|
|
290
|
+
request: { allowScreenControl?: boolean } = {},
|
|
291
|
+
): Promise<MintEnrollTokenResponse> {
|
|
292
|
+
return await this.requestJson<MintEnrollTokenResponse>(
|
|
293
|
+
"POST",
|
|
294
|
+
`/v1/workspaces/${workspaceId}/enrollments/token`,
|
|
295
|
+
{ allowScreenControl: request.allowScreenControl ?? false },
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Swap a session's active sandbox (the user-authenticated equivalent of the
|
|
301
|
+
* M7 `sandbox_swap` MCP tool). `target` is a `MachineView.sandboxId` from
|
|
302
|
+
* `listMachines`, or "session"/"default" to swap back to the session's own
|
|
303
|
+
* group box. Validation (ownership/liveness/epoch fence) is server-side; the
|
|
304
|
+
* result echoes the resulting pointer (`swapped: false` + `reason` on a
|
|
305
|
+
* rejected target or a lost epoch fence).
|
|
306
|
+
*/
|
|
307
|
+
async swapActiveSandbox(
|
|
308
|
+
workspaceId: string,
|
|
309
|
+
sessionId: string,
|
|
310
|
+
request: SwapActiveSandboxRequest,
|
|
311
|
+
): Promise<SwapActiveSandboxResponse> {
|
|
312
|
+
return await this.requestJson<SwapActiveSandboxResponse>(
|
|
313
|
+
"POST",
|
|
314
|
+
`/v1/workspaces/${workspaceId}/sessions/${sessionId}/active-sandbox`,
|
|
315
|
+
request,
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
|
|
180
319
|
// --- Scheduled tasks -------------------------------------------------------
|
|
181
320
|
|
|
182
321
|
async listScheduledTasks(workspaceId: string, options: { limit?: number } = {}): Promise<ScheduledTask[]> {
|
|
@@ -1041,6 +1180,76 @@ export class OpenGeniClient {
|
|
|
1041
1180
|
return `${this.baseUrl}${path}${params ? `?${params}` : ""}`;
|
|
1042
1181
|
}
|
|
1043
1182
|
|
|
1183
|
+
// --- Codex (ChatGPT) subscription (workspace-scoped) --------------------------------------------
|
|
1184
|
+
|
|
1185
|
+
/** Connection state + the codex models the workspace may select (empty until connected). */
|
|
1186
|
+
async codexStatus(workspaceId: string): Promise<CodexConnectionStatus> {
|
|
1187
|
+
return await this.requestJson<CodexConnectionStatus>("GET", `/v1/workspaces/${workspaceId}/codex/status`);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
/** Begin device-code login: show `userCode` at `verificationUri`, then poll with `state`. */
|
|
1191
|
+
async codexConnectStart(workspaceId: string): Promise<CodexConnectStart> {
|
|
1192
|
+
return await this.requestJson<CodexConnectStart>("POST", `/v1/workspaces/${workspaceId}/codex/connect/start`);
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
/** Poll device-code authorization with the `state` from {@link codexConnectStart}. */
|
|
1196
|
+
async codexConnectPoll(workspaceId: string, state: string): Promise<CodexConnectPoll> {
|
|
1197
|
+
return await this.requestJson<CodexConnectPoll>("POST", `/v1/workspaces/${workspaceId}/codex/connect/poll`, { state });
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
/** Remaining usage / limits for the connected (ACTIVE) subscription. Back-compat. */
|
|
1201
|
+
async codexUsage(workspaceId: string): Promise<CodexUsage> {
|
|
1202
|
+
return await this.requestJson<CodexUsage>("GET", `/v1/workspaces/${workspaceId}/codex/usage`);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
/** Live per-account usage read (refreshes THIS account's bearer; writes the cache). */
|
|
1206
|
+
async codexAccountUsage(workspaceId: string, accountId: string): Promise<CodexUsage> {
|
|
1207
|
+
return await this.requestJson<CodexUsage>("GET", `/v1/workspaces/${workspaceId}/codex/accounts/${accountId}/usage`);
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
/** Batched live refresh across every connected account, keyed by credential id. */
|
|
1211
|
+
async refreshCodexUsage(workspaceId: string): Promise<{ usage: CodexUsageMap }> {
|
|
1212
|
+
return await this.requestJson<{ usage: CodexUsageMap }>("POST", `/v1/workspaces/${workspaceId}/codex/usage/refresh`);
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
/** Disconnect ALL accounts (legacy workspace-wide). Prefer `disconnectCodexAccount`. */
|
|
1216
|
+
async codexDisconnect(workspaceId: string): Promise<{ disconnected: boolean }> {
|
|
1217
|
+
return await this.requestJson<{ disconnected: boolean }>("DELETE", `/v1/workspaces/${workspaceId}/codex`);
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
/** List every connected Codex account + the workspace active pointer + settings. */
|
|
1221
|
+
async listCodexAccounts(workspaceId: string): Promise<CodexAccountsResponse> {
|
|
1222
|
+
return await this.requestJson<CodexAccountsResponse>("GET", `/v1/workspaces/${workspaceId}/codex/accounts`);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
/** Switch the workspace ACTIVE Codex account (the one unpinned sessions use). */
|
|
1226
|
+
async activateCodexAccount(workspaceId: string, accountId: string): Promise<{ activated: boolean; accountId: string }> {
|
|
1227
|
+
return await this.requestJson<{ activated: boolean; accountId: string }>("POST", `/v1/workspaces/${workspaceId}/codex/accounts/${accountId}/activate`);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
/** P3: enable/disable Codex auto-rotation and/or pick the strategy. Returns the effective settings. */
|
|
1231
|
+
async setCodexRotationSettings(
|
|
1232
|
+
workspaceId: string,
|
|
1233
|
+
patch: { rotationEnabled?: boolean; rotationStrategy?: CodexRotationSettings["rotationStrategy"] },
|
|
1234
|
+
): Promise<CodexRotationSettings> {
|
|
1235
|
+
return await this.requestJson<CodexRotationSettings>("PATCH", `/v1/workspaces/${workspaceId}/codex/settings`, patch);
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
/** Disconnect ONE Codex account by id (re-picks active when the removed one was active). */
|
|
1239
|
+
async disconnectCodexAccount(workspaceId: string, accountId: string): Promise<{ disconnected: boolean; newActiveId: string | null }> {
|
|
1240
|
+
return await this.requestJson<{ disconnected: boolean; newActiveId: string | null }>("DELETE", `/v1/workspaces/${workspaceId}/codex/accounts/${accountId}`);
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
/** Rename a Codex account (label only in P1). */
|
|
1244
|
+
async renameCodexAccount(workspaceId: string, accountId: string, label: string | null): Promise<CodexAccount> {
|
|
1245
|
+
return await this.requestJson<CodexAccount>("PATCH", `/v1/workspaces/${workspaceId}/codex/accounts/${accountId}`, { label });
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
/** Pin (or unpin via "auto") a session's Codex account. Applies on the next turn. */
|
|
1249
|
+
async pinSessionCodexAccount(workspaceId: string, sessionId: string, target: string): Promise<{ pinned: string }> {
|
|
1250
|
+
return await this.requestJson<{ pinned: string }>("POST", `/v1/workspaces/${workspaceId}/sessions/${sessionId}/codex-account`, { target });
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1044
1253
|
private async requestJson<T>(method: string, path: string, body?: unknown, query: Record<string, string> = {}): Promise<T> {
|
|
1045
1254
|
const response = await this.fetchImpl(this.url(path, query), {
|
|
1046
1255
|
method,
|
package/src/index.ts
CHANGED
|
@@ -73,6 +73,17 @@ export type {
|
|
|
73
73
|
CapabilityUnavailableReason,
|
|
74
74
|
ClientConfig,
|
|
75
75
|
ClientModel,
|
|
76
|
+
CodexAccount,
|
|
77
|
+
CodexAccountsResponse,
|
|
78
|
+
CodexAccountSwitchedPayload,
|
|
79
|
+
CodexConnectionStatus,
|
|
80
|
+
CodexConnectStart,
|
|
81
|
+
CodexConnectPoll,
|
|
82
|
+
CodexRotationSettings,
|
|
83
|
+
CodexUsage,
|
|
84
|
+
CodexUsageMap,
|
|
85
|
+
CodexUsagePayload,
|
|
86
|
+
CodexUsageWindow,
|
|
76
87
|
CompactSessionContextResult,
|
|
77
88
|
ClientSessionEventInput,
|
|
78
89
|
CompleteFileUploadResponse,
|
|
@@ -228,6 +239,7 @@ export type {
|
|
|
228
239
|
ToolRef,
|
|
229
240
|
UpdateScheduledTaskRequest,
|
|
230
241
|
UpdateSessionGoalRequest,
|
|
242
|
+
UpdateSessionRequest,
|
|
231
243
|
UpdateSessionTurnRequest,
|
|
232
244
|
UpdateWorkspaceEnvironmentRequest,
|
|
233
245
|
UpdateWorkspaceMemberRequest,
|
|
@@ -243,4 +255,29 @@ export type {
|
|
|
243
255
|
WorkspaceEnvironmentVariableMetadata,
|
|
244
256
|
WorkspaceMember,
|
|
245
257
|
WorkspaceRegisteredPack,
|
|
258
|
+
// Bring-your-own-compute: Machines dashboard + per-machine metrics (M10).
|
|
259
|
+
MetricSample,
|
|
260
|
+
MachineState,
|
|
261
|
+
MachineKind,
|
|
262
|
+
MachineView,
|
|
263
|
+
MachinesResponse,
|
|
264
|
+
MachineMetricsSeriesResponse,
|
|
265
|
+
// Bring-your-own-compute: the user-authenticated active-sandbox swap (M7).
|
|
266
|
+
SwapActiveSandboxRequest,
|
|
267
|
+
SwapActiveSandboxResponse,
|
|
268
|
+
// Self-hosted enrollment UX (design 11): click-Grant approve-page lookup/deny +
|
|
269
|
+
// headless enroll-token mint/exchange.
|
|
270
|
+
EnrollmentOs,
|
|
271
|
+
DeviceEnrollmentLookupRequest,
|
|
272
|
+
DeviceEnrollmentLookupResponse,
|
|
273
|
+
DeviceEnrollmentLookupMachine,
|
|
274
|
+
DeviceEnrollmentApproveRequest,
|
|
275
|
+
DeviceEnrollmentApproveResponse,
|
|
276
|
+
DeviceEnrollmentDenyRequest,
|
|
277
|
+
DeviceEnrollmentDenyResponse,
|
|
278
|
+
MintEnrollTokenRequest,
|
|
279
|
+
MintEnrollTokenResponse,
|
|
280
|
+
EnrollmentCredentials,
|
|
281
|
+
EnrollTokenExchangeRequest,
|
|
282
|
+
EnrollTokenExchangeResponse,
|
|
246
283
|
} from "./types";
|