@opengeni/contracts 0.18.0 → 0.19.4

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/src/index.ts CHANGED
@@ -468,6 +468,8 @@ export const ErrorCode = z.enum([
468
468
  "conflict",
469
469
  "idempotency_conflict",
470
470
  "limit_exceeded",
471
+ "nested_agent_depth_exceeded",
472
+ "nested_agent_depth_override_forbidden",
471
473
  "provider_verification_failed",
472
474
  "upstream_unavailable",
473
475
  "internal_error",
@@ -476,14 +478,55 @@ export type ErrorCode = z.infer<typeof ErrorCode>;
476
478
 
477
479
  export const ErrorEnvelope = z.object({
478
480
  error: z.object({
481
+ status: z.number().int().min(400).max(599),
479
482
  code: ErrorCode,
480
483
  message: z.string(),
484
+ retryable: z.boolean(),
481
485
  requestId: z.string().optional(),
482
486
  details: z.record(z.string(), z.unknown()).optional(),
483
487
  }),
484
488
  });
485
489
  export type ErrorEnvelope = z.infer<typeof ErrorEnvelope>;
486
490
 
491
+ /** Physical ceiling of the PostgreSQL integer columns that persist depth policy. */
492
+ export const MAX_NESTED_AGENT_DEPTH = 2_147_483_647;
493
+ export const NestedAgentDepthValue = z.number().int().nonnegative().max(MAX_NESTED_AGENT_DEPTH);
494
+ export type NestedAgentDepthValue = z.infer<typeof NestedAgentDepthValue>;
495
+ /** A denied child can be one greater than the persisted PostgreSQL int ceiling. */
496
+ export const NestedAgentDepthAttemptValue = z
497
+ .number()
498
+ .int()
499
+ .nonnegative()
500
+ .max(MAX_NESTED_AGENT_DEPTH + 1);
501
+
502
+ export const NestedAgentDepthPolicySource = z.enum([
503
+ "session",
504
+ "workspace",
505
+ "deployment",
506
+ "default",
507
+ ]);
508
+ export type NestedAgentDepthPolicySource = z.infer<typeof NestedAgentDepthPolicySource>;
509
+
510
+ /** Durable evidence for a session-create denial at the database admission boundary. */
511
+ export const SessionSpawnDenial = z.object({
512
+ id: z.string().uuid(),
513
+ accountId: z.string().uuid(),
514
+ workspaceId: z.string().uuid(),
515
+ parentSessionId: z.string().uuid().nullable(),
516
+ rootSessionId: z.string().uuid().nullable(),
517
+ currentDepth: NestedAgentDepthValue,
518
+ attemptedDepth: NestedAgentDepthAttemptValue,
519
+ effectiveMaxNestedAgentDepth: NestedAgentDepthValue,
520
+ requestedMaxNestedAgentDepthOverride: NestedAgentDepthValue.nullable(),
521
+ policySource: NestedAgentDepthPolicySource,
522
+ policySessionId: z.string().uuid().nullable(),
523
+ subjectId: z.string().nullable(),
524
+ code: z.enum(["nested_agent_depth_exceeded", "nested_agent_depth_override_forbidden"]),
525
+ idempotencyKey: z.string().nullable(),
526
+ createdAt: z.string(),
527
+ });
528
+ export type SessionSpawnDenial = z.infer<typeof SessionSpawnDenial>;
529
+
487
530
  export const Permission = z.enum([
488
531
  "account:read",
489
532
  "account:admin",
@@ -934,6 +977,9 @@ export const WorkspaceSettingsSchema = z
934
977
  .object({
935
978
  memoryEnabled: z.boolean().optional(),
936
979
  transcription: WorkspaceTranscriptionPolicy.optional(),
980
+ // null clears the workspace override and falls back to the persisted
981
+ // deployment policy. The database boundary validates the same range.
982
+ maxNestedAgentDepth: NestedAgentDepthValue.nullable().optional(),
937
983
  })
938
984
  .passthrough();
939
985
  export type WorkspaceSettings = z.infer<typeof WorkspaceSettingsSchema>;
@@ -951,6 +997,7 @@ export const UpdateWorkspaceSettingsRequest = z
951
997
  .object({
952
998
  memoryEnabled: z.boolean().optional(),
953
999
  transcription: WorkspaceTranscriptionPolicy.optional(),
1000
+ maxNestedAgentDepth: NestedAgentDepthValue.nullable().optional(),
954
1001
  })
955
1002
  .passthrough();
956
1003
  export type UpdateWorkspaceSettingsRequest = z.infer<typeof UpdateWorkspaceSettingsRequest>;
@@ -2131,11 +2178,22 @@ export type ConnectionCredentialsPort = {
2131
2178
 
2132
2179
  export type GitHubInstallationSummary = {
2133
2180
  installationId: number;
2181
+ accountId: number;
2134
2182
  accountLogin: string | null;
2135
2183
  accountType: string | null;
2136
2184
  suspended: boolean;
2137
2185
  };
2138
2186
 
2187
+ export type GitHubInstallationAuthorityKind = "personal_owner" | "organization_owner";
2188
+
2189
+ export interface GitHubInstallationBindingProof {
2190
+ actorId: number;
2191
+ actorLogin: string;
2192
+ authorityKind: GitHubInstallationAuthorityKind;
2193
+ installation: GitHubInstallationSummary;
2194
+ repositories: GitHubRepository[];
2195
+ }
2196
+
2139
2197
  export type GitHubRepositoryPermissions = {
2140
2198
  admin: boolean;
2141
2199
  maintain: boolean;
@@ -2153,6 +2211,18 @@ export type GitHubUserInstallationAccess = GitHubInstallationSummary & {
2153
2211
  };
2154
2212
 
2155
2213
  export type GitHubAppApiPort = {
2214
+ /**
2215
+ * Exchange one fresh GitHub user-authorization code and prove current
2216
+ * installation authority. Implementations must accept only exact personal
2217
+ * ownership or active organization ownership; installation visibility,
2218
+ * repository permission bits, and App Manager metadata are not authority.
2219
+ * Organization ownership must be revalidated after repository discovery,
2220
+ * immediately before returning the proof used by the durable bind.
2221
+ */
2222
+ authorizeInstallationBinding?: (input: {
2223
+ code: string;
2224
+ installationId: number;
2225
+ }) => Promise<GitHubInstallationBindingProof>;
2156
2226
  authorizeUser?: (input: { code: string }) => Promise<GitHubUserInstallationAccess[]>;
2157
2227
  verifyInstallationAccessForUser?: (input: {
2158
2228
  code: string;
@@ -2446,6 +2516,37 @@ export type KnowledgeSourceKind = z.infer<typeof KnowledgeSourceKind>;
2446
2516
  export const DocumentSearchMode = z.enum(["hybrid", "vector", "keyword"]);
2447
2517
  export type DocumentSearchMode = z.infer<typeof DocumentSearchMode>;
2448
2518
 
2519
+ // 'workspace' documents are readable by anyone with workspace access;
2520
+ // 'private' documents are readable only by the grant subject that created them.
2521
+ export const DocumentVisibility = z.enum(["workspace", "private"]);
2522
+ export type DocumentVisibility = z.infer<typeof DocumentVisibility>;
2523
+
2524
+ // Knowledge-drop auto-curation lifecycle. 'none' = ordinary caller-described add
2525
+ // (never auto-curated). 'pending' = dropped, curation runs during indexing.
2526
+ // 'suggested' = curated but the base move was NOT applied (low confidence or
2527
+ // conflict) — the suggestion lives in Document.curation. 'auto_filed' = curated
2528
+ // and moved into the suggested base. 'failed' = curation errored (fail-soft;
2529
+ // the document still indexes and stays searchable).
2530
+ export const DocumentCurationStatus = z.enum([
2531
+ "none",
2532
+ "pending",
2533
+ "suggested",
2534
+ "auto_filed",
2535
+ "failed",
2536
+ ]);
2537
+ export type DocumentCurationStatus = z.infer<typeof DocumentCurationStatus>;
2538
+
2539
+ // Curator audit blob persisted on the document.
2540
+ export const DocumentCuration = z.object({
2541
+ suggestedBaseId: z.string().uuid().nullable(),
2542
+ suggestedBaseName: z.string().nullable(),
2543
+ confidence: z.number().min(0).max(1),
2544
+ reason: z.string().nullable(),
2545
+ originalTitle: z.string().nullable(),
2546
+ model: z.string().nullable(),
2547
+ });
2548
+ export type DocumentCuration = z.infer<typeof DocumentCuration>;
2549
+
2449
2550
  export const DocumentBase = z.object({
2450
2551
  id: z.string().uuid(),
2451
2552
  workspaceId: z.string().uuid(),
@@ -2475,6 +2576,13 @@ export const Document = z.object({
2475
2576
  sourceUpdatedAt: z.string().nullable(),
2476
2577
  sourceVersion: z.string().nullable(),
2477
2578
  aclTags: z.array(z.string()),
2579
+ visibility: DocumentVisibility,
2580
+ createdBy: z.string().nullable(),
2581
+ agentAccess: z.boolean(),
2582
+ summary: z.string().nullable(),
2583
+ topics: z.array(z.string()),
2584
+ curationStatus: DocumentCurationStatus,
2585
+ curation: DocumentCuration.nullable(),
2478
2586
  createdAt: z.string(),
2479
2587
  updatedAt: z.string(),
2480
2588
  });
@@ -2524,9 +2632,37 @@ export const AddDocumentRequest = z.object({
2524
2632
  sourceUpdatedAt: z.string().datetime({ offset: true }).optional(),
2525
2633
  sourceVersion: z.string().min(1).optional(),
2526
2634
  aclTags: z.array(z.string().min(1)).optional(),
2635
+ visibility: DocumentVisibility.optional(),
2636
+ agentAccess: z.boolean().optional(),
2527
2637
  });
2528
2638
  export type AddDocumentRequest = z.infer<typeof AddDocumentRequest>;
2529
2639
 
2640
+ // A knowledge drop: raw text or an already-uploaded file, with no required
2641
+ // metadata. The server files it into the workspace Default base. When a
2642
+ // curation provider is enabled, it may name, summarize, categorize, and
2643
+ // (confidence permitting) move the document; provider=none leaves caller
2644
+ // metadata and Default placement unchanged.
2645
+ export const CreateKnowledgeDropRequest = z
2646
+ .object({
2647
+ text: z.string().min(1).max(2_000_000).optional(),
2648
+ fileId: z.string().uuid().optional(),
2649
+ filename: z.string().min(1).optional(),
2650
+ title: z.string().min(1).optional(),
2651
+ visibility: DocumentVisibility.optional(),
2652
+ agentAccess: z.boolean().optional(),
2653
+ })
2654
+ .refine((value) => (value.text === undefined) !== (value.fileId === undefined), {
2655
+ message: "provide exactly one of text or fileId",
2656
+ });
2657
+ export type CreateKnowledgeDropRequest = z.infer<typeof CreateKnowledgeDropRequest>;
2658
+
2659
+ // Move a document (and its indexed chunks) to another base. With no explicit
2660
+ // targetBaseId, applies the document's stored curation suggestion.
2661
+ export const MoveDocumentRequest = z.object({
2662
+ targetBaseId: z.string().uuid().optional(),
2663
+ });
2664
+ export type MoveDocumentRequest = z.infer<typeof MoveDocumentRequest>;
2665
+
2530
2666
  export const DocumentSearchRequest = z.object({
2531
2667
  query: z.string().min(1),
2532
2668
  baseIds: z.array(z.string().uuid()).optional(),
@@ -3011,6 +3147,41 @@ export const SessionGoalPausedReason = z.enum([
3011
3147
  ]);
3012
3148
  export type SessionGoalPausedReason = z.infer<typeof SessionGoalPausedReason>;
3013
3149
 
3150
+ export const SessionGoalContinuationState = z.enum([
3151
+ "inactive",
3152
+ "scheduled",
3153
+ "running",
3154
+ "blocked",
3155
+ "invariant_broken",
3156
+ ]);
3157
+ export type SessionGoalContinuationState = z.infer<typeof SessionGoalContinuationState>;
3158
+
3159
+ export const SessionGoalContinuationReason = z.enum([
3160
+ "goal_inactive",
3161
+ "wake_pending",
3162
+ "continuation_pending",
3163
+ "human_work_pending",
3164
+ "goal_turn_running",
3165
+ "human_turn_running",
3166
+ "workstream_paused",
3167
+ "approval_required",
3168
+ "provider_backpressure",
3169
+ "session_cancelled",
3170
+ "system_work_pending",
3171
+ "missing_obligation",
3172
+ ]);
3173
+ export type SessionGoalContinuationReason = z.infer<typeof SessionGoalContinuationReason>;
3174
+
3175
+ export const SessionGoalContinuation = z.object({
3176
+ state: SessionGoalContinuationState,
3177
+ reason: SessionGoalContinuationReason,
3178
+ wakeRevision: z.number().int().nonnegative(),
3179
+ observedRevision: z.number().int().nonnegative(),
3180
+ nextAttemptAt: z.string().datetime({ offset: true }).nullable(),
3181
+ lastError: z.string().nullable(),
3182
+ });
3183
+ export type SessionGoalContinuation = z.infer<typeof SessionGoalContinuation>;
3184
+
3014
3185
  export const SessionGoal = z.object({
3015
3186
  id: z.string().uuid(),
3016
3187
  accountId: z.string().uuid(),
@@ -3028,6 +3199,9 @@ export const SessionGoal = z.object({
3028
3199
  noProgressStreak: z.number().int().nonnegative(),
3029
3200
  maxAutoContinuations: z.number().int().positive().nullable(),
3030
3201
  metadata: z.record(z.string(), z.unknown()),
3202
+ // Optional for source compatibility with older clients; the API always
3203
+ // supplies this authoritative continuation projection.
3204
+ continuation: SessionGoalContinuation.optional(),
3031
3205
  createdAt: z.string(),
3032
3206
  updatedAt: z.string(),
3033
3207
  });
@@ -3051,6 +3225,29 @@ export const UpdateSessionRequest = z.object({
3051
3225
  });
3052
3226
  export type UpdateSessionRequest = z.infer<typeof UpdateSessionRequest>;
3053
3227
 
3228
+ /**
3229
+ * Replace an existing session's durable tool policy, or explicitly opt back in
3230
+ * to the current workspace defaults. The mode-less explicit shape is retained
3231
+ * for compatibility with clients released before workspace-default adoption
3232
+ * was supported.
3233
+ */
3234
+ export const UpdateSessionToolPolicyRequest = z.union([
3235
+ z
3236
+ .object({
3237
+ mode: z.literal("workspace_default"),
3238
+ expectedVersion: z.number().int().positive(),
3239
+ })
3240
+ .strict(),
3241
+ z
3242
+ .object({
3243
+ mode: z.literal("explicit").optional(),
3244
+ tools: z.array(ToolRef).max(64),
3245
+ expectedVersion: z.number().int().positive(),
3246
+ })
3247
+ .strict(),
3248
+ ]);
3249
+ export type UpdateSessionToolPolicyRequest = z.infer<typeof UpdateSessionToolPolicyRequest>;
3250
+
3054
3251
  /**
3055
3252
  * A member's personal pin preference for a session. `expectedVersion` is
3056
3253
  * optional: ordinary pin/unpin actions are idempotent last-write-wins, while a
@@ -3192,6 +3389,7 @@ export const SessionAuthorizationOperation = z.enum([
3192
3389
  "session.human_input.write",
3193
3390
  "session.title.write",
3194
3391
  "session.mcp.approval_policy.write",
3392
+ "session.tool_policy.write",
3195
3393
  "session.goal.read",
3196
3394
  "session.goal.write",
3197
3395
  "session.child.create",
@@ -3464,6 +3662,48 @@ export const SaveComposerDraftRequest = ComposerDraft.pick({
3464
3662
  }).extend({ expectedRevision: z.number().int().nonnegative() });
3465
3663
  export type SaveComposerDraftRequest = z.infer<typeof SaveComposerDraftRequest>;
3466
3664
 
3665
+ /**
3666
+ * Create-only options saved with an actor's private pre-session draft. This is
3667
+ * deliberately narrower than CreateSessionRequest: idempotency/event keys and
3668
+ * credential-bearing MCP server inputs are per-attempt data, never draft state.
3669
+ */
3670
+ export const NewSessionDraftOptions = z.object({
3671
+ sandboxBackend: SandboxBackend.optional(),
3672
+ targetSandboxId: z.string().uuid().optional(),
3673
+ workingDir: z.string().min(1).optional(),
3674
+ variableSetId: z.string().uuid().optional(),
3675
+ rigId: z.string().uuid().optional(),
3676
+ goal: GoalSpec.optional(),
3677
+ firstPartyMcpPermissions: z.array(Permission).optional(),
3678
+ });
3679
+ export type NewSessionDraftOptions = z.infer<typeof NewSessionDraftOptions>;
3680
+
3681
+ /** Actor-private, server-authoritative composer state before a session exists. */
3682
+ export const NewSessionDraft = z.object({
3683
+ revision: z.number().int().nonnegative(),
3684
+ text: z.string(),
3685
+ resources: z.array(ResourceRef),
3686
+ tools: z.array(ToolRef),
3687
+ /** False means the workspace-default MCP policy is still inherited. */
3688
+ toolsProvided: z.boolean().default(false),
3689
+ model: z.string().min(1),
3690
+ reasoningEffort: ReasoningEffort,
3691
+ options: NewSessionDraftOptions,
3692
+ updatedAt: z.string().nullable(),
3693
+ });
3694
+ export type NewSessionDraft = z.infer<typeof NewSessionDraft>;
3695
+
3696
+ export const SaveNewSessionDraftRequest = NewSessionDraft.pick({
3697
+ text: true,
3698
+ resources: true,
3699
+ tools: true,
3700
+ toolsProvided: true,
3701
+ model: true,
3702
+ reasoningEffort: true,
3703
+ options: true,
3704
+ }).extend({ expectedRevision: z.number().int().nonnegative() });
3705
+ export type SaveNewSessionDraftRequest = z.infer<typeof SaveNewSessionDraftRequest>;
3706
+
3467
3707
  export const WORKSPACE_CONTROL_REASON_MAX_BYTES = 8 * 1024;
3468
3708
  export const WORKSPACE_CONTROL_ACTOR_MAX_BYTES = 1024;
3469
3709
  export const WORKSPACE_CONTROL_EVENT_MAX_BYTES = 16 * 1024;
@@ -4037,6 +4277,9 @@ export const ScheduledTaskAgentConfig = z.object({
4037
4277
  reasoningEffort: ReasoningEffort.optional(),
4038
4278
  sandboxBackend: SandboxBackend.optional(),
4039
4279
  goal: GoalSpec.optional(),
4280
+ // Durable task override. Scheduled dispatch is trusted to preserve this
4281
+ // snapshot even if the workspace/deployment policy narrows later.
4282
+ maxNestedAgentDepth: NestedAgentDepthValue.optional(),
4040
4283
  });
4041
4284
  export type ScheduledTaskAgentConfig = z.infer<typeof ScheduledTaskAgentConfig>;
4042
4285
 
@@ -4728,6 +4971,10 @@ export const Session = z.object({
4728
4971
  // Origin of the persisted tool allow-list. Optional for rolling client
4729
4972
  // compatibility; current servers emit it and legacy rows map to `legacy`.
4730
4973
  toolPolicy: SessionToolPolicy.optional(),
4974
+ // Optimistic-concurrency fence for durable policy mutations. Optional for
4975
+ // older clients/fixtures; current servers always emit the authoritative
4976
+ // value.
4977
+ toolPolicyVersion: z.number().int().positive().optional(),
4731
4978
  // Secret-safe current resolution, computed at an API/read or execution
4732
4979
  // boundary from IDs only. Optional because internal DB readers need not load
4733
4980
  // the workspace runtime registry.
@@ -4772,6 +5019,14 @@ export const Session = z.object({
4772
5019
  // direct API creates and scheduled-task runs. When set, this session's
4773
5020
  // terminal-for-now transitions wake the parent.
4774
5021
  parentSessionId: z.string().uuid().nullable(),
5022
+ // Server-authored nested-agent lineage/policy. Root sessions are depth 0;
5023
+ // snapshots are immutable and govern only future descendant creation.
5024
+ rootSessionId: z.string().uuid(),
5025
+ nestedAgentDepth: NestedAgentDepthValue,
5026
+ maxNestedAgentDepthOverride: NestedAgentDepthValue.nullable(),
5027
+ effectiveMaxNestedAgentDepth: NestedAgentDepthValue,
5028
+ nestedAgentDepthPolicySource: NestedAgentDepthPolicySource,
5029
+ nestedAgentDepthPolicySessionId: z.string().uuid().nullable(),
4775
5030
  // Workspace-scoped CREATE idempotency key the session was created under (the
4776
5031
  // dedup target collapsing double-submit/retry races to one session); null
4777
5032
  // when the create carried no key.
@@ -4970,6 +5225,7 @@ export const SessionEventType = z.enum([
4970
5225
  "terminal.pty.exited", // PTY session ended (exitCode/reason)
4971
5226
  "session.title_set",
4972
5227
  "session.mcp.approval_policy.updated",
5228
+ "session.tool_policy.updated",
4973
5229
  // Multi-account Codex (P1): the account a session's turn runs on changed
4974
5230
  // (manual switch in P1; failover/rotation in P3 reuse the same event). Drives
4975
5231
  // the in-session "Running on:" indicator's live flip.
@@ -4977,6 +5233,10 @@ export const SessionEventType = z.enum([
4977
5233
  // credential allocator per-turn selection audit. Payload is metadata only: credential row
4978
5234
  // id, bounded strategy/reason, and pool counts — never token material.
4979
5235
  "codex.credential.selected",
5236
+ // Adaptive fleet shadow decision record. Contains only bounded opaque candidate aliases,
5237
+ // normalized pressure/cache/confidence features, deterministic fingerprints,
5238
+ // the actual-vs-shadow comparison, and no credential/account identity.
5239
+ "codex.fleet.decision",
4980
5240
  // credential allocator durable zero-capacity wait lifecycle. Runtime/system events only;
4981
5241
  // no synthetic user message is created when capacity returns.
4982
5242
  "codex.capacity.waiting",
@@ -5131,6 +5391,7 @@ export const SESSION_EVENT_SEMANTIC_CLASS_TYPES = {
5131
5391
  "session.queue.changed",
5132
5392
  "session.queue.prompt.cancelled",
5133
5393
  "session.mcp.approval_policy.updated",
5394
+ "session.tool_policy.updated",
5134
5395
  ],
5135
5396
  terminal: [
5136
5397
  "turn.completed",
@@ -5446,7 +5707,7 @@ export type TerminalPtyOutputDeltaPayload = z.infer<typeof TerminalPtyOutputDelt
5446
5707
  export const TerminalPtyExitedPayload = z.object({
5447
5708
  ptyId: z.string().uuid(),
5448
5709
  exitCode: z.number().int().nullable(),
5449
- reason: z.enum(["exit", "killed", "owner_gone", "timeout"]),
5710
+ reason: z.enum(["exit", "killed", "owner_gone", "timeout", "lost"]),
5450
5711
  });
5451
5712
  export type TerminalPtyExitedPayload = z.infer<typeof TerminalPtyExitedPayload>;
5452
5713
 
@@ -5905,7 +6166,8 @@ export type GitShowResponse = z.infer<typeof GitShowResponse>;
5905
6166
  export const TerminalExecRequest = z.object({
5906
6167
  command: z.string().min(1),
5907
6168
  cwd: z.string().default(""), // workspace-relative
5908
- // Soft per-call wall-clock bound (the box yields output back when reached).
6169
+ // Hard wall-clock bound. A timeout response is returned only after the exact
6170
+ // provider process is physically absent and any retained admission settles.
5909
6171
  timeoutMs: z.number().int().positive().max(120_000).default(30_000),
5910
6172
  // Stream the deltas onto A1 as the agent firehose (so other viewers see it),
5911
6173
  // in addition to returning the buffered result inline.
@@ -5915,10 +6177,10 @@ export type TerminalExecRequest = z.infer<typeof TerminalExecRequest>;
5915
6177
  export const TerminalExecResponse = z.object({
5916
6178
  stdout: z.string(),
5917
6179
  stderr: z.string(),
5918
- exitCode: z.number().int().nullable(),
5919
- // True when the process was still running when the call yielded (a long
5920
- // command); the remaining output drains onto A1 if emitStream was set.
5921
- running: z.boolean(),
6180
+ exitCode: z.number().int(),
6181
+ // Retained for wire compatibility; synchronous exec never exposes a live
6182
+ // provider process. Interactive work uses the PTY API.
6183
+ running: z.literal(false),
5922
6184
  wallTimeSeconds: z.number().nonnegative(),
5923
6185
  });
5924
6186
  export type TerminalExecResponse = z.infer<typeof TerminalExecResponse>;
@@ -7015,6 +7277,14 @@ export const CreateSessionRequest = withVariableSetIdAlias({
7015
7277
  // creation of a brand-new session. Absent means no create-dedup (each call
7016
7278
  // is an independent create).
7017
7279
  idempotencyKey: z.string().min(1).max(200).optional(),
7280
+ // The exact actor-private pre-session draft revision represented by this
7281
+ // create. The durable initializer consumes only this revision. A newer draft
7282
+ // written by a sibling tab survives, while every failed pre-initialization
7283
+ // create leaves the submitted draft intact.
7284
+ expectedNewSessionDraftRevision: z.number().int().nonnegative().optional(),
7285
+ // A child may lower its inherited limit freely; an increase requires
7286
+ // workspace:admin and is checked again at the DB transaction boundary.
7287
+ maxNestedAgentDepth: NestedAgentDepthValue.optional(),
7018
7288
  // Permissions the session's first-party MCP token should carry. A top-level
7019
7289
  // omission uses the deployment's worker default; a child omission inherits
7020
7290
  // the creating session's effective grant. An explicit set is capped at
@@ -7322,10 +7592,18 @@ export type GitHubRepository = z.infer<typeof GitHubRepository>;
7322
7592
  export const GitHubRepositoryScope = z.enum(["all", "selected"]);
7323
7593
  export type GitHubRepositoryScope = z.infer<typeof GitHubRepositoryScope>;
7324
7594
 
7595
+ export const GitHubBindingStatus = z.enum(["disabled", "unbound", "bound"]);
7596
+ export type GitHubBindingStatus = z.infer<typeof GitHubBindingStatus>;
7597
+
7598
+ export const GitHubInstallationLifecycle = z.enum(["active", "suspended", "deleted", "unverified"]);
7599
+ export type GitHubInstallationLifecycle = z.infer<typeof GitHubInstallationLifecycle>;
7600
+
7325
7601
  export const GitHubInstallationBinding = z.object({
7326
7602
  installationId: z.number().int().positive(),
7603
+ githubAccountId: z.number().int().positive().nullable(),
7327
7604
  accountLogin: z.string().nullable(),
7328
7605
  accountType: z.string().nullable(),
7606
+ lifecycle: GitHubInstallationLifecycle,
7329
7607
  repositoryScope: GitHubRepositoryScope,
7330
7608
  repositoryCount: z.number().int().nonnegative(),
7331
7609
  createdAt: z.string(),
@@ -7335,6 +7613,7 @@ export type GitHubInstallationBinding = z.infer<typeof GitHubInstallationBinding
7335
7613
 
7336
7614
  export const GitHubAppInfo = z.object({
7337
7615
  configured: z.boolean(),
7616
+ status: GitHubBindingStatus,
7338
7617
  appId: z.string().nullable(),
7339
7618
  clientId: z.string().nullable(),
7340
7619
  appSlug: z.string().nullable(),
@@ -7397,6 +7676,9 @@ export const SessionCapabilities = z.object({
7397
7676
  liveness: z.enum(["cold", "warming", "warm", "draining"]),
7398
7677
  // Echoed on viewer heartbeats (the split-brain fence).
7399
7678
  leaseEpoch: z.number().int().nonnegative(),
7679
+ workspaceGeneration: z.number().int().nonnegative().nullable().default(null),
7680
+ archiveGeneration: z.number().int().nonnegative().nullable().default(null),
7681
+ archiveComplete: z.boolean().default(false),
7400
7682
  viewerHeartbeatIntervalMs: z.number().int().positive().default(30_000),
7401
7683
  FileSystem: z.object({
7402
7684
  available: z.boolean(),
@@ -7501,6 +7783,9 @@ export const ViewerHolder = z.object({
7501
7783
  liveness: z.enum(["cold", "warming", "warm", "draining"]),
7502
7784
  // The epoch the viewer is fenced on; echoed back on heartbeats.
7503
7785
  leaseEpoch: z.number().int().nonnegative(),
7786
+ workspaceGeneration: z.number().int().nonnegative().nullable(),
7787
+ archiveGeneration: z.number().int().nonnegative().nullable(),
7788
+ archiveComplete: z.boolean(),
7504
7789
  viewerHeartbeatIntervalMs: z.number().int().positive(),
7505
7790
  // The desktop pixel tunnel URL the viewer connects to directly; null until
7506
7791
  // a viewer grant is minted (gated until then).
@@ -7864,6 +8149,9 @@ export const MachineView = z.object({
7864
8149
  state: MachineState,
7865
8150
  active: z.boolean(),
7866
8151
  isSessionGroup: z.boolean(),
8152
+ workspaceGeneration: z.number().int().nonnegative().nullable(),
8153
+ archiveGeneration: z.number().int().nonnegative().nullable(),
8154
+ archiveComplete: z.boolean(),
7867
8155
  os: z.string(),
7868
8156
  arch: z.string(),
7869
8157
  hasDisplay: z.boolean(),
@@ -7923,6 +8211,9 @@ export const SwapActiveSandboxResponse = z.object({
7923
8211
  "unsupported_backend_context",
7924
8212
  "transient_establishment",
7925
8213
  "concurrent_swap",
8214
+ "recovery_in_progress",
8215
+ "recovery_degraded",
8216
+ "recovery_unrecoverable",
7926
8217
  ])
7927
8218
  .optional(),
7928
8219
  });
@@ -8315,6 +8606,8 @@ export type WorkspaceModelCatalogResponse = z.infer<typeof WorkspaceModelCatalog
8315
8606
  */
8316
8607
  export const OPENGENI_API_CONTRACT_REVISION = "2026-07-turn-instructions-v1" as const;
8317
8608
  export const OPENGENI_API_CONTRACT_HEADER = "x-opengeni-api-contract" as const;
8609
+ /** Bounded request/response identifier shared by browser, ingress, and API diagnostics. */
8610
+ export const OPENGENI_CORRELATION_HEADER = "x-opengeni-correlation-id" as const;
8318
8611
 
8319
8612
  export const ClientConfig = /* @__PURE__ */ defineModelContractSchema(() =>
8320
8613
  z.object({
@@ -8434,3 +8727,6 @@ export function evaluateWorkspaceModelPolicy(
8434
8727
  }
8435
8728
  return { allowed: true };
8436
8729
  }
8730
+
8731
+ export * from "./codex-fleet-policy";
8732
+ export * from "./secret-redaction";