@opengeni/contracts 2.7.0 → 2.9.2-canary.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/src/index.ts CHANGED
@@ -942,15 +942,8 @@ const FIRST_PARTY_IN_PROCESS_TOOL_NAME_SET = new Set<FirstPartyMcpToolName>(
942
942
  * trustworthy logical-delivery identity. Server-owned Slack delivery paths
943
943
  * call the internal client directly with their own durable operation IDs.
944
944
  */
945
- // Names kept so previously written data still parses - immutable scheduled-task
946
- // execution snapshots recorded the tool set that was default at the time, and
947
- // they are strictly re-parsed on replay. Retiring a tool must not strand an
948
- // accepted occurrence. These are never registered, never default, and never
949
- // authorized; they exist so history stays readable.
950
945
  const FIRST_PARTY_COMPATIBILITY_ONLY_TOOL_NAMES = [
951
946
  "slack_bot_post_message",
952
- "memory_save",
953
- "memory_correct",
954
947
  ] as const satisfies readonly FirstPartyMcpToolName[];
955
948
 
956
949
  const FIRST_PARTY_COMPATIBILITY_ONLY_TOOL_NAME_SET = new Set<FirstPartyMcpToolName>(
@@ -983,10 +976,6 @@ export const EDITABLE_ARTIFACT_MCP_CODEMODE_PATHS = {
983
976
  */
984
977
  export const DEFAULT_FIRST_PARTY_MCP_TOOLS = FIRST_PARTY_MCP_TOOL_NAMES.filter(
985
978
  (name) =>
986
- // Memory V1 writes are retired entirely; `remember` and task-note
987
- // promotion own durable agent writes.
988
- name !== "memory_save" &&
989
- name !== "memory_correct" &&
990
979
  !name.startsWith("social_") &&
991
980
  !name.startsWith("x_") &&
992
981
  !name.startsWith("reddit_") &&
@@ -2311,6 +2300,79 @@ export const UpdateWorkspaceModelPolicyRequest = z.object({
2311
2300
  });
2312
2301
  export type UpdateWorkspaceModelPolicyRequest = z.infer<typeof UpdateWorkspaceModelPolicyRequest>;
2313
2302
 
2303
+ export const WORKSPACE_GATEWAY_CUSTOM_MODEL_UPSTREAM_ID_MAX_LENGTH = 238;
2304
+
2305
+ export const CreateWorkspaceGatewayCustomModelRequest = z
2306
+ .object({
2307
+ operationId: z.string().uuid(),
2308
+ upstreamModelId: z
2309
+ .string()
2310
+ .max(WORKSPACE_GATEWAY_CUSTOM_MODEL_UPSTREAM_ID_MAX_LENGTH)
2311
+ .regex(/^[!-{}-~]+$/),
2312
+ label: z
2313
+ .string()
2314
+ .min(1)
2315
+ .max(128)
2316
+ .refine((value) => new TextEncoder().encode(value).byteLength <= 128, {
2317
+ message: "label must be at most 128 UTF-8 bytes",
2318
+ })
2319
+ .refine((value) => !/[\r\n|]/u.test(value), {
2320
+ message: "label must not contain newlines or the | field separator",
2321
+ })
2322
+ .optional(),
2323
+ })
2324
+ .strict();
2325
+ export type CreateWorkspaceGatewayCustomModelRequest = z.infer<
2326
+ typeof CreateWorkspaceGatewayCustomModelRequest
2327
+ >;
2328
+
2329
+ export const DeleteWorkspaceGatewayCustomModelRequest = z
2330
+ .object({
2331
+ expectedVersion: z.number().int().positive(),
2332
+ operationId: z.string().uuid(),
2333
+ })
2334
+ .strict();
2335
+ export type DeleteWorkspaceGatewayCustomModelRequest = z.infer<
2336
+ typeof DeleteWorkspaceGatewayCustomModelRequest
2337
+ >;
2338
+
2339
+ export const WorkspaceGatewayCustomModel = z.object({
2340
+ id: z.string().uuid(),
2341
+ upstreamModelId: z.string(),
2342
+ label: z.string().nullable(),
2343
+ version: z.number().int().positive(),
2344
+ createdAt: z.string().datetime(),
2345
+ updatedAt: z.string().datetime(),
2346
+ });
2347
+ export type WorkspaceGatewayCustomModel = z.infer<typeof WorkspaceGatewayCustomModel>;
2348
+
2349
+ export const WorkspaceGatewayCustomModelsResponse = z.object({
2350
+ models: z.array(WorkspaceGatewayCustomModel),
2351
+ });
2352
+ export type WorkspaceGatewayCustomModelsResponse = z.infer<
2353
+ typeof WorkspaceGatewayCustomModelsResponse
2354
+ >;
2355
+
2356
+ export const CreateWorkspaceOpenRouterCustomModelRequest = CreateWorkspaceGatewayCustomModelRequest;
2357
+ export type CreateWorkspaceOpenRouterCustomModelRequest = z.infer<
2358
+ typeof CreateWorkspaceOpenRouterCustomModelRequest
2359
+ >;
2360
+
2361
+ export const DeleteWorkspaceOpenRouterCustomModelRequest = DeleteWorkspaceGatewayCustomModelRequest;
2362
+ export type DeleteWorkspaceOpenRouterCustomModelRequest = z.infer<
2363
+ typeof DeleteWorkspaceOpenRouterCustomModelRequest
2364
+ >;
2365
+
2366
+ export const WorkspaceOpenRouterCustomModel = WorkspaceGatewayCustomModel;
2367
+ export type WorkspaceOpenRouterCustomModel = z.infer<typeof WorkspaceOpenRouterCustomModel>;
2368
+
2369
+ export const WorkspaceOpenRouterCustomModelsResponse = z.object({
2370
+ models: z.array(WorkspaceOpenRouterCustomModel),
2371
+ });
2372
+ export type WorkspaceOpenRouterCustomModelsResponse = z.infer<
2373
+ typeof WorkspaceOpenRouterCustomModelsResponse
2374
+ >;
2375
+
2314
2376
  const turnInitiatorIdentityFields = {
2315
2377
  subjectId: z.string().min(1),
2316
2378
  /** Immutable display snapshot; never an authorization input. */
@@ -2960,6 +3022,28 @@ export const CreateWorkspaceRequest = z.object({
2960
3022
  });
2961
3023
  export type CreateWorkspaceRequest = z.infer<typeof CreateWorkspaceRequest>;
2962
3024
 
3025
+ export const EnsureWorkspaceRequest = z
3026
+ .object({
3027
+ accountId: z.string().uuid(),
3028
+ externalSource: z.string().trim().min(1).max(200),
3029
+ externalId: z.string().trim().min(1).max(1024),
3030
+ name: z.string().trim().min(1).max(200),
3031
+ slug: z.string().trim().min(1).max(200).optional(),
3032
+ // White-label persona override for this workspace's agent. null/omitted uses
3033
+ // the deployment default template.
3034
+ agentInstructions: z.string().min(1).nullable().optional(),
3035
+ })
3036
+ .strict();
3037
+ export type EnsureWorkspaceRequest = z.infer<typeof EnsureWorkspaceRequest>;
3038
+
3039
+ export const EnsureWorkspaceResponse = z
3040
+ .object({
3041
+ workspace: Workspace,
3042
+ created: z.boolean(),
3043
+ })
3044
+ .strict();
3045
+ export type EnsureWorkspaceResponse = z.infer<typeof EnsureWorkspaceResponse>;
3046
+
2963
3047
  export const UpdateWorkspaceRequest = z
2964
3048
  .object({
2965
3049
  name: z.string().min(1).optional(),
@@ -3002,6 +3086,15 @@ export const CreateApiKeyResponse = z.object({
3002
3086
  });
3003
3087
  export type CreateApiKeyResponse = z.infer<typeof CreateApiKeyResponse>;
3004
3088
 
3089
+ export const CreateOrganizationApiKeyRequest = z
3090
+ .object({
3091
+ name: z.string().trim().min(1).max(200),
3092
+ description: z.string().trim().min(1).max(500).optional(),
3093
+ expiresAt: z.string().datetime({ offset: true }).optional(),
3094
+ })
3095
+ .strict();
3096
+ export type CreateOrganizationApiKeyRequest = z.infer<typeof CreateOrganizationApiKeyRequest>;
3097
+
3005
3098
  // A person (or API key) with access to a workspace: one workspace_memberships
3006
3099
  // row. `subjectId` is `user:<betterAuthUserId>` or `api_key:<id>`; the People
3007
3100
  // surface lists the `user:` subjects (api_key subjects belong to API keys).
@@ -3019,10 +3112,26 @@ export const ListWorkspaceMembersResponse = z.object({
3019
3112
  });
3020
3113
  export type ListWorkspaceMembersResponse = z.infer<typeof ListWorkspaceMembersResponse>;
3021
3114
 
3115
+ export const WorkspaceMemberCandidate = z.object({
3116
+ organizationMembershipId: z.string().uuid(),
3117
+ subjectId: z.string().min(1),
3118
+ name: z.string().min(1).max(1024).nullable(),
3119
+ email: z.string().email().max(320).nullable(),
3120
+ organizationRole: z.enum(["owner", "admin", "member"]),
3121
+ });
3122
+ export type WorkspaceMemberCandidate = z.infer<typeof WorkspaceMemberCandidate>;
3123
+
3124
+ export const ListWorkspaceMemberCandidatesResponse = z.object({
3125
+ members: z.array(WorkspaceMemberCandidate).max(1000),
3126
+ });
3127
+ export type ListWorkspaceMemberCandidatesResponse = z.infer<
3128
+ typeof ListWorkspaceMemberCandidatesResponse
3129
+ >;
3130
+
3022
3131
  export const AddWorkspaceMemberRequest = z.object({
3023
- // Resolved against the managed (Better Auth) users; email invites for
3024
- // not-yet-registered users are deferred, so an unknown email returns 404.
3025
- email: z.string().email(),
3132
+ // The candidate inventory exposes this opaque organization-local identifier.
3133
+ // Organization invitations stay in the organization-admin lifecycle.
3134
+ organizationMembershipId: z.string().uuid(),
3026
3135
  role: z.string().min(1).optional(),
3027
3136
  permissions: z.array(Permission),
3028
3137
  });
@@ -7625,17 +7734,74 @@ export function renderSessionSystemUpdateBatch(
7625
7734
  ].join("\n");
7626
7735
  }
7627
7736
 
7737
+ export const SCHEDULED_OCCURRENCE_TASK_LABEL = "[OpenGeni scheduled task occurrence]" as const;
7738
+
7739
+ /**
7740
+ * A pure scheduled-occurrence batch is a new task boundary for the model, not
7741
+ * merely background context. The user role here is conversational only: the
7742
+ * owning turn retains its immutable scheduler/service initiator and frozen
7743
+ * execution authority in the database.
7744
+ *
7745
+ * Malformed or mixed legacy batches fall back to the generic system envelope
7746
+ * so this renderer never invents task identity from inconsistent payloads.
7747
+ */
7748
+ function renderScheduledOccurrenceTaskBatch(
7749
+ updates: Parameters<typeof renderSessionSystemUpdateBatch>[0],
7750
+ ): string | null {
7751
+ if (updates.length === 0 || updates.some((update) => update.kind !== "scheduled_occurrence")) {
7752
+ return null;
7753
+ }
7754
+ const occurrences = updates.map((update) => {
7755
+ const parsed = SessionSystemUpdatePayload.safeParse(update.payload);
7756
+ if (
7757
+ !parsed.success ||
7758
+ parsed.data.type !== "scheduled_occurrence" ||
7759
+ parsed.data.scheduledTaskRunId !== update.sourceId
7760
+ ) {
7761
+ return null;
7762
+ }
7763
+ return { update, payload: parsed.data };
7764
+ });
7765
+ if (occurrences.some((occurrence) => occurrence === null)) return null;
7766
+
7767
+ const introduction =
7768
+ occurrences.length === 1
7769
+ ? "A new scheduled occurrence has started. Execute the instructions below for this occurrence now."
7770
+ : `${occurrences.length} new scheduled occurrences have started. Execute every instruction set below for this turn now.`;
7771
+ return [
7772
+ SCHEDULED_OCCURRENCE_TASK_LABEL,
7773
+ introduction,
7774
+ "The scheduled instructions below are the task for this turn. Earlier completed goals, occurrences, conversation, and tool outputs are historical context and do not complete this occurrence. When the task depends on mutable external state, query that state during this occurrence instead of reusing an earlier result.",
7775
+ ...occurrences.flatMap((occurrence, index) => {
7776
+ if (!occurrence) return [];
7777
+ return [
7778
+ "",
7779
+ ...(occurrences.length > 1 ? [`Occurrence ${index + 1}:`] : []),
7780
+ `Scheduled task ID: ${occurrence.payload.scheduledTaskId}`,
7781
+ `Scheduled task run ID: ${occurrence.payload.scheduledTaskRunId}`,
7782
+ `Update ID: ${occurrence.update.id}`,
7783
+ "Instructions:",
7784
+ occurrence.payload.text,
7785
+ ];
7786
+ }),
7787
+ ].join("\n");
7788
+ }
7789
+
7628
7790
  export function sessionSystemUpdateBatchHistoryItem(
7629
7791
  updates: Parameters<typeof renderSessionSystemUpdateBatch>[0],
7630
7792
  goalSnapshot?: SessionGoalSnapshot,
7631
- ): { type: "message"; role: "system"; content: string } {
7793
+ options: { promoteScheduledOccurrenceToUser?: boolean } = {},
7794
+ ): { type: "message"; role: "system" | "user"; content: string } {
7632
7795
  const goalContext = renderSessionGoalContext(goalSnapshot);
7796
+ const scheduledTask = options.promoteScheduledOccurrenceToUser
7797
+ ? renderScheduledOccurrenceTaskBatch(updates)
7798
+ : null;
7633
7799
  return {
7634
7800
  type: "message",
7635
- role: "system",
7801
+ role: scheduledTask ? "user" : "system",
7636
7802
  content: [
7637
7803
  ...(goalContext ? [`${SESSION_GOAL_CONTEXT_LABEL}\n${goalContext}`] : []),
7638
- renderSessionSystemUpdateBatch(updates),
7804
+ scheduledTask ?? renderSessionSystemUpdateBatch(updates),
7639
7805
  ].join("\n\n"),
7640
7806
  };
7641
7807
  }
@@ -7646,6 +7812,48 @@ export const VariableSetVariableName = z
7646
7812
  .max(128);
7647
7813
  export type VariableSetVariableName = z.infer<typeof VariableSetVariableName>;
7648
7814
 
7815
+ export const VARIABLE_SET_RESERVED_EXACT_NAMES = [
7816
+ "HOME",
7817
+ "PATH",
7818
+ "SHELL",
7819
+ "USER",
7820
+ "LOGNAME",
7821
+ "TMPDIR",
7822
+ "IFS",
7823
+ "ENV",
7824
+ "BASH_ENV",
7825
+ "NODE_OPTIONS",
7826
+ "PYTHONPATH",
7827
+ "PYTHONSTARTUP",
7828
+ "PERL5OPT",
7829
+ "PERL5LIB",
7830
+ "GH_TOKEN",
7831
+ "GITHUB_TOKEN",
7832
+ "GITLAB_TOKEN",
7833
+ "AZURE_DEVOPS_EXT_PAT",
7834
+ "GIT_ASKPASS",
7835
+ "GIT_TERMINAL_PROMPT",
7836
+ ] as const;
7837
+
7838
+ export const VARIABLE_SET_RESERVED_PREFIXES = [
7839
+ "OPENGENI_",
7840
+ "GIT_CONFIG_",
7841
+ "GIT_AUTHOR_",
7842
+ "GIT_COMMITTER_",
7843
+ "LD_",
7844
+ "DYLD_",
7845
+ ] as const;
7846
+
7847
+ export function variableSetVariableNameReservation(
7848
+ name: string,
7849
+ ): { kind: "exact" | "prefix"; value: string } | null {
7850
+ if ((VARIABLE_SET_RESERVED_EXACT_NAMES as readonly string[]).includes(name)) {
7851
+ return { kind: "exact", value: name };
7852
+ }
7853
+ const prefix = VARIABLE_SET_RESERVED_PREFIXES.find((candidate) => name.startsWith(candidate));
7854
+ return prefix ? { kind: "prefix", value: prefix } : null;
7855
+ }
7856
+
7649
7857
  function withVariableSetIdAlias<T extends z.ZodRawShape>(
7650
7858
  shape: T,
7651
7859
  options: { rejectKeys?: readonly string[] } = {},
@@ -8483,17 +8691,24 @@ function scheduledTaskBoundedString(maxBytes: number, label: string) {
8483
8691
  }
8484
8692
 
8485
8693
  /** Ingress-bounded task name for create/update requests. */
8486
- export const ScheduledTaskNameInput = /* @__PURE__ */ scheduledTaskBoundedString(
8487
- SCHEDULED_TASK_NAME_MAX_BYTES,
8488
- "scheduled task name",
8489
- );
8694
+ export const ScheduledTaskNameInput =
8695
+ /* @__PURE__ */ scheduledTaskBoundedString(SCHEDULED_TASK_NAME_MAX_BYTES, "scheduled task name");
8490
8696
  /** Ingress-bounded task metadata for create/update requests. */
8491
- export const ScheduledTaskMetadataInput = /* @__PURE__ */ scheduledTaskBoundedJsonObject(
8492
- SCHEDULED_TASK_METADATA_MAX_BYTES,
8493
- "scheduled task metadata",
8494
- );
8697
+ export const ScheduledTaskMetadataInput =
8698
+ /* @__PURE__ */ scheduledTaskBoundedJsonObject(
8699
+ SCHEDULED_TASK_METADATA_MAX_BYTES,
8700
+ "scheduled task metadata",
8701
+ );
8495
8702
 
8496
8703
  function scheduledTaskAgentConfigShape(bounded: boolean) {
8704
+ const machineTarget = z
8705
+ .object({
8706
+ targetSandboxId: z.string().uuid(),
8707
+ workingDir: bounded
8708
+ ? z.string().trim().min(1).max(4096).optional()
8709
+ : z.string().min(1).optional(),
8710
+ })
8711
+ .strict();
8497
8712
  return {
8498
8713
  prompt: bounded
8499
8714
  ? scheduledTaskBoundedString(SCHEDULED_TASK_PROMPT_MAX_BYTES, "scheduled task prompt")
@@ -8519,6 +8734,10 @@ function scheduledTaskAgentConfigShape(bounded: boolean) {
8519
8734
  : z.string().min(1).optional(),
8520
8735
  reasoningEffort: ReasoningEffort.optional(),
8521
8736
  sandboxBackend: SandboxBackend.optional(),
8737
+ // Connected Machines are a concrete execution target, not a generic
8738
+ // sandbox backend. Persist the exact machine + optional cwd so every
8739
+ // generated session can seed its active route before its first turn.
8740
+ machineTarget: machineTarget.optional(),
8522
8741
  goal: GoalSpec.optional(),
8523
8742
  // Incident telemetry is the only special execution class. Omission keeps
8524
8743
  // every existing task on the byte-compatible ordinary dispatch path.
@@ -8560,6 +8779,20 @@ export type ScheduledTaskAgentConfig = z.infer<typeof ScheduledTaskAgentConfig>;
8560
8779
  export const ScheduledTaskAgentConfigInput = /* @__PURE__ */ z
8561
8780
  .object(scheduledTaskAgentConfigShape(true))
8562
8781
  .superRefine((value, context) => {
8782
+ if (value.machineTarget && value.sandboxBackend !== undefined) {
8783
+ context.addIssue({
8784
+ code: "custom",
8785
+ path: ["machineTarget"],
8786
+ message: "machineTarget cannot be combined with sandboxBackend",
8787
+ });
8788
+ }
8789
+ if (value.sandboxBackend === "selfhosted") {
8790
+ context.addIssue({
8791
+ code: "custom",
8792
+ path: ["sandboxBackend"],
8793
+ message: "selfhosted scheduled tasks require machineTarget",
8794
+ });
8795
+ }
8563
8796
  if (scheduledTaskJsonUtf8Bytes(value) > SCHEDULED_TASK_AGENT_CONFIG_MAX_BYTES) {
8564
8797
  context.addIssue({
8565
8798
  code: "custom",
@@ -8627,6 +8860,10 @@ export const ScheduledTaskRunAcceptedExecution = /* @__PURE__ */ z
8627
8860
  resolvedModel: z.string().min(1),
8628
8861
  resolvedReasoningEffort: ReasoningEffort,
8629
8862
  resolvedLatencyMode: LatencyMode,
8863
+ /** Secret-safe TurnExecutionPolicyV1 accepted with this occurrence. Kept
8864
+ * structurally open here because the canonical policy schema is declared
8865
+ * later in this package; consumers must parse it with TurnExecutionPolicyV1. */
8866
+ turnExecutionPolicy: z.unknown().optional(),
8630
8867
  resolvedSandboxBackend: SandboxBackend,
8631
8868
  resolvedSandboxOs: SandboxOs,
8632
8869
  resolvedTools: z.array(ToolRef).max(SCHEDULED_TASK_TOOL_MAX_COUNT),
@@ -8884,6 +9121,13 @@ const CreateAgentScheduledTaskRequest = /* @__PURE__ */ withVariableSetIdAlias({
8884
9121
  message: "agentConfig.goal cannot be used with an existing-session target",
8885
9122
  });
8886
9123
  }
9124
+ if (value.runMode === "existing_session" && value.agentConfig.machineTarget) {
9125
+ context.addIssue({
9126
+ code: "custom",
9127
+ path: ["agentConfig", "machineTarget"],
9128
+ message: "machineTarget cannot be used with an existing-session target",
9129
+ });
9130
+ }
8887
9131
  });
8888
9132
 
8889
9133
  const CreateKnowledgeSourceSyncScheduledTaskRequest = /* @__PURE__ */ z
@@ -8918,48 +9162,59 @@ export const CreateScheduledTaskRequest = /* @__PURE__ */ z.union([
8918
9162
  ]);
8919
9163
  export type CreateScheduledTaskRequest = z.infer<typeof CreateScheduledTaskRequest>;
8920
9164
 
8921
- export const UpdateScheduledTaskRequest = /* @__PURE__ */ withVariableSetIdAlias({
8922
- name: ScheduledTaskNameInput.optional(),
8923
- schedule: ScheduledTaskScheduleSpec.optional(),
8924
- runMode: ScheduledTaskRunMode.optional(),
8925
- overlapPolicy: ScheduledTaskOverlapPolicy.optional(),
8926
- action: ScheduledTaskAction.optional(),
8927
- targetSessionId: z.string().uuid().nullable().optional(),
8928
- connectionAuthorities: McpConnectionAuthoritySelections.optional(),
8929
- agentConfig: ScheduledTaskAgentConfigInput.optional(),
8930
- status: ScheduledTaskStatus.optional(),
8931
- variableSetId: z.string().uuid().nullable().optional(),
8932
- environmentId: z.string().uuid().nullable().optional(),
8933
- // The rig each run binds to (M3); null clears it. Its active version is
8934
- // resolved per fire, so an update takes effect on the next dispatch.
8935
- rigId: z.string().uuid().nullable().optional(),
8936
- metadata: z.record(z.string(), z.unknown()).optional(),
8937
- }).superRefine((value, context) => {
8938
- if (value.targetSessionId && value.runMode && value.runMode !== "existing_session") {
8939
- context.addIssue({
8940
- code: "custom",
8941
- path: ["targetSessionId"],
8942
- message: "targetSessionId requires runMode=existing_session",
8943
- });
8944
- }
8945
- if (value.runMode === "existing_session" && value.targetSessionId === null) {
8946
- context.addIssue({
8947
- code: "custom",
8948
- path: ["targetSessionId"],
8949
- message: "targetSessionId cannot be null when runMode=existing_session",
8950
- });
8951
- }
8952
- if (
8953
- value.agentConfig?.goal &&
8954
- (value.runMode === "existing_session" || Boolean(value.targetSessionId))
8955
- ) {
8956
- context.addIssue({
8957
- code: "custom",
8958
- path: ["agentConfig", "goal"],
8959
- message: "agentConfig.goal cannot be used with an existing-session target",
8960
- });
8961
- }
8962
- });
9165
+ export const UpdateScheduledTaskRequest =
9166
+ /* @__PURE__ */ withVariableSetIdAlias({
9167
+ name: ScheduledTaskNameInput.optional(),
9168
+ schedule: ScheduledTaskScheduleSpec.optional(),
9169
+ runMode: ScheduledTaskRunMode.optional(),
9170
+ overlapPolicy: ScheduledTaskOverlapPolicy.optional(),
9171
+ action: ScheduledTaskAction.optional(),
9172
+ targetSessionId: z.string().uuid().nullable().optional(),
9173
+ connectionAuthorities: McpConnectionAuthoritySelections.optional(),
9174
+ agentConfig: ScheduledTaskAgentConfigInput.optional(),
9175
+ status: ScheduledTaskStatus.optional(),
9176
+ variableSetId: z.string().uuid().nullable().optional(),
9177
+ environmentId: z.string().uuid().nullable().optional(),
9178
+ // The rig each run binds to (M3); null clears it. Its active version is
9179
+ // resolved per fire, so an update takes effect on the next dispatch.
9180
+ rigId: z.string().uuid().nullable().optional(),
9181
+ metadata: z.record(z.string(), z.unknown()).optional(),
9182
+ }).superRefine((value, context) => {
9183
+ if (value.targetSessionId && value.runMode && value.runMode !== "existing_session") {
9184
+ context.addIssue({
9185
+ code: "custom",
9186
+ path: ["targetSessionId"],
9187
+ message: "targetSessionId requires runMode=existing_session",
9188
+ });
9189
+ }
9190
+ if (value.runMode === "existing_session" && value.targetSessionId === null) {
9191
+ context.addIssue({
9192
+ code: "custom",
9193
+ path: ["targetSessionId"],
9194
+ message: "targetSessionId cannot be null when runMode=existing_session",
9195
+ });
9196
+ }
9197
+ if (
9198
+ value.agentConfig?.goal &&
9199
+ (value.runMode === "existing_session" || Boolean(value.targetSessionId))
9200
+ ) {
9201
+ context.addIssue({
9202
+ code: "custom",
9203
+ path: ["agentConfig", "goal"],
9204
+ message: "agentConfig.goal cannot be used with an existing-session target",
9205
+ });
9206
+ }
9207
+ if (
9208
+ value.agentConfig?.machineTarget &&
9209
+ (value.runMode === "existing_session" || Boolean(value.targetSessionId))
9210
+ ) {
9211
+ context.addIssue({
9212
+ code: "custom",
9213
+ path: ["agentConfig", "machineTarget"],
9214
+ message: "machineTarget cannot be used with an existing-session target",
9215
+ });
9216
+ }
9217
+ });
8963
9218
  export type UpdateScheduledTaskRequest = z.infer<typeof UpdateScheduledTaskRequest>;
8964
9219
 
8965
9220
  /**
@@ -10312,6 +10567,15 @@ function compareDescending(left: number | string, right: number | string): numbe
10312
10567
  export const ConnectionCredentialBundle = z.record(z.string(), z.unknown());
10313
10568
  export type ConnectionCredentialBundle = z.infer<typeof ConnectionCredentialBundle>;
10314
10569
 
10570
+ export const VERCEL_AI_GATEWAY_CREDENTIAL_OPERATION_ID_METADATA_KEY =
10571
+ "vercelAiGatewayCredentialOperationId" as const;
10572
+ export const VERCEL_AI_GATEWAY_CREDENTIAL_OPERATION_DIGEST_METADATA_KEY =
10573
+ "vercelAiGatewayCredentialOperationDigest" as const;
10574
+ export const OPENROUTER_CREDENTIAL_OPERATION_ID_METADATA_KEY =
10575
+ "openRouterCredentialOperationId" as const;
10576
+ export const OPENROUTER_CREDENTIAL_OPERATION_DIGEST_METADATA_KEY =
10577
+ "openRouterCredentialOperationDigest" as const;
10578
+
10315
10579
  export const CreateConnectionRequest = z.object({
10316
10580
  providerDomain: z.string().min(1),
10317
10581
  kind: ConnectionKind,
@@ -10322,6 +10586,7 @@ export const CreateConnectionRequest = z.object({
10322
10586
  grantedScopes: z.array(z.string().min(1)).default([]),
10323
10587
  expiresAt: z.string().datetime({ offset: true }).nullable().optional(),
10324
10588
  metadata: z.record(z.string(), z.unknown()).default({}),
10589
+ operationId: z.string().uuid().optional(),
10325
10590
  });
10326
10591
  export type CreateConnectionRequest = z.infer<typeof CreateConnectionRequest>;
10327
10592
 
@@ -10377,6 +10642,8 @@ export const UpdateConnectionRequest = z.object({
10377
10642
  grantedScopes: z.array(z.string().min(1)).optional(),
10378
10643
  expiresAt: z.string().datetime({ offset: true }).nullable().optional(),
10379
10644
  metadata: z.record(z.string(), z.unknown()).optional(),
10645
+ expectedVersion: z.number().int().positive().optional(),
10646
+ operationId: z.string().uuid().optional(),
10380
10647
  });
10381
10648
  export type UpdateConnectionRequest = z.infer<typeof UpdateConnectionRequest>;
10382
10649
 
@@ -11664,8 +11931,11 @@ export const Session = z.object({
11664
11931
  queuedDescendants: z.number().int().nonnegative(),
11665
11932
  attentionDescendants: z.number().int().nonnegative(),
11666
11933
  pausedDescendants: z.number().int().nonnegative(),
11934
+ /** Historical failed lifecycle states, including already-reviewed failures. */
11667
11935
  failedDescendants: z.number().int().nonnegative(),
11668
11936
  unreadDescendants: z.number().int().nonnegative().optional(),
11937
+ /** Failed descendants whose latest durable event this viewer has not acknowledged. */
11938
+ unreadFailedDescendants: z.number().int().nonnegative().optional(),
11669
11939
  activelyWorkingDescendants: z.number().int().nonnegative().optional(),
11670
11940
  /**
11671
11941
  * Earliest moment one of the counted `attentionDescendants` entered
@@ -14498,6 +14768,10 @@ export const ClientAuthConfig = z.discriminatedUnion("mode", [
14498
14768
  mode: z.literal("managedSession"),
14499
14769
  session: z.literal("cookie"),
14500
14770
  emailVerificationRequired: z.boolean().default(true),
14771
+ socialProviders: z
14772
+ .array(z.enum(["google", "github"]))
14773
+ .max(2)
14774
+ .default([]),
14501
14775
  }),
14502
14776
  ]);
14503
14777
  export type ClientAuthConfig = z.infer<typeof ClientAuthConfig>;
@@ -14596,10 +14870,10 @@ export const SessionCapabilities = z.object({
14596
14870
  codecs: z.array(z.enum(["h264-mp4", "vp9-webm"])),
14597
14871
  reason: CapabilityUnavailableReason.nullable(),
14598
14872
  }),
14599
- // The AGENT drives the SAME :0 (xdotool/XTEST + scrot) the human watches; the
14600
- // human viewer plane is read-only by default (§6). `available` == desktop-
14601
- // capable backend && computerUseEnabled; `readOnly` reports whether the agent
14602
- // driver itself is gated to no-op input (v1 default false — the agent clicks).
14873
+ // Deprecated compatibility cell for clients that predate managed
14874
+ // ComputerSession interaction tools. Newly negotiated documents report this
14875
+ // unavailable/read-only with `disabled_by_policy`; the shape remains so older
14876
+ // clients and persisted payloads still parse.
14603
14877
  ComputerUse: z.object({
14604
14878
  available: z.boolean(),
14605
14879
  readOnly: z.boolean(),
@@ -15279,9 +15553,8 @@ function defineModelContractSchema<Schema>(factory: () => Schema): Schema {
15279
15553
  return factory();
15280
15554
  }
15281
15555
 
15282
- export const ModelCapabilitySupportV1 = /* @__PURE__ */ defineModelContractSchema(() =>
15283
- z.enum(["supported", "unsupported", "unknown"]),
15284
- );
15556
+ export const ModelCapabilitySupportV1 =
15557
+ /* @__PURE__ */ defineModelContractSchema(() => z.enum(["supported", "unsupported", "unknown"]));
15285
15558
  export type ModelCapabilitySupportV1 = z.infer<typeof ModelCapabilitySupportV1>;
15286
15559
 
15287
15560
  export const ModelCapabilityStateV1 = /* @__PURE__ */ defineModelContractSchema(() =>
@@ -15329,28 +15602,29 @@ export const ModelCapabilitiesV1 = /* @__PURE__ */ defineModelContractSchema(()
15329
15602
  );
15330
15603
  export type ModelCapabilitiesV1 = z.infer<typeof ModelCapabilitiesV1>;
15331
15604
 
15332
- export const ModelCredentialSourceV1 = /* @__PURE__ */ defineModelContractSchema(() =>
15333
- z.union([
15334
- z
15335
- .object({
15336
- kind: z.literal("deployment"),
15337
- mechanism: z.enum(["api_key", "azure_ad_bearer"]),
15338
- })
15339
- .strict(),
15340
- z
15341
- .object({
15342
- kind: z.literal("connected_subscription"),
15343
- provider: z.enum(["codex", "xai"]),
15344
- })
15345
- .strict(),
15346
- z
15347
- .object({
15348
- kind: z.literal("workspace_connection"),
15349
- mechanism: z.literal("api_key"),
15350
- })
15351
- .strict(),
15352
- ]),
15353
- );
15605
+ export const ModelCredentialSourceV1 =
15606
+ /* @__PURE__ */ defineModelContractSchema(() =>
15607
+ z.union([
15608
+ z
15609
+ .object({
15610
+ kind: z.literal("deployment"),
15611
+ mechanism: z.enum(["api_key", "azure_ad_bearer"]),
15612
+ })
15613
+ .strict(),
15614
+ z
15615
+ .object({
15616
+ kind: z.literal("connected_subscription"),
15617
+ provider: z.enum(["codex", "xai"]),
15618
+ })
15619
+ .strict(),
15620
+ z
15621
+ .object({
15622
+ kind: z.literal("workspace_connection"),
15623
+ mechanism: z.literal("api_key"),
15624
+ })
15625
+ .strict(),
15626
+ ]),
15627
+ );
15354
15628
  export type ModelCredentialSourceV1 = z.infer<typeof ModelCredentialSourceV1>;
15355
15629
 
15356
15630
  const TurnExecutionCredentialSourceV1 = z.union([
@@ -15363,31 +15637,40 @@ const TurnExecutionCredentialSourceV1 = z.union([
15363
15637
  .strict(),
15364
15638
  ]);
15365
15639
 
15366
- export const ModelBillingAttributionV1 = /* @__PURE__ */ defineModelContractSchema(() =>
15367
- z
15368
- .object({
15369
- upstreamPayer: z.enum(["deployment", "workspace", "connected_subscription"]),
15370
- metering: z.enum(["opengeni_credits", "external"]),
15371
- })
15372
- .strict(),
15373
- );
15640
+ export const ModelBillingAttributionV1 =
15641
+ /* @__PURE__ */ defineModelContractSchema(() =>
15642
+ z
15643
+ .object({
15644
+ upstreamPayer: z.enum(["deployment", "workspace", "connected_subscription"]),
15645
+ metering: z.enum(["opengeni_credits", "external"]),
15646
+ })
15647
+ .strict(),
15648
+ );
15374
15649
  export type ModelBillingAttributionV1 = z.infer<typeof ModelBillingAttributionV1>;
15375
15650
 
15651
+ export const ModelCostClassV1 = /* @__PURE__ */ defineModelContractSchema(() =>
15652
+ z.enum(["free", "credits", "subscription", "workspace"]),
15653
+ );
15654
+ export type ModelCostClassV1 = z.infer<typeof ModelCostClassV1>;
15655
+
15376
15656
  export const TURN_EXECUTION_POLICY_METADATA_KEY = "turnExecutionPolicyV1" as const;
15377
15657
 
15378
- export const TurnExecutionModelSourceV1 = /* @__PURE__ */ defineModelContractSchema(() =>
15379
- z.enum(["explicit", "session", "deployment", "continuation"]),
15380
- );
15658
+ export const TurnExecutionModelSourceV1 =
15659
+ /* @__PURE__ */ defineModelContractSchema(() =>
15660
+ z.enum(["explicit", "session", "deployment", "continuation"]),
15661
+ );
15381
15662
  export type TurnExecutionModelSourceV1 = z.infer<typeof TurnExecutionModelSourceV1>;
15382
15663
 
15383
- export const TurnExecutionReasoningSourceV1 = /* @__PURE__ */ defineModelContractSchema(() =>
15384
- z.enum(["explicit", "session", "deployment", "continuation"]),
15385
- );
15664
+ export const TurnExecutionReasoningSourceV1 =
15665
+ /* @__PURE__ */ defineModelContractSchema(() =>
15666
+ z.enum(["explicit", "session", "deployment", "continuation"]),
15667
+ );
15386
15668
  export type TurnExecutionReasoningSourceV1 = z.infer<typeof TurnExecutionReasoningSourceV1>;
15387
15669
 
15388
- export const TurnExecutionLatencyModeSourceV1 = /* @__PURE__ */ defineModelContractSchema(() =>
15389
- z.enum(["explicit", "session", "deployment", "continuation"]),
15390
- );
15670
+ export const TurnExecutionLatencyModeSourceV1 =
15671
+ /* @__PURE__ */ defineModelContractSchema(() =>
15672
+ z.enum(["explicit", "session", "deployment", "continuation"]),
15673
+ );
15391
15674
  export type TurnExecutionLatencyModeSourceV1 = z.infer<typeof TurnExecutionLatencyModeSourceV1>;
15392
15675
 
15393
15676
  /**
@@ -15557,7 +15840,9 @@ export const ClientModel = /* @__PURE__ */ defineModelContractSchema(() =>
15557
15840
  provider: z.string(), // provider id
15558
15841
  providerLabel: z.string(),
15559
15842
  api: z.enum(["responses", "chat"]),
15560
- source: z.enum(["opengeni", "codex", "supergrok", "workspace_gateway"]).optional(),
15843
+ source: z
15844
+ .enum(["opengeni", "codex", "supergrok", "workspace_gateway", "openrouter"])
15845
+ .optional(),
15561
15846
  contextWindowTokens: z.number().int().positive().optional(),
15562
15847
  // Additive normalized definition metadata. Optional so older server payloads
15563
15848
  // remain parseable; current servers project the complete V1 set.
@@ -15579,6 +15864,7 @@ export const ClientModel = /* @__PURE__ */ defineModelContractSchema(() =>
15579
15864
  .optional(),
15580
15865
  credentialSource: ModelCredentialSourceV1.optional(),
15581
15866
  billing: ModelBillingAttributionV1.optional(),
15867
+ cost: ModelCostClassV1.optional(),
15582
15868
  capabilities: ModelCapabilitiesV1.optional(),
15583
15869
  pricing: ModelPricingScheduleV1.optional(),
15584
15870
  definitionVersion: z
@@ -15589,59 +15875,60 @@ export const ClientModel = /* @__PURE__ */ defineModelContractSchema(() =>
15589
15875
  );
15590
15876
  export type ClientModel = z.infer<typeof ClientModel>;
15591
15877
 
15592
- export const ModelCredentialReadinessV1 = /* @__PURE__ */ defineModelContractSchema(() =>
15593
- z
15594
- .object({
15595
- status: z.enum(["ready", "not_ready", "error"]),
15596
- reason: z
15597
- .enum([
15598
- "missing_credential",
15599
- "needs_reauth",
15600
- "prerequisites_missing",
15601
- "resolver_error",
15602
- "observation_stale",
15603
- ])
15604
- .nullable(),
15605
- basis: z.enum(["configuration", "connection", "resolver"]),
15606
- checkedAt: z.string().datetime().nullable(),
15607
- })
15608
- .strict()
15609
- .superRefine((readiness, context) => {
15610
- if ((readiness.status === "ready") !== (readiness.reason === null)) {
15611
- context.addIssue({
15612
- code: "custom",
15613
- path: ["reason"],
15614
- message: "ready credential state requires no reason; non-ready state requires a reason",
15615
- });
15616
- }
15617
- if ((readiness.status === "error") !== (readiness.reason === "resolver_error")) {
15618
- context.addIssue({
15619
- code: "custom",
15620
- path: ["reason"],
15621
- message:
15622
- "credential errors require resolver_error and resolver_error requires error status",
15623
- });
15624
- }
15625
- if (
15626
- readiness.basis === "resolver" &&
15627
- readiness.status === "ready" &&
15628
- readiness.checkedAt === null
15629
- ) {
15630
- context.addIssue({
15631
- code: "custom",
15632
- path: ["checkedAt"],
15633
- message: "resolver readiness requires an observation timestamp",
15634
- });
15635
- }
15636
- if (readiness.reason === "observation_stale" && readiness.checkedAt === null) {
15637
- context.addIssue({
15638
- code: "custom",
15639
- path: ["checkedAt"],
15640
- message: "a stale observation requires its observation timestamp",
15641
- });
15642
- }
15643
- }),
15644
- );
15878
+ export const ModelCredentialReadinessV1 =
15879
+ /* @__PURE__ */ defineModelContractSchema(() =>
15880
+ z
15881
+ .object({
15882
+ status: z.enum(["ready", "not_ready", "error"]),
15883
+ reason: z
15884
+ .enum([
15885
+ "missing_credential",
15886
+ "needs_reauth",
15887
+ "prerequisites_missing",
15888
+ "resolver_error",
15889
+ "observation_stale",
15890
+ ])
15891
+ .nullable(),
15892
+ basis: z.enum(["configuration", "connection", "resolver"]),
15893
+ checkedAt: z.string().datetime().nullable(),
15894
+ })
15895
+ .strict()
15896
+ .superRefine((readiness, context) => {
15897
+ if ((readiness.status === "ready") !== (readiness.reason === null)) {
15898
+ context.addIssue({
15899
+ code: "custom",
15900
+ path: ["reason"],
15901
+ message: "ready credential state requires no reason; non-ready state requires a reason",
15902
+ });
15903
+ }
15904
+ if ((readiness.status === "error") !== (readiness.reason === "resolver_error")) {
15905
+ context.addIssue({
15906
+ code: "custom",
15907
+ path: ["reason"],
15908
+ message:
15909
+ "credential errors require resolver_error and resolver_error requires error status",
15910
+ });
15911
+ }
15912
+ if (
15913
+ readiness.basis === "resolver" &&
15914
+ readiness.status === "ready" &&
15915
+ readiness.checkedAt === null
15916
+ ) {
15917
+ context.addIssue({
15918
+ code: "custom",
15919
+ path: ["checkedAt"],
15920
+ message: "resolver readiness requires an observation timestamp",
15921
+ });
15922
+ }
15923
+ if (readiness.reason === "observation_stale" && readiness.checkedAt === null) {
15924
+ context.addIssue({
15925
+ code: "custom",
15926
+ path: ["checkedAt"],
15927
+ message: "a stale observation requires its observation timestamp",
15928
+ });
15929
+ }
15930
+ }),
15931
+ );
15645
15932
  export type ModelCredentialReadinessV1 = z.infer<typeof ModelCredentialReadinessV1>;
15646
15933
 
15647
15934
  export const ModelAvailabilityV1 = /* @__PURE__ */ defineModelContractSchema(() =>
@@ -15664,21 +15951,23 @@ export const ModelAvailabilityV1 = /* @__PURE__ */ defineModelContractSchema(()
15664
15951
  );
15665
15952
  export type ModelAvailabilityV1 = z.infer<typeof ModelAvailabilityV1>;
15666
15953
 
15667
- export const WorkspaceModelCatalogModel = /* @__PURE__ */ defineModelContractSchema(() =>
15668
- ClientModel.extend({
15669
- credentialReadiness: ModelCredentialReadinessV1,
15670
- /** Exact workspace-policy verdict without exposing provider identity. */
15671
- policyAllowed: z.boolean().optional(),
15672
- availability: ModelAvailabilityV1,
15673
- }),
15674
- );
15954
+ export const WorkspaceModelCatalogModel =
15955
+ /* @__PURE__ */ defineModelContractSchema(() =>
15956
+ ClientModel.extend({
15957
+ credentialReadiness: ModelCredentialReadinessV1,
15958
+ /** Exact workspace-policy verdict without exposing provider identity. */
15959
+ policyAllowed: z.boolean().optional(),
15960
+ availability: ModelAvailabilityV1,
15961
+ }),
15962
+ );
15675
15963
  export type WorkspaceModelCatalogModel = z.infer<typeof WorkspaceModelCatalogModel>;
15676
15964
 
15677
- export const WorkspaceModelCatalogResponse = /* @__PURE__ */ defineModelContractSchema(() =>
15678
- z.object({
15679
- models: z.array(WorkspaceModelCatalogModel),
15680
- }),
15681
- );
15965
+ export const WorkspaceModelCatalogResponse =
15966
+ /* @__PURE__ */ defineModelContractSchema(() =>
15967
+ z.object({
15968
+ models: z.array(WorkspaceModelCatalogModel),
15969
+ }),
15970
+ );
15682
15971
  export type WorkspaceModelCatalogResponse = z.infer<typeof WorkspaceModelCatalogResponse>;
15683
15972
 
15684
15973
  /**
@@ -15709,6 +15998,9 @@ export const ClientConfig = /* @__PURE__ */ defineModelContractSchema(() =>
15709
15998
  models: z.array(ClientModel).default([]),
15710
15999
  defaultReasoningEffort: ReasoningEffort,
15711
16000
  allowedReasoningEfforts: z.array(ReasoningEffort).min(1),
16001
+ // Client-safe execution default. The schedule editor uses this to avoid
16002
+ // presenting a targetless "managed" choice on self-hosted deployments.
16003
+ defaultSandboxBackend: SandboxBackend.default("modal"),
15712
16004
  mcpServers: z
15713
16005
  .array(
15714
16006
  z.object({