@opengeni/sdk 0.23.0 → 0.25.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/dist/index.d.ts +126 -6
- package/dist/index.js +89 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +111 -34
- package/src/errors.ts +22 -1
- package/src/index.ts +9 -0
- package/src/types.ts +173 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.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
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
OpenGeniApiContractMismatchError,
|
|
3
|
+
OpenGeniApiError,
|
|
4
|
+
OpenGeniSessionListCursorError,
|
|
5
|
+
} from "./errors";
|
|
2
6
|
import {
|
|
3
7
|
streamSessionEvents,
|
|
4
8
|
type SessionEventStreamTransport,
|
|
@@ -112,7 +116,9 @@ import type {
|
|
|
112
116
|
DeleteSessionQueueItemRequest,
|
|
113
117
|
EditSessionQueueItemRequest,
|
|
114
118
|
MoveSessionQueueItemRequest,
|
|
119
|
+
NewSessionDraft,
|
|
115
120
|
SaveComposerDraftRequest,
|
|
121
|
+
SaveNewSessionDraftRequest,
|
|
116
122
|
SteerSessionQueueItemRequest,
|
|
117
123
|
SessionControlResponse,
|
|
118
124
|
WorkspaceInferenceControlResponse,
|
|
@@ -193,6 +199,17 @@ import {
|
|
|
193
199
|
RETAINED_OUTPUT_MAX_PAGE_BYTES,
|
|
194
200
|
} from "./types";
|
|
195
201
|
|
|
202
|
+
function sessionListQuery(options: {
|
|
203
|
+
limit?: number;
|
|
204
|
+
parentSessionId?: string | null;
|
|
205
|
+
}): Record<string, string> {
|
|
206
|
+
const { limit, parentSessionId } = options;
|
|
207
|
+
return {
|
|
208
|
+
...(limit === undefined ? {} : { limit: String(limit) }),
|
|
209
|
+
...(parentSessionId === undefined ? {} : { parentSessionId: parentSessionId ?? "null" }),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
196
213
|
export type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
197
214
|
|
|
198
215
|
export type WorkspaceControlEventPage = {
|
|
@@ -269,6 +286,24 @@ export class OpenGeniClient {
|
|
|
269
286
|
);
|
|
270
287
|
}
|
|
271
288
|
|
|
289
|
+
async getNewSessionDraft(workspaceId: string): Promise<NewSessionDraft> {
|
|
290
|
+
return await this.requestJson<NewSessionDraft>(
|
|
291
|
+
"GET",
|
|
292
|
+
`/v1/workspaces/${workspaceId}/new-session-draft`,
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
async saveNewSessionDraft(
|
|
297
|
+
workspaceId: string,
|
|
298
|
+
request: SaveNewSessionDraftRequest,
|
|
299
|
+
): Promise<NewSessionDraft> {
|
|
300
|
+
return await this.requestJson<NewSessionDraft>(
|
|
301
|
+
"PUT",
|
|
302
|
+
`/v1/workspaces/${workspaceId}/new-session-draft`,
|
|
303
|
+
request,
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
272
307
|
async getSession(workspaceId: string, sessionId: string): Promise<Session> {
|
|
273
308
|
return await this.requestJson<Session>(
|
|
274
309
|
"GET",
|
|
@@ -314,21 +349,21 @@ export class OpenGeniClient {
|
|
|
314
349
|
search?: string;
|
|
315
350
|
} = {},
|
|
316
351
|
): Promise<Session[]> {
|
|
352
|
+
// Search was added with the pin-aware page endpoint. An older API silently
|
|
353
|
+
// ignores unknown query parameters on the historical array endpoint, which
|
|
354
|
+
// would turn a search into a plausible-looking unfiltered result. Route
|
|
355
|
+
// searches through listSessionPage so its rolling-version shape check can
|
|
356
|
+
// fail explicitly on an older server; retain the array endpoint for every
|
|
357
|
+
// pre-existing call shape.
|
|
358
|
+
if (options.search?.trim()) {
|
|
359
|
+
const page = await this.listSessionPage(workspaceId, options);
|
|
360
|
+
return [...page.pinned, ...page.sessions];
|
|
361
|
+
}
|
|
317
362
|
return await this.requestJson<Session[]>(
|
|
318
363
|
"GET",
|
|
319
364
|
`/v1/workspaces/${workspaceId}/sessions`,
|
|
320
365
|
undefined,
|
|
321
|
-
|
|
322
|
-
...(options.limit !== undefined ? { limit: String(options.limit) } : {}),
|
|
323
|
-
...(options.search?.trim() ? { search: options.search.trim() } : {}),
|
|
324
|
-
...(Object.prototype.hasOwnProperty.call(options, "parentSessionId") &&
|
|
325
|
-
options.parentSessionId !== undefined
|
|
326
|
-
? {
|
|
327
|
-
parentSessionId:
|
|
328
|
-
options.parentSessionId === null ? "null" : String(options.parentSessionId),
|
|
329
|
-
}
|
|
330
|
-
: {}),
|
|
331
|
-
},
|
|
366
|
+
sessionListQuery(options),
|
|
332
367
|
);
|
|
333
368
|
}
|
|
334
369
|
|
|
@@ -340,26 +375,51 @@ export class OpenGeniClient {
|
|
|
340
375
|
parentSessionId?: string | null;
|
|
341
376
|
cursor?: string;
|
|
342
377
|
search?: string;
|
|
378
|
+
/** Return only the complete personal pinned projection. */
|
|
379
|
+
pinsOnly?: boolean;
|
|
343
380
|
} = {},
|
|
344
381
|
): Promise<SessionListResponse> {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
? {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
382
|
+
const search = options.search?.trim();
|
|
383
|
+
let response: SessionListResponse | Session[];
|
|
384
|
+
try {
|
|
385
|
+
response = await this.requestJson<SessionListResponse | Session[]>(
|
|
386
|
+
"GET",
|
|
387
|
+
`/v1/workspaces/${workspaceId}/sessions`,
|
|
388
|
+
undefined,
|
|
389
|
+
{
|
|
390
|
+
view: "page",
|
|
391
|
+
...sessionListQuery(options),
|
|
392
|
+
...(options.cursor !== undefined ? { cursor: options.cursor } : {}),
|
|
393
|
+
...(search ? { search } : {}),
|
|
394
|
+
...(options.pinsOnly ? { pinsOnly: "true" } : {}),
|
|
395
|
+
},
|
|
396
|
+
);
|
|
397
|
+
} catch (error) {
|
|
398
|
+
if (error instanceof OpenGeniApiError && error.status === 410) {
|
|
399
|
+
throw new OpenGeniSessionListCursorError(error.status, error.body);
|
|
400
|
+
}
|
|
401
|
+
throw error;
|
|
402
|
+
}
|
|
403
|
+
if (Array.isArray(response)) {
|
|
404
|
+
// Rolling/same-major compatibility: an older API ignores `view=page` and
|
|
405
|
+
// returns the historical array. That is an honest one-page projection;
|
|
406
|
+
// never pretend it honored a cursor supplied directly by a caller.
|
|
407
|
+
if (options.cursor) {
|
|
408
|
+
throw new Error("The connected OpenGeni API does not support stable session-page cursors");
|
|
409
|
+
}
|
|
410
|
+
// Older APIs ignore unknown query parameters. Treating their unfiltered
|
|
411
|
+
// array as a successful search would be worse than an explicit rolling-
|
|
412
|
+
// upgrade error (and client-side filtering cannot recover matches beyond
|
|
413
|
+
// the old endpoint's bounded first page).
|
|
414
|
+
if (search) {
|
|
415
|
+
throw new Error("The connected OpenGeni API does not support session search");
|
|
416
|
+
}
|
|
417
|
+
if (options.pinsOnly) {
|
|
418
|
+
throw new Error("The connected OpenGeni API does not support pins-only session lists");
|
|
419
|
+
}
|
|
420
|
+
return { pinned: [], sessions: response, nextCursor: null };
|
|
421
|
+
}
|
|
422
|
+
return response;
|
|
363
423
|
}
|
|
364
424
|
|
|
365
425
|
/** Set this authenticated member's personal workspace pin for a session. */
|
|
@@ -1919,21 +1979,27 @@ export class OpenGeniClient {
|
|
|
1919
1979
|
* -> complete. Returns the ready `FileAsset`.
|
|
1920
1980
|
*/
|
|
1921
1981
|
async uploadFile(workspaceId: string, input: UploadFileInput): Promise<FileAsset> {
|
|
1922
|
-
//
|
|
1923
|
-
//
|
|
1982
|
+
// Snapshot mutable inputs before hashing so the digest always describes the
|
|
1983
|
+
// exact bytes later sent to object storage. Copy Uint8Array views into a
|
|
1984
|
+
// Blob so byte offsets/shared buffers can't leak surrounding bytes.
|
|
1924
1985
|
const body: Blob | ArrayBuffer | string =
|
|
1925
|
-
input.data instanceof Uint8Array
|
|
1986
|
+
input.data instanceof Uint8Array
|
|
1987
|
+
? new Blob([input.data.slice()])
|
|
1988
|
+
: input.data instanceof ArrayBuffer
|
|
1989
|
+
? input.data.slice(0)
|
|
1990
|
+
: input.data;
|
|
1926
1991
|
const sizeBytes =
|
|
1927
1992
|
typeof body === "string"
|
|
1928
1993
|
? new TextEncoder().encode(body).byteLength
|
|
1929
1994
|
: body instanceof Blob
|
|
1930
1995
|
? body.size
|
|
1931
1996
|
: body.byteLength;
|
|
1997
|
+
const sha256 = input.sha256 ?? (await sha256ForUpload(body));
|
|
1932
1998
|
const upload = await this.beginFileUpload(workspaceId, {
|
|
1933
1999
|
filename: input.filename,
|
|
1934
2000
|
contentType: input.contentType,
|
|
1935
2001
|
sizeBytes,
|
|
1936
|
-
|
|
2002
|
+
sha256,
|
|
1937
2003
|
});
|
|
1938
2004
|
const putResponse = await this.fetchImpl(upload.putUrl, {
|
|
1939
2005
|
method: "PUT",
|
|
@@ -2720,6 +2786,17 @@ function assertApiContractResponse(response: Response): void {
|
|
|
2720
2786
|
}
|
|
2721
2787
|
}
|
|
2722
2788
|
|
|
2789
|
+
async function sha256ForUpload(body: Blob | ArrayBuffer | string): Promise<string> {
|
|
2790
|
+
const bytes =
|
|
2791
|
+
typeof body === "string"
|
|
2792
|
+
? new TextEncoder().encode(body)
|
|
2793
|
+
: body instanceof Blob
|
|
2794
|
+
? new Uint8Array(await body.arrayBuffer())
|
|
2795
|
+
: new Uint8Array(body);
|
|
2796
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
|
|
2797
|
+
return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2723
2800
|
async function safeText(response: Response): Promise<string> {
|
|
2724
2801
|
try {
|
|
2725
2802
|
return await response.text();
|
package/src/errors.ts
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
/** Error for a non-2xx OpenGeni API response. */
|
|
2
2
|
export class OpenGeniApiError extends Error {
|
|
3
3
|
readonly status: number;
|
|
4
|
+
readonly code: string | undefined;
|
|
4
5
|
readonly body: string;
|
|
5
6
|
|
|
6
7
|
constructor(status: number, body: string) {
|
|
7
|
-
|
|
8
|
+
const decoded = decodeApiErrorBody(body);
|
|
9
|
+
super(`OpenGeni API ${status}: ${decoded.message ?? (body || "(empty body)")}`);
|
|
8
10
|
this.name = "OpenGeniApiError";
|
|
9
11
|
this.status = status;
|
|
12
|
+
this.code = decoded.code;
|
|
10
13
|
this.body = body;
|
|
11
14
|
}
|
|
12
15
|
}
|
|
13
16
|
|
|
17
|
+
function decodeApiErrorBody(body: string): { code?: string; message?: string } {
|
|
18
|
+
if (!body) return {};
|
|
19
|
+
try {
|
|
20
|
+
const decoded: unknown = JSON.parse(body);
|
|
21
|
+
if (!decoded || typeof decoded !== "object" || Array.isArray(decoded)) return {};
|
|
22
|
+
const record = decoded as Record<string, unknown>;
|
|
23
|
+
return {
|
|
24
|
+
...(typeof record.code === "string" && record.code ? { code: record.code } : {}),
|
|
25
|
+
...(typeof record.message === "string" && record.message ? { message: record.message } : {}),
|
|
26
|
+
};
|
|
27
|
+
} catch {
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** A short-lived session-list snapshot cursor can no longer be continued. */
|
|
33
|
+
export class OpenGeniSessionListCursorError extends OpenGeniApiError {}
|
|
34
|
+
|
|
14
35
|
/** The browser bundle and API disagree about their state-changing wire contract. */
|
|
15
36
|
export class OpenGeniApiContractMismatchError extends Error {
|
|
16
37
|
readonly expected: string;
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type {
|
|
|
10
10
|
export {
|
|
11
11
|
OpenGeniApiContractMismatchError,
|
|
12
12
|
OpenGeniApiError,
|
|
13
|
+
OpenGeniSessionListCursorError,
|
|
13
14
|
OpenGeniStreamError,
|
|
14
15
|
isRetryableStreamError,
|
|
15
16
|
} from "./errors";
|
|
@@ -142,6 +143,11 @@ export type {
|
|
|
142
143
|
CodexConnectionStatus,
|
|
143
144
|
CodexConnectStart,
|
|
144
145
|
CodexConnectPoll,
|
|
146
|
+
CodexFleetConfidence,
|
|
147
|
+
CodexFleetCacheState,
|
|
148
|
+
CodexFleetDecisionEventPayload,
|
|
149
|
+
CodexFleetDecisionScore,
|
|
150
|
+
CodexFleetShadowComparison,
|
|
145
151
|
CodexOverviewResponse,
|
|
146
152
|
CodexResetCredit,
|
|
147
153
|
CodexResetRedemptionRecovery,
|
|
@@ -276,7 +282,10 @@ export type {
|
|
|
276
282
|
EffectiveControlResumeOption,
|
|
277
283
|
EffectiveSessionControl,
|
|
278
284
|
MoveSessionQueueItemRequest,
|
|
285
|
+
NewSessionDraft,
|
|
286
|
+
NewSessionDraftOptions,
|
|
279
287
|
SaveComposerDraftRequest,
|
|
288
|
+
SaveNewSessionDraftRequest,
|
|
280
289
|
SessionCommandReceipt,
|
|
281
290
|
SteerSessionQueueItemRequest,
|
|
282
291
|
WorkspaceInferenceControlResponse,
|
package/src/types.ts
CHANGED
|
@@ -65,6 +65,9 @@ export type SessionCapabilities = {
|
|
|
65
65
|
os: SandboxOs;
|
|
66
66
|
liveness: "cold" | "warming" | "warm" | "draining";
|
|
67
67
|
leaseEpoch: number;
|
|
68
|
+
workspaceGeneration: number | null;
|
|
69
|
+
archiveGeneration: number | null;
|
|
70
|
+
archiveComplete: boolean;
|
|
68
71
|
viewerHeartbeatIntervalMs: number;
|
|
69
72
|
FileSystem: {
|
|
70
73
|
available: boolean;
|
|
@@ -182,6 +185,9 @@ export type ViewerHolder = {
|
|
|
182
185
|
sandboxGroupId: string;
|
|
183
186
|
liveness: "cold" | "warming" | "warm" | "draining";
|
|
184
187
|
leaseEpoch: number;
|
|
188
|
+
workspaceGeneration: number | null;
|
|
189
|
+
archiveGeneration: number | null;
|
|
190
|
+
archiveComplete: boolean;
|
|
185
191
|
viewerHeartbeatIntervalMs: number;
|
|
186
192
|
dataPlaneUrl: string | null;
|
|
187
193
|
};
|
|
@@ -487,6 +493,13 @@ export type Session = {
|
|
|
487
493
|
firstPartyMcpPermissions: string[] | null;
|
|
488
494
|
mcpServers: SessionMcpServerMetadata[];
|
|
489
495
|
parentSessionId: string | null;
|
|
496
|
+
/** Immutable server-authored nested-agent lineage and policy snapshot. */
|
|
497
|
+
rootSessionId: string;
|
|
498
|
+
nestedAgentDepth: number;
|
|
499
|
+
maxNestedAgentDepthOverride: number | null;
|
|
500
|
+
effectiveMaxNestedAgentDepth: number;
|
|
501
|
+
nestedAgentDepthPolicySource: "session" | "workspace" | "deployment" | "default";
|
|
502
|
+
nestedAgentDepthPolicySessionId: string | null;
|
|
490
503
|
createIdempotencyKey: string | null;
|
|
491
504
|
temporalWorkflowId: string | null;
|
|
492
505
|
activeTurnId: string | null;
|
|
@@ -753,6 +766,8 @@ export const SESSION_EVENT_TYPES = [
|
|
|
753
766
|
"codex.account.switched",
|
|
754
767
|
// credential allocator metadata-only per-turn credential selection audit.
|
|
755
768
|
"codex.credential.selected",
|
|
769
|
+
// Bounded, identity-free deterministic shadow/replay decision.
|
|
770
|
+
"codex.fleet.decision",
|
|
756
771
|
// credential allocator durable zero-capacity wait lifecycle. These are system/runtime
|
|
757
772
|
// events, never synthetic user messages.
|
|
758
773
|
"codex.capacity.waiting",
|
|
@@ -957,6 +972,89 @@ export type AgentToolCallCreatedPayload = {
|
|
|
957
972
|
export type AgentToolCallOutputPayload = { id: string | null; output: unknown };
|
|
958
973
|
export type SessionStatusChangedPayload = { status: SessionStatus };
|
|
959
974
|
|
|
975
|
+
// Adaptive-fleet shadow event. This is the typed, identity-free view
|
|
976
|
+
// consumed by UI/manager tooling; the durable replay record also contains the
|
|
977
|
+
// complete normalized policy/input needed for offline deterministic replay.
|
|
978
|
+
export type CodexFleetConfidence = "unknown" | "low" | "medium" | "high";
|
|
979
|
+
export type CodexFleetCacheState = "unknown" | "healthy" | "collapsed";
|
|
980
|
+
export type CodexFleetShadowComparison =
|
|
981
|
+
| "match"
|
|
982
|
+
| "different_candidate"
|
|
983
|
+
| "different_outcome"
|
|
984
|
+
| "not_comparable_truncated";
|
|
985
|
+
export type CodexFleetDecisionScore = {
|
|
986
|
+
candidateKey: string;
|
|
987
|
+
eligible: boolean;
|
|
988
|
+
rejectionReason:
|
|
989
|
+
| "allocator_disabled"
|
|
990
|
+
| "unavailable"
|
|
991
|
+
| "cooling"
|
|
992
|
+
| "quota_ceiling"
|
|
993
|
+
| "overlay_isolation"
|
|
994
|
+
| null;
|
|
995
|
+
quotaPressure: number;
|
|
996
|
+
leasePressure: number;
|
|
997
|
+
observedBurnPressure: number;
|
|
998
|
+
inferredBurnPressure: number;
|
|
999
|
+
runwayPressure: number;
|
|
1000
|
+
uncertaintyPressure: number;
|
|
1001
|
+
cacheAffinityBenefit: number;
|
|
1002
|
+
cacheState: CodexFleetCacheState;
|
|
1003
|
+
overlayPreferenceBenefit: number;
|
|
1004
|
+
total: number;
|
|
1005
|
+
confidence: CodexFleetConfidence;
|
|
1006
|
+
};
|
|
1007
|
+
export type CodexFleetDecisionEventPayload = {
|
|
1008
|
+
schemaVersion: 1;
|
|
1009
|
+
mode: "shadow";
|
|
1010
|
+
actual: {
|
|
1011
|
+
outcome: "selected" | "waiting" | "none";
|
|
1012
|
+
candidateKey: string | null;
|
|
1013
|
+
reason: "lease_reused" | "pin" | "rotation" | "active" | "all_capped" | "none";
|
|
1014
|
+
};
|
|
1015
|
+
comparison: CodexFleetShadowComparison;
|
|
1016
|
+
replay: {
|
|
1017
|
+
schemaVersion: 1;
|
|
1018
|
+
policyVersion: "adaptive-shadow-v1";
|
|
1019
|
+
mode: "shadow";
|
|
1020
|
+
input: { candidates: Array<{ key: string }> } & Record<string, unknown>;
|
|
1021
|
+
truncatedCandidateCount: number;
|
|
1022
|
+
inputFingerprint: string;
|
|
1023
|
+
decisionFingerprint: string;
|
|
1024
|
+
decision: {
|
|
1025
|
+
outcome: "selected" | "paced" | "none";
|
|
1026
|
+
selectedCandidateKey: string | null;
|
|
1027
|
+
reason:
|
|
1028
|
+
| "fenced_in_flight"
|
|
1029
|
+
| "fenced_candidate_missing"
|
|
1030
|
+
| "admission_paced"
|
|
1031
|
+
| "no_eligible_candidate"
|
|
1032
|
+
| "overlay_isolated_empty"
|
|
1033
|
+
| "best_score"
|
|
1034
|
+
| "affinity_best"
|
|
1035
|
+
| "hysteresis_hold";
|
|
1036
|
+
admission: {
|
|
1037
|
+
outcome: "admit" | "pace";
|
|
1038
|
+
reason:
|
|
1039
|
+
| "fenced_in_flight"
|
|
1040
|
+
| "pacing_disabled"
|
|
1041
|
+
| "capacity_unknown"
|
|
1042
|
+
| "capacity_available"
|
|
1043
|
+
| "work_conserving_borrow"
|
|
1044
|
+
| "manager_priority"
|
|
1045
|
+
| "standard_starvation_bound"
|
|
1046
|
+
| "capacity_saturated"
|
|
1047
|
+
| "emergency_fuse";
|
|
1048
|
+
borrowedIdleCapacity: boolean;
|
|
1049
|
+
};
|
|
1050
|
+
borrowedOverlayCapacity: boolean;
|
|
1051
|
+
strandedEligibleCount: number;
|
|
1052
|
+
confidence: CodexFleetConfidence;
|
|
1053
|
+
scores: CodexFleetDecisionScore[];
|
|
1054
|
+
};
|
|
1055
|
+
} & Record<string, unknown>;
|
|
1056
|
+
};
|
|
1057
|
+
|
|
960
1058
|
// Recording payloads (P4.3 — plain TS mirror of the contracts Zod schemas; the
|
|
961
1059
|
// SDK is zero-runtime-dep so these are TYPES, not Zod, F15). The contract-parity
|
|
962
1060
|
// test asserts the event-type literals; these shapes document the wire payloads.
|
|
@@ -1046,7 +1144,7 @@ export type TerminalPtyOutputDeltaPayload = {
|
|
|
1046
1144
|
export type TerminalPtyExitedPayload = {
|
|
1047
1145
|
ptyId: string;
|
|
1048
1146
|
exitCode: number | null;
|
|
1049
|
-
reason: "exit" | "killed" | "owner_gone" | "timeout";
|
|
1147
|
+
reason: "exit" | "killed" | "owner_gone" | "timeout" | "lost";
|
|
1050
1148
|
};
|
|
1051
1149
|
|
|
1052
1150
|
// A2 FileSystem request/response.
|
|
@@ -1333,8 +1431,8 @@ export type TerminalExecRequest = {
|
|
|
1333
1431
|
export type TerminalExecResponse = {
|
|
1334
1432
|
stdout: string;
|
|
1335
1433
|
stderr: string;
|
|
1336
|
-
exitCode: number
|
|
1337
|
-
running:
|
|
1434
|
+
exitCode: number;
|
|
1435
|
+
running: false;
|
|
1338
1436
|
wallTimeSeconds: number;
|
|
1339
1437
|
};
|
|
1340
1438
|
export type PtyOpenRequest = {
|
|
@@ -1398,6 +1496,7 @@ export type ScheduledTaskAgentConfig = {
|
|
|
1398
1496
|
reasoningEffort?: ReasoningEffort | undefined;
|
|
1399
1497
|
sandboxBackend?: SandboxBackend | undefined;
|
|
1400
1498
|
goal?: GoalSpec | undefined;
|
|
1499
|
+
maxNestedAgentDepth?: number | undefined;
|
|
1401
1500
|
};
|
|
1402
1501
|
|
|
1403
1502
|
export type ScheduledTask = {
|
|
@@ -1459,6 +1558,10 @@ export type CreateSessionRequest = {
|
|
|
1459
1558
|
// double-submit/retry of the same logical create collapse to one session.
|
|
1460
1559
|
// Distinct from the per-call clientEventId.
|
|
1461
1560
|
idempotencyKey?: string | undefined;
|
|
1561
|
+
// Exact actor-private pre-session draft revision represented by this create.
|
|
1562
|
+
// The server consumes only this revision after durable initialization.
|
|
1563
|
+
expectedNewSessionDraftRevision?: number | undefined;
|
|
1564
|
+
maxNestedAgentDepth?: number | undefined;
|
|
1462
1565
|
firstPartyMcpPermissions?: string[] | undefined;
|
|
1463
1566
|
mcpServers?: SessionMcpServerInput[] | undefined;
|
|
1464
1567
|
// Shared-sandbox placement (mirror of `@opengeni/contracts` CreateSessionRequest.sandbox,
|
|
@@ -1978,12 +2081,14 @@ export type Workspace = {
|
|
|
1978
2081
|
export type WorkspaceSettings = {
|
|
1979
2082
|
memoryEnabled?: boolean | undefined;
|
|
1980
2083
|
transcription?: WorkspaceTranscriptionPolicy | undefined;
|
|
2084
|
+
maxNestedAgentDepth?: number | null | undefined;
|
|
1981
2085
|
[key: string]: unknown;
|
|
1982
2086
|
};
|
|
1983
2087
|
|
|
1984
2088
|
export type UpdateWorkspaceSettingsRequest = {
|
|
1985
2089
|
memoryEnabled?: boolean | undefined;
|
|
1986
2090
|
transcription?: WorkspaceTranscriptionPolicy | undefined;
|
|
2091
|
+
maxNestedAgentDepth?: number | null | undefined;
|
|
1987
2092
|
[key: string]: unknown;
|
|
1988
2093
|
};
|
|
1989
2094
|
|
|
@@ -2068,6 +2173,36 @@ export type SessionGoalStatus = "active" | "paused" | "completed";
|
|
|
2068
2173
|
|
|
2069
2174
|
export type SessionGoalCreatedBy = "api" | "agent" | "scheduled_task";
|
|
2070
2175
|
|
|
2176
|
+
export type SessionGoalContinuationState =
|
|
2177
|
+
| "inactive"
|
|
2178
|
+
| "scheduled"
|
|
2179
|
+
| "running"
|
|
2180
|
+
| "blocked"
|
|
2181
|
+
| "invariant_broken";
|
|
2182
|
+
|
|
2183
|
+
export type SessionGoalContinuationReason =
|
|
2184
|
+
| "goal_inactive"
|
|
2185
|
+
| "wake_pending"
|
|
2186
|
+
| "continuation_pending"
|
|
2187
|
+
| "human_work_pending"
|
|
2188
|
+
| "goal_turn_running"
|
|
2189
|
+
| "human_turn_running"
|
|
2190
|
+
| "workstream_paused"
|
|
2191
|
+
| "approval_required"
|
|
2192
|
+
| "provider_backpressure"
|
|
2193
|
+
| "session_cancelled"
|
|
2194
|
+
| "system_work_pending"
|
|
2195
|
+
| "missing_obligation";
|
|
2196
|
+
|
|
2197
|
+
export type SessionGoalContinuation = {
|
|
2198
|
+
state: SessionGoalContinuationState;
|
|
2199
|
+
reason: SessionGoalContinuationReason;
|
|
2200
|
+
wakeRevision: number;
|
|
2201
|
+
observedRevision: number;
|
|
2202
|
+
nextAttemptAt: string | null;
|
|
2203
|
+
lastError: string | null;
|
|
2204
|
+
};
|
|
2205
|
+
|
|
2071
2206
|
export type SessionGoal = {
|
|
2072
2207
|
id: string;
|
|
2073
2208
|
accountId: string;
|
|
@@ -2085,6 +2220,8 @@ export type SessionGoal = {
|
|
|
2085
2220
|
noProgressStreak: number;
|
|
2086
2221
|
maxAutoContinuations: number | null;
|
|
2087
2222
|
metadata: Record<string, unknown>;
|
|
2223
|
+
/** Optional for source compatibility; the API always supplies this projection. */
|
|
2224
|
+
continuation?: SessionGoalContinuation | undefined;
|
|
2088
2225
|
createdAt: string;
|
|
2089
2226
|
updatedAt: string;
|
|
2090
2227
|
};
|
|
@@ -2172,6 +2309,27 @@ export type ComposerDraft = {
|
|
|
2172
2309
|
updatedAt: string | null;
|
|
2173
2310
|
};
|
|
2174
2311
|
|
|
2312
|
+
export type NewSessionDraftOptions = {
|
|
2313
|
+
sandboxBackend?: SandboxBackend | undefined;
|
|
2314
|
+
targetSandboxId?: string | undefined;
|
|
2315
|
+
workingDir?: string | undefined;
|
|
2316
|
+
variableSetId?: string | undefined;
|
|
2317
|
+
rigId?: string | undefined;
|
|
2318
|
+
goal?: GoalSpec | undefined;
|
|
2319
|
+
firstPartyMcpPermissions?: Permission[] | undefined;
|
|
2320
|
+
};
|
|
2321
|
+
|
|
2322
|
+
export type NewSessionDraft = {
|
|
2323
|
+
revision: number;
|
|
2324
|
+
text: string;
|
|
2325
|
+
resources: ResourceRef[];
|
|
2326
|
+
tools: ToolRef[];
|
|
2327
|
+
model: string;
|
|
2328
|
+
reasoningEffort: ReasoningEffort;
|
|
2329
|
+
options: NewSessionDraftOptions;
|
|
2330
|
+
updatedAt: string | null;
|
|
2331
|
+
};
|
|
2332
|
+
|
|
2175
2333
|
export type SessionQueueSnapshot = {
|
|
2176
2334
|
version: number;
|
|
2177
2335
|
effectiveControl: EffectiveSessionControl;
|
|
@@ -2300,6 +2458,10 @@ export type SaveComposerDraftRequest = Omit<
|
|
|
2300
2458
|
"revision" | "sourceTurnId" | "sourceTurnVersion" | "updatedAt"
|
|
2301
2459
|
> & { expectedRevision: number };
|
|
2302
2460
|
|
|
2461
|
+
export type SaveNewSessionDraftRequest = Omit<NewSessionDraft, "revision" | "updatedAt"> & {
|
|
2462
|
+
expectedRevision: number;
|
|
2463
|
+
};
|
|
2464
|
+
|
|
2303
2465
|
// --- Scheduled tasks: requests + runs ----------------------------------------
|
|
2304
2466
|
|
|
2305
2467
|
/** Input shape for agent config on create/update (server applies defaults). */
|
|
@@ -2312,6 +2474,7 @@ export type ScheduledTaskAgentConfigInput = {
|
|
|
2312
2474
|
reasoningEffort?: ReasoningEffort | undefined;
|
|
2313
2475
|
sandboxBackend?: SandboxBackend | undefined;
|
|
2314
2476
|
goal?: GoalSpec | undefined;
|
|
2477
|
+
maxNestedAgentDepth?: number | undefined;
|
|
2315
2478
|
};
|
|
2316
2479
|
|
|
2317
2480
|
export type CreateScheduledTaskRequest = {
|
|
@@ -3379,6 +3542,9 @@ export type MachineView = {
|
|
|
3379
3542
|
state: MachineState;
|
|
3380
3543
|
active: boolean;
|
|
3381
3544
|
isSessionGroup: boolean;
|
|
3545
|
+
workspaceGeneration: number | null;
|
|
3546
|
+
archiveGeneration: number | null;
|
|
3547
|
+
archiveComplete: boolean;
|
|
3382
3548
|
os: string;
|
|
3383
3549
|
arch: string;
|
|
3384
3550
|
hasDisplay: boolean;
|
|
@@ -3428,7 +3594,10 @@ export type SwapActiveSandboxResponse = {
|
|
|
3428
3594
|
| "offline_enrollment"
|
|
3429
3595
|
| "unsupported_backend_context"
|
|
3430
3596
|
| "transient_establishment"
|
|
3431
|
-
| "concurrent_swap"
|
|
3597
|
+
| "concurrent_swap"
|
|
3598
|
+
| "recovery_in_progress"
|
|
3599
|
+
| "recovery_degraded"
|
|
3600
|
+
| "recovery_unrecoverable";
|
|
3432
3601
|
};
|
|
3433
3602
|
|
|
3434
3603
|
// ── Self-hosted enrollment UX (design 11) ────────────────────────────────────
|