@opengeni/db 0.31.1 → 0.36.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.
Files changed (122) hide show
  1. package/dist/browser-auth.d.ts +209 -1
  2. package/dist/browser-downloads.d.ts +51 -0
  3. package/dist/browser-identities.d.ts +11 -2
  4. package/dist/browser-sessions.d.ts +83 -1
  5. package/dist/browser-state-artifacts.d.ts +75 -1
  6. package/dist/canonical-human-identities.d.ts +48 -0
  7. package/dist/canonical-human-identities.js +28 -0
  8. package/dist/canonical-human-identities.js.map +1 -0
  9. package/dist/capability-integrations.d.ts +8 -6
  10. package/dist/{chunk-MWDVXQOL.js → chunk-5KTIEDX7.js} +5773 -4212
  11. package/dist/chunk-5KTIEDX7.js.map +1 -0
  12. package/dist/{chunk-NBE6CHRI.js → chunk-CQZ4QSP5.js} +49 -9
  13. package/dist/chunk-CQZ4QSP5.js.map +1 -0
  14. package/dist/chunk-F32YT7MP.js +117 -0
  15. package/dist/chunk-F32YT7MP.js.map +1 -0
  16. package/dist/{chunk-ISI2TIUG.js → chunk-JC5QPLUM.js} +30 -3
  17. package/dist/chunk-JC5QPLUM.js.map +1 -0
  18. package/dist/{chunk-F5FT7BEZ.js → chunk-P3RE4D2B.js} +2 -2
  19. package/dist/chunk-TAUTWOS5.js +259 -0
  20. package/dist/chunk-TAUTWOS5.js.map +1 -0
  21. package/dist/{chunk-YHZXQ7HP.js → chunk-VKLB2ZGI.js} +446 -19
  22. package/dist/chunk-VKLB2ZGI.js.map +1 -0
  23. package/dist/database.d.ts +5 -0
  24. package/dist/editable-artifact-durable-export.js +2 -2
  25. package/dist/editable-artifacts.js +3 -3
  26. package/dist/index.d.ts +438 -29
  27. package/dist/index.js +35640 -28969
  28. package/dist/index.js.map +1 -1
  29. package/dist/insights.d.ts +23 -7
  30. package/dist/integration-bindings.d.ts +24 -24
  31. package/dist/integration-facets.d.ts +99 -0
  32. package/dist/interaction-revisions.d.ts +11 -0
  33. package/dist/interaction-schema.d.ts +698 -34
  34. package/dist/provision-roles.js +1 -1
  35. package/dist/runtime-posture.d.ts +8 -7
  36. package/dist/schema.d.ts +9464 -5412
  37. package/dist/schema.js +51 -9
  38. package/dist/session-control.d.ts +29 -3
  39. package/dist/session-tenancy.d.ts +44 -0
  40. package/dist/session-tenancy.js +16 -0
  41. package/dist/session-tenancy.js.map +1 -0
  42. package/dist/slack-task-policy-schema.d.ts +847 -0
  43. package/dist/slack-task-policy.d.ts +65 -0
  44. package/dist/task-notes-schema.d.ts +924 -0
  45. package/dist/task-notes.d.ts +85 -0
  46. package/dist/video-generation.d.ts +9 -0
  47. package/dist/video-generation.js +5 -3
  48. package/dist/xai-subscription.d.ts +326 -0
  49. package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
  50. package/drizzle/0213_browser_interaction_authority.sql +67 -0
  51. package/drizzle/0214_browser_download_saves.sql +34 -0
  52. package/drizzle/0215_browser_controller_host.sql +385 -0
  53. package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
  54. package/drizzle/0217_external_browser_auth_operations.sql +22 -0
  55. package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
  56. package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
  57. package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
  58. package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
  59. package/drizzle/0220_session_channels.sql +54 -0
  60. package/drizzle/0221_sessions_channel_index.sql +5 -0
  61. package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
  62. package/drizzle/0222_sessions_channel_fk.sql +89 -0
  63. package/drizzle/0223_pending_tool_event_output.sql +55 -0
  64. package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
  65. package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
  66. package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
  67. package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
  68. package/drizzle/0227_slack_native_actions.sql +145 -0
  69. package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
  70. package/drizzle/0228_slack_task_policy.sql +400 -0
  71. package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
  72. package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
  73. package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
  74. package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
  75. package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
  76. package/drizzle/0234_xai_subscription_authority.sql +1139 -0
  77. package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
  78. package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
  79. package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
  80. package/drizzle/0237_interaction_transition_reaper.sql +263 -0
  81. package/drizzle/0238_goal_persistence_policy.sql +471 -0
  82. package/drizzle/0238_supergrok_realtime_model.sql +29 -0
  83. package/drizzle/0239_supergrok_video_funding.sql +50 -0
  84. package/drizzle/0239_task_tree_notes.sql +990 -0
  85. package/package.json +13 -5
  86. package/src/browser-auth.ts +2600 -123
  87. package/src/browser-downloads.ts +517 -0
  88. package/src/browser-identities.ts +220 -3
  89. package/src/browser-sessions.ts +334 -45
  90. package/src/browser-state-artifacts.ts +402 -12
  91. package/src/canonical-human-identities.ts +317 -0
  92. package/src/capability-integrations.ts +121 -213
  93. package/src/database.ts +41 -1
  94. package/src/index.ts +4157 -394
  95. package/src/insights.ts +109 -28
  96. package/src/integration-bindings.ts +101 -101
  97. package/src/{integration-features.ts → integration-facets.ts} +187 -184
  98. package/src/interaction-revisions.ts +33 -3
  99. package/src/interaction-schema.ts +311 -8
  100. package/src/pack-components.ts +43 -43
  101. package/src/pack-installations.ts +0 -43
  102. package/src/plugin-packages.ts +9 -9
  103. package/src/provision-roles.ts +232 -0
  104. package/src/runtime-posture.ts +227 -14
  105. package/src/schema.ts +1188 -75
  106. package/src/session-control.ts +122 -37
  107. package/src/session-queue-commands.ts +78 -1
  108. package/src/session-tenancy.ts +188 -0
  109. package/src/session-tool-call-settlement.ts +9 -3
  110. package/src/slack-task-policy-schema.ts +130 -0
  111. package/src/slack-task-policy.ts +341 -0
  112. package/src/task-notes-schema.ts +135 -0
  113. package/src/task-notes.ts +178 -0
  114. package/src/video-generation.ts +90 -12
  115. package/src/workspace-artifacts.ts +1 -1
  116. package/src/xai-subscription.ts +1887 -0
  117. package/dist/chunk-ISI2TIUG.js.map +0 -1
  118. package/dist/chunk-MWDVXQOL.js.map +0 -1
  119. package/dist/chunk-NBE6CHRI.js.map +0 -1
  120. package/dist/chunk-YHZXQ7HP.js.map +0 -1
  121. package/dist/integration-features.d.ts +0 -99
  122. /package/dist/{chunk-F5FT7BEZ.js.map → chunk-P3RE4D2B.js.map} +0 -0
@@ -2,7 +2,7 @@ import {
2
2
  rawRows,
3
3
  withRlsContext,
4
4
  withWorkspaceRls
5
- } from "./chunk-ISI2TIUG.js";
5
+ } from "./chunk-JC5QPLUM.js";
6
6
  import {
7
7
  connections,
8
8
  creditLedgerEntries,
@@ -14,12 +14,13 @@ import {
14
14
  workspaceVideoGenerationPolicies,
15
15
  workspaceVideoGenerationQuotas,
16
16
  workspaces
17
- } from "./chunk-MWDVXQOL.js";
17
+ } from "./chunk-5KTIEDX7.js";
18
18
 
19
19
  // src/video-generation.ts
20
20
  import {
21
21
  GENERATED_VIDEO_MAX_BYTES,
22
22
  GeneratedVideoReceipt,
23
+ GROK_IMAGINE_VIDEO_1_5_MODEL_ID,
23
24
  SEEDANCE_2_5_MODEL_ID,
24
25
  VideoGenerationPolicy,
25
26
  VideoGenerationOperationSummary,
@@ -134,7 +135,12 @@ async function admitVideoGenerationOperation(db, input) {
134
135
  if (active.length >= input.maxConcurrentPerWorkspace) {
135
136
  throw new VideoGenerationCapacityError("Workspace video generation limit reached");
136
137
  }
137
- await tx.insert(workspaceVideoGenerationQuotas).values({ workspaceId: input.workspaceId, accountId: input.accountId }).onConflictDoNothing({ target: workspaceVideoGenerationQuotas.workspaceId });
138
+ await tx.insert(workspaceVideoGenerationQuotas).values({
139
+ workspaceId: input.workspaceId,
140
+ accountId: input.accountId
141
+ }).onConflictDoNothing({
142
+ target: workspaceVideoGenerationQuotas.workspaceId
143
+ });
138
144
  const [quota] = await tx.select().from(workspaceVideoGenerationQuotas).where(eq(workspaceVideoGenerationQuotas.workspaceId, input.workspaceId)).for("update").limit(1);
139
145
  if (!quota) throw new Error("Video generation quota row disappeared");
140
146
  if (quota.reservedBytes + quota.readyBytes + reservedBytes > input.workspaceQuotaBytes) {
@@ -196,6 +202,28 @@ async function admitVideoGenerationOperation(db, input) {
196
202
  })
197
203
  );
198
204
  }
205
+ async function rotateVideoGenerationCredential(db, input) {
206
+ const [row] = await db.update(videoGenerationOperations).set({
207
+ credentialEncrypted: input.credentialEncrypted,
208
+ updatedAt: /* @__PURE__ */ new Date()
209
+ }).where(
210
+ and(
211
+ eq(videoGenerationOperations.accountId, input.accountId),
212
+ eq(videoGenerationOperations.workspaceId, input.workspaceId),
213
+ eq(videoGenerationOperations.id, input.operationId),
214
+ eq(videoGenerationOperations.requestDigest, input.requestDigest),
215
+ eq(videoGenerationOperations.credentialEncrypted, input.expectedCredentialEncrypted),
216
+ inArray(videoGenerationOperations.status, [
217
+ "accepted",
218
+ "submission_uncertain",
219
+ "provider_started",
220
+ "retaining"
221
+ ])
222
+ )
223
+ ).returning();
224
+ if (!row) throw new VideoGenerationConflictError("Video provider credential changed");
225
+ return row;
226
+ }
199
227
  async function markVideoGenerationPrepared(db, input) {
200
228
  return await mutateOperation(db, input, async (tx, operation) => {
201
229
  if (operation.status === "prepared") return operation;
@@ -244,7 +272,8 @@ async function markVideoGenerationAcceptedInTransaction(tx, input) {
244
272
  ).for("share").limit(1) : [];
245
273
  const workspaceGatewayAuthorized = operation.fundingSource === "workspace_gateway" && connection?.status === "active" && connection.version === operation.credentialVersion && connection.metadata.credentialRole === "vercel_ai_gateway";
246
274
  const managedAuthorized = operation.fundingSource === "opengeni_credits" && operation.connectionId === null && (operation.creditState === "debited" || operation.creditState === "not_applicable" && operation.pricedCostMicros === 0);
247
- if (!policy || policy.fundingSource !== operation.fundingSource || !policy.enabledModelIds.includes(operation.modelId) || !workspaceGatewayAuthorized && !managedAuthorized) {
275
+ const supergrokAuthorized = operation.fundingSource === "supergrok_subscription" && operation.connectionId === null && operation.credentialEncrypted !== null && operation.pricedCostMicros === 0 && operation.creditState === "not_applicable";
276
+ if (!policy || policy.fundingSource !== operation.fundingSource || !policy.enabledModelIds.includes(operation.modelId) || !workspaceGatewayAuthorized && !managedAuthorized && !supergrokAuthorized) {
248
277
  throw new VideoGenerationConflictError("Video generation authorization changed");
249
278
  }
250
279
  const now = /* @__PURE__ */ new Date();
@@ -573,6 +602,8 @@ async function settleVideoGenerationReady(db, input) {
573
602
  providerRequestExpiresAt: null,
574
603
  credentialEncrypted: null,
575
604
  requestEncrypted: null,
605
+ boundedPublicReason: null,
606
+ lastError: null,
576
607
  privateDataEraseAfter: now,
577
608
  reconcileLeaseOwner: null,
578
609
  reconcileLeaseExpiresAt: null,
@@ -600,7 +631,10 @@ async function listSessionGeneratedVideoArtifacts(db, workspaceId, sessionId) {
600
631
  return await withWorkspaceRls(
601
632
  db,
602
633
  workspaceId,
603
- async (scopedDb) => await scopedDb.select({ artifact: generatedVideoArtifacts, file: files }).from(generatedVideoArtifacts).innerJoin(files, eq(files.id, generatedVideoArtifacts.primaryFileId)).where(
634
+ async (scopedDb) => await scopedDb.select({
635
+ artifact: generatedVideoArtifacts,
636
+ file: files
637
+ }).from(generatedVideoArtifacts).innerJoin(files, eq(files.id, generatedVideoArtifacts.primaryFileId)).where(
604
638
  and(
605
639
  eq(generatedVideoArtifacts.workspaceId, workspaceId),
606
640
  eq(generatedVideoArtifacts.sessionId, sessionId),
@@ -626,7 +660,9 @@ async function markVideoGenerationReferenceCleaned(db, input) {
626
660
  eq(videoGenerationReferences.ordinal, input.ordinal),
627
661
  eq(videoGenerationReferences.stagingObjectKey, input.stagingObjectKey)
628
662
  )
629
- ).returning({ operationId: videoGenerationReferences.operationId });
663
+ ).returning({
664
+ operationId: videoGenerationReferences.operationId
665
+ });
630
666
  if (updated) return true;
631
667
  const [existing] = await scopedDb.select({ cleanedAt: videoGenerationReferences.cleanedAt }).from(videoGenerationReferences).where(
632
668
  and(
@@ -731,7 +767,10 @@ async function mediaGenerationResultForStoredOperation(db, operation) {
731
767
  },
732
768
  sandboxPath: `/workspace/generated-videos/${retained.artifact.sandboxFilename}`
733
769
  });
734
- return mediaGenerationResultForOperation({ operation, readyReceipt: receipt });
770
+ return mediaGenerationResultForOperation({
771
+ operation,
772
+ readyReceipt: receipt
773
+ });
735
774
  }
736
775
  async function getVideoGenerationOperationSummary(db, workspaceId, operationId) {
737
776
  const operation = await getVideoGenerationOperation(db, workspaceId, operationId);
@@ -886,7 +925,7 @@ function policyFromRow(row) {
886
925
  }
887
926
  function assertSupportedModels(modelIds) {
888
927
  for (const modelId of modelIds) {
889
- if (modelId !== SEEDANCE_2_5_MODEL_ID) {
928
+ if (modelId !== SEEDANCE_2_5_MODEL_ID && modelId !== GROK_IMAGINE_VIDEO_1_5_MODEL_ID) {
890
929
  throw new Error(`Unknown video generation model: ${modelId}`);
891
930
  }
892
931
  }
@@ -929,6 +968,7 @@ export {
929
968
  getWorkspaceVideoGenerationPolicy,
930
969
  updateWorkspaceVideoGenerationPolicy,
931
970
  admitVideoGenerationOperation,
971
+ rotateVideoGenerationCredential,
932
972
  markVideoGenerationPrepared,
933
973
  markVideoGenerationAccepted,
934
974
  markVideoGenerationAcceptedInTransaction,
@@ -952,4 +992,4 @@ export {
952
992
  mediaGenerationResultForStoredOperation,
953
993
  getVideoGenerationOperationSummary
954
994
  };
955
- //# sourceMappingURL=chunk-NBE6CHRI.js.map
995
+ //# sourceMappingURL=chunk-CQZ4QSP5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/video-generation.ts"],"sourcesContent":["import {\n GENERATED_VIDEO_MAX_BYTES,\n GeneratedVideoReceipt,\n GROK_IMAGINE_VIDEO_1_5_MODEL_ID,\n SEEDANCE_2_5_MODEL_ID,\n VideoGenerationPolicy,\n VideoGenerationOperationSummary,\n retainedGeneratedVideoReferenceFromFile,\n type GeneratedVideoFacts,\n type MediaGenerationResult,\n type VideoGenerationFundingSource,\n type VideoGenerationPolicy as VideoGenerationPolicyValue,\n} from \"@opengeni/contracts\";\nimport { and, eq, inArray, sql } from \"drizzle-orm\";\nimport type { Database } from \"./database\";\nimport { rawRows, withRlsContext, withWorkspaceRls } from \"./database\";\nimport * as schema from \"./schema\";\n\nexport const ACTIVE_VIDEO_GENERATION_STATUSES = [\n \"preparing\",\n \"prepared\",\n \"accepted\",\n \"submission_uncertain\",\n \"provider_started\",\n \"retaining\",\n] as const;\n\nexport type VideoGenerationOperation = typeof schema.videoGenerationOperations.$inferSelect;\nexport type VideoGenerationReference = typeof schema.videoGenerationReferences.$inferSelect;\nexport type GeneratedVideoArtifact = typeof schema.generatedVideoArtifacts.$inferSelect;\n\nexport type VideoGenerationOperationWithReferences = VideoGenerationOperation & {\n references: VideoGenerationReference[];\n};\n\nexport class VideoGenerationConflictError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"VideoGenerationConflictError\";\n }\n}\n\nexport class VideoGenerationCapacityError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"VideoGenerationCapacityError\";\n }\n}\n\nexport class VideoGenerationCreditError extends Error {\n constructor(message = \"insufficient OpenGeni credits\") {\n super(message);\n this.name = \"VideoGenerationCreditError\";\n }\n}\n\nexport async function getWorkspaceVideoGenerationPolicy(\n db: Database,\n workspaceId: string,\n): Promise<VideoGenerationPolicyValue> {\n return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {\n const [row] = await scopedDb\n .select()\n .from(schema.workspaceVideoGenerationPolicies)\n .where(eq(schema.workspaceVideoGenerationPolicies.workspaceId, workspaceId))\n .limit(1);\n return policyFromRow(row);\n });\n}\n\nexport async function updateWorkspaceVideoGenerationPolicy(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n subjectId: string;\n expectedRevision: number;\n fundingSource: VideoGenerationFundingSource;\n enabledModelIds: string[];\n defaultModelId: string | null;\n },\n): Promise<VideoGenerationPolicyValue> {\n const requested = VideoGenerationPolicy.parse({\n schemaVersion: 1,\n revision: input.expectedRevision + 1,\n fundingSource: input.fundingSource,\n enabledModelIds: input.enabledModelIds,\n defaultModelId: input.defaultModelId,\n });\n assertSupportedModels(requested.enabledModelIds);\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) =>\n await scopedDb.transaction(async (tx) => {\n const [workspace] = await tx\n .select({ id: schema.workspaces.id })\n .from(schema.workspaces)\n .where(\n and(\n eq(schema.workspaces.id, input.workspaceId),\n eq(schema.workspaces.accountId, input.accountId),\n ),\n )\n .for(\"update\")\n .limit(1);\n if (!workspace) throw new Error(\"Workspace not found\");\n const [current] = await tx\n .select()\n .from(schema.workspaceVideoGenerationPolicies)\n .where(eq(schema.workspaceVideoGenerationPolicies.workspaceId, input.workspaceId))\n .for(\"update\")\n .limit(1);\n const currentRevision = current?.revision ?? 0;\n if (currentRevision !== input.expectedRevision) {\n throw new VideoGenerationConflictError(\"Video generation policy changed\");\n }\n const now = new Date();\n const values = {\n workspaceId: input.workspaceId,\n accountId: input.accountId,\n revision: currentRevision + 1,\n fundingSource: requested.fundingSource,\n enabledModelIds: [...requested.enabledModelIds],\n defaultModelId: requested.defaultModelId,\n updatedBySubjectId: input.subjectId.slice(0, 1_024),\n updatedAt: now,\n };\n const [row] = current\n ? await tx\n .update(schema.workspaceVideoGenerationPolicies)\n .set(values)\n .where(eq(schema.workspaceVideoGenerationPolicies.workspaceId, input.workspaceId))\n .returning()\n : await tx.insert(schema.workspaceVideoGenerationPolicies).values(values).returning();\n if (!row) throw new Error(\"Video generation policy update was not persisted\");\n return policyFromRow(row);\n }),\n );\n}\n\nexport type AdmitVideoGenerationOperationInput = {\n id: string;\n accountId: string;\n workspaceId: string;\n sessionId: string;\n turnId: string;\n attemptId: string;\n toolCallId: string;\n admissionKey: string;\n requestDigest: string;\n promptDigest: string;\n requestEncrypted: string;\n modelId: string;\n sourceMode: string;\n capabilityRevision: string;\n policyRevision: number;\n fundingSource: VideoGenerationFundingSource;\n pricedCostMicros: number;\n connectionId: string | null;\n credentialVersion: number;\n credentialEncrypted: string;\n providerIdempotencyKey: string;\n expectedArtifactId: string;\n expectedFileId: string;\n reservedBytes?: number;\n workspaceQuotaBytes: number;\n maxConcurrentPerWorkspace: number;\n recoveryDeadlineAt: Date;\n references: Array<{\n ordinal: number;\n role: string;\n contentType: string;\n sizeBytes: number;\n sha256: string;\n stagingObjectKey: string;\n grantExpiresAt?: Date | null;\n cleanupAfter: Date;\n }>;\n};\n\nexport async function admitVideoGenerationOperation(\n db: Database,\n input: AdmitVideoGenerationOperationInput,\n): Promise<{ operation: VideoGenerationOperation; created: boolean }> {\n const reservedBytes = input.reservedBytes ?? GENERATED_VIDEO_MAX_BYTES;\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) =>\n await scopedDb.transaction(async (tx) => {\n await tx.execute(\n sql`select pg_advisory_xact_lock(hashtextextended(${`video-generation:${input.admissionKey}`}, 0))`,\n );\n const [existing] = await tx\n .select()\n .from(schema.videoGenerationOperations)\n .where(\n and(\n eq(schema.videoGenerationOperations.workspaceId, input.workspaceId),\n eq(schema.videoGenerationOperations.admissionKey, input.admissionKey),\n ),\n )\n .limit(1);\n if (existing) {\n assertAdmissionMatches(existing, input);\n return { operation: existing, created: false };\n }\n const [policy] = await tx\n .select()\n .from(schema.workspaceVideoGenerationPolicies)\n .where(eq(schema.workspaceVideoGenerationPolicies.workspaceId, input.workspaceId))\n .for(\"update\")\n .limit(1);\n if (\n !policy ||\n policy.revision !== input.policyRevision ||\n policy.fundingSource !== input.fundingSource ||\n !policy.enabledModelIds.includes(input.modelId)\n ) {\n throw new VideoGenerationConflictError(\"Video generation capability changed\");\n }\n const active = await tx\n .select({ id: schema.videoGenerationOperations.id })\n .from(schema.videoGenerationOperations)\n .where(\n and(\n eq(schema.videoGenerationOperations.workspaceId, input.workspaceId),\n inArray(schema.videoGenerationOperations.status, [\n ...ACTIVE_VIDEO_GENERATION_STATUSES,\n ]),\n ),\n )\n .for(\"update\");\n if (active.length >= input.maxConcurrentPerWorkspace) {\n throw new VideoGenerationCapacityError(\"Workspace video generation limit reached\");\n }\n await tx\n .insert(schema.workspaceVideoGenerationQuotas)\n .values({\n workspaceId: input.workspaceId,\n accountId: input.accountId,\n })\n .onConflictDoNothing({\n target: schema.workspaceVideoGenerationQuotas.workspaceId,\n });\n const [quota] = await tx\n .select()\n .from(schema.workspaceVideoGenerationQuotas)\n .where(eq(schema.workspaceVideoGenerationQuotas.workspaceId, input.workspaceId))\n .for(\"update\")\n .limit(1);\n if (!quota) throw new Error(\"Video generation quota row disappeared\");\n if (quota.reservedBytes + quota.readyBytes + reservedBytes > input.workspaceQuotaBytes) {\n throw new VideoGenerationCapacityError(\"Workspace video storage quota reached\");\n }\n const [operation] = await tx\n .insert(schema.videoGenerationOperations)\n .values({\n id: input.id,\n accountId: input.accountId,\n workspaceId: input.workspaceId,\n sessionId: input.sessionId,\n turnId: input.turnId,\n attemptId: input.attemptId,\n toolCallId: input.toolCallId,\n admissionKey: input.admissionKey,\n requestDigest: input.requestDigest,\n promptDigest: input.promptDigest,\n requestEncrypted: input.requestEncrypted,\n modelId: input.modelId,\n sourceMode: input.sourceMode,\n capabilityRevision: input.capabilityRevision,\n fundingSource: input.fundingSource,\n pricedCostMicros: input.pricedCostMicros,\n creditState: input.pricedCostMicros > 0 ? \"debited\" : \"not_applicable\",\n connectionId: input.connectionId,\n credentialVersion: input.credentialVersion,\n credentialEncrypted: input.credentialEncrypted,\n providerIdempotencyKey: input.providerIdempotencyKey,\n expectedArtifactId: input.expectedArtifactId,\n expectedFileId: input.expectedFileId,\n reservedBytes,\n recoveryDeadlineAt: input.recoveryDeadlineAt,\n status: input.references.length === 0 ? \"prepared\" : \"preparing\",\n admissionOutputState: \"pending\",\n terminalUpdateState: \"ineligible\",\n })\n .returning();\n if (!operation) throw new Error(\"Video generation operation was not admitted\");\n if (input.pricedCostMicros > 0) {\n if (input.fundingSource !== \"opengeni_credits\" || input.connectionId !== null) {\n throw new Error(\"Only OpenGeni-funded video operations may debit credits\");\n }\n await debitVideoGenerationCredits(tx, operation);\n }\n if (input.references.length > 0) {\n await tx.insert(schema.videoGenerationReferences).values(\n input.references.map((reference) => ({\n operationId: operation.id,\n workspaceId: input.workspaceId,\n accountId: input.accountId,\n grantExpiresAt: reference.grantExpiresAt ?? null,\n ...reference,\n })),\n );\n }\n await tx\n .update(schema.workspaceVideoGenerationQuotas)\n .set({\n reservedBytes: sql`${schema.workspaceVideoGenerationQuotas.reservedBytes} + ${reservedBytes}`,\n updatedAt: new Date(),\n })\n .where(eq(schema.workspaceVideoGenerationQuotas.workspaceId, input.workspaceId));\n return { operation, created: true };\n }),\n );\n}\n\n/** Persist a rotated provider token before it is used for another remote call. */\nexport async function rotateVideoGenerationCredential(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n operationId: string;\n requestDigest: string;\n expectedCredentialEncrypted: string;\n credentialEncrypted: string;\n },\n): Promise<VideoGenerationOperation> {\n const [row] = await db\n .update(schema.videoGenerationOperations)\n .set({\n credentialEncrypted: input.credentialEncrypted,\n updatedAt: new Date(),\n })\n .where(\n and(\n eq(schema.videoGenerationOperations.accountId, input.accountId),\n eq(schema.videoGenerationOperations.workspaceId, input.workspaceId),\n eq(schema.videoGenerationOperations.id, input.operationId),\n eq(schema.videoGenerationOperations.requestDigest, input.requestDigest),\n eq(schema.videoGenerationOperations.credentialEncrypted, input.expectedCredentialEncrypted),\n inArray(schema.videoGenerationOperations.status, [\n \"accepted\",\n \"submission_uncertain\",\n \"provider_started\",\n \"retaining\",\n ]),\n ),\n )\n .returning();\n if (!row) throw new VideoGenerationConflictError(\"Video provider credential changed\");\n return row;\n}\n\n/**\n * Seal a reference-bearing operation only after every immutable staging object\n * has been uploaded and independently verified by the worker. The source\n * sandbox path is intentionally not stored, so a failed preparation can only\n * be retried by the same logical tool call while its sandbox still exists.\n */\nexport async function markVideoGenerationPrepared(\n db: Database,\n input: OperationMutationInput,\n): Promise<VideoGenerationOperation> {\n return await mutateOperation(db, input, async (tx, operation) => {\n if (operation.status === \"prepared\") return operation;\n if (operation.status !== \"preparing\") throw invalidTransition(operation, \"prepared\");\n const references = await tx\n .select({\n stagingObjectKey: schema.videoGenerationReferences.stagingObjectKey,\n cleanedAt: schema.videoGenerationReferences.cleanedAt,\n })\n .from(schema.videoGenerationReferences)\n .where(eq(schema.videoGenerationReferences.operationId, operation.id));\n if (\n references.length === 0 ||\n references.some((reference) => !reference.stagingObjectKey || reference.cleanedAt)\n ) {\n throw new VideoGenerationConflictError(\"Video references are not sealed\");\n }\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({ status: \"prepared\", updatedAt: new Date() })\n .where(eq(schema.videoGenerationOperations.id, operation.id))\n .returning();\n return requireRow(updated, \"seal video generation references\");\n });\n}\n\n/** Final authorization fence. Call only after the accepted function output is durable. */\nexport async function markVideoGenerationAccepted(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n operationId: string;\n requestDigest: string;\n },\n): Promise<VideoGenerationOperation> {\n return await mutateOperation(\n db,\n input,\n async (tx, operation) =>\n await markVideoGenerationAcceptedInTransaction(tx, {\n workspaceId: input.workspaceId,\n operation,\n }),\n );\n}\n\n/**\n * Transactional half of acceptance. The pending function result and this\n * transition must commit together: the provider reconciler never observes an\n * accepted operation whose model-visible `accepted` receipt was lost.\n */\nexport async function markVideoGenerationAcceptedInTransaction(\n tx: Database,\n input: {\n workspaceId: string;\n operation: VideoGenerationOperation;\n toolCallId?: string;\n },\n): Promise<VideoGenerationOperation> {\n const operation = input.operation;\n if (input.toolCallId !== undefined && operation.toolCallId !== input.toolCallId) {\n throw new VideoGenerationConflictError(\"Video generation tool-call identity changed\");\n }\n if (operation.admissionOutputState === \"recorded\") return operation;\n if (operation.status !== \"prepared\") {\n throw new VideoGenerationConflictError(\"Video generation is no longer awaiting acceptance\");\n }\n const [policy] = await tx\n .select()\n .from(schema.workspaceVideoGenerationPolicies)\n .where(eq(schema.workspaceVideoGenerationPolicies.workspaceId, input.workspaceId))\n .for(\"share\")\n .limit(1);\n const [connection] = operation.connectionId\n ? await tx\n .select({\n id: schema.connections.id,\n version: schema.connections.version,\n status: schema.connections.status,\n metadata: schema.connections.metadata,\n })\n .from(schema.connections)\n .where(\n and(\n eq(schema.connections.workspaceId, input.workspaceId),\n eq(schema.connections.id, operation.connectionId),\n ),\n )\n .for(\"share\")\n .limit(1)\n : [];\n const workspaceGatewayAuthorized =\n operation.fundingSource === \"workspace_gateway\" &&\n connection?.status === \"active\" &&\n connection.version === operation.credentialVersion &&\n connection.metadata.credentialRole === \"vercel_ai_gateway\";\n const managedAuthorized =\n operation.fundingSource === \"opengeni_credits\" &&\n operation.connectionId === null &&\n (operation.creditState === \"debited\" ||\n (operation.creditState === \"not_applicable\" && operation.pricedCostMicros === 0));\n const supergrokAuthorized =\n operation.fundingSource === \"supergrok_subscription\" &&\n operation.connectionId === null &&\n operation.credentialEncrypted !== null &&\n operation.pricedCostMicros === 0 &&\n operation.creditState === \"not_applicable\";\n if (\n !policy ||\n policy.fundingSource !== operation.fundingSource ||\n !policy.enabledModelIds.includes(operation.modelId) ||\n (!workspaceGatewayAuthorized && !managedAuthorized && !supergrokAuthorized)\n ) {\n throw new VideoGenerationConflictError(\"Video generation authorization changed\");\n }\n const now = new Date();\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({\n status: \"accepted\",\n admissionOutputState: \"recorded\",\n terminalUpdateState: \"pending\",\n nextReconcileAt: now,\n updatedAt: now,\n })\n .where(eq(schema.videoGenerationOperations.id, operation.id))\n .returning();\n return requireRow(updated, \"record video generation acceptance\");\n}\n\nexport async function cancelVideoGenerationBeforeSubmit(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n operationId: string;\n requestDigest: string;\n reason: string;\n },\n): Promise<VideoGenerationOperation> {\n return await mutateOperation(db, input, async (tx, operation) => {\n if (operation.status === \"cancelled_before_submit\") return operation;\n if (!inPreSubmitState(operation.status) || operation.providerRequestSentAt) {\n throw new VideoGenerationConflictError(\n \"Video generation may already have reached the provider\",\n );\n }\n const now = new Date();\n await releaseReservedQuota(tx, operation, false);\n const creditState = await refundVideoGenerationCredits(tx, operation, now);\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({\n status: \"cancelled_before_submit\",\n creditState,\n quotaState: \"released\",\n terminalAt: now,\n terminalUpdateState:\n operation.admissionOutputState === \"recorded\" ? \"pending\" : \"suppressed\",\n credentialEncrypted: null,\n requestEncrypted: null,\n boundedPublicReason: boundPublicReason(input.reason),\n updatedAt: now,\n })\n .where(eq(schema.videoGenerationOperations.id, operation.id))\n .returning();\n if (!updated) throw new Error(\"Video generation cancellation was not recorded\");\n return updated;\n });\n}\n\n/**\n * Turn-interruption half of pre-submit cancellation. It runs under the same\n * session/turn transaction that closes unresolved tool calls, so an accepted\n * receipt can never race a cancellation of its operation.\n */\nexport async function cancelUnacceptedVideoGenerationsForToolCallsInTransaction(\n tx: Database,\n input: {\n workspaceId: string;\n sessionId: string;\n turnId: string;\n toolCallIds: readonly string[];\n reason: string;\n now: Date;\n },\n): Promise<string[]> {\n const toolCallIds = [...new Set(input.toolCallIds)];\n if (toolCallIds.length === 0) return [];\n const operations = await tx\n .select()\n .from(schema.videoGenerationOperations)\n .where(\n and(\n eq(schema.videoGenerationOperations.workspaceId, input.workspaceId),\n eq(schema.videoGenerationOperations.sessionId, input.sessionId),\n eq(schema.videoGenerationOperations.turnId, input.turnId),\n inArray(schema.videoGenerationOperations.toolCallId, toolCallIds),\n eq(schema.videoGenerationOperations.admissionOutputState, \"pending\"),\n inArray(schema.videoGenerationOperations.status, [\"preparing\", \"prepared\"]),\n sql`${schema.videoGenerationOperations.providerRequestSentAt} is null`,\n ),\n )\n .orderBy(schema.videoGenerationOperations.id)\n .for(\"update\");\n const cancelled: string[] = [];\n for (const operation of operations) {\n await releaseReservedQuota(tx, operation, false);\n const creditState = await refundVideoGenerationCredits(tx, operation, input.now);\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({\n status: \"cancelled_before_submit\",\n creditState,\n quotaState: \"released\",\n terminalAt: input.now,\n terminalUpdateState: \"suppressed\",\n nextReconcileAt: input.now,\n providerRequestEncrypted: null,\n providerRequestExpiresAt: null,\n credentialEncrypted: null,\n requestEncrypted: null,\n privateDataEraseAfter: input.now,\n boundedPublicReason: boundPublicReason(input.reason),\n reconcileLeaseOwner: null,\n reconcileLeaseExpiresAt: null,\n updatedAt: input.now,\n })\n .where(eq(schema.videoGenerationOperations.id, operation.id))\n .returning({ id: schema.videoGenerationOperations.id });\n if (!updated) throw new Error(\"Interrupted video generation was not cancelled\");\n await tx\n .update(schema.videoGenerationReferences)\n .set({ cleanupAfter: input.now })\n .where(eq(schema.videoGenerationReferences.operationId, operation.id));\n cancelled.push(updated.id);\n }\n return cancelled;\n}\n\nexport async function claimVideoGenerationOperations(\n db: Database,\n input: { owner: string; leaseSeconds: number; limit: number },\n): Promise<Array<{ operationId: string; accountId: string; workspaceId: string }>> {\n const rows = await rawRows<{\n operation_id: string;\n account_id: string;\n workspace_id: string;\n }>(\n db,\n sql`select * from opengeni_private.claim_video_generation_operations(\n ${input.owner}, ${input.leaseSeconds}, ${input.limit}\n )`,\n );\n return rows.map((row) => ({\n operationId: row.operation_id,\n accountId: row.account_id,\n workspaceId: row.workspace_id,\n }));\n}\n\nexport async function getVideoGenerationOperation(\n db: Database,\n workspaceId: string,\n operationId: string,\n): Promise<VideoGenerationOperationWithReferences | null> {\n return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {\n const [operation] = await scopedDb\n .select()\n .from(schema.videoGenerationOperations)\n .where(\n and(\n eq(schema.videoGenerationOperations.workspaceId, workspaceId),\n eq(schema.videoGenerationOperations.id, operationId),\n ),\n )\n .limit(1);\n if (!operation) return null;\n const references = await scopedDb\n .select()\n .from(schema.videoGenerationReferences)\n .where(eq(schema.videoGenerationReferences.operationId, operationId))\n .orderBy(schema.videoGenerationReferences.ordinal);\n return { ...operation, references };\n });\n}\n\nexport async function markVideoGenerationSubmissionUncertain(\n db: Database,\n input: OperationMutationInput & { nextReconcileAt: Date; error: string },\n): Promise<VideoGenerationOperation> {\n return await mutateOperation(db, input, async (tx, operation) => {\n if (operation.status !== \"submission_uncertain\" || !operation.providerRequestEncrypted) {\n throw invalidTransition(operation, \"submission_uncertain\");\n }\n const now = new Date();\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({\n status: \"submission_uncertain\",\n providerRequestSentAt: operation.providerRequestSentAt ?? now,\n nextReconcileAt: input.nextReconcileAt,\n lastError: boundPrivateError(input.error),\n reconcileLeaseOwner: null,\n reconcileLeaseExpiresAt: null,\n updatedAt: now,\n })\n .where(eq(schema.videoGenerationOperations.id, operation.id))\n .returning();\n return requireRow(updated, \"record uncertain video submission\");\n });\n}\n\n/**\n * Freeze the exact provider start body before issuing the request. If the\n * worker disappears after this transaction, recovery replays the same body\n * and idempotency key rather than reminting URLs or changing request bytes.\n */\nexport async function markVideoGenerationSubmissionIntent(\n db: Database,\n input: OperationMutationInput & {\n encryptedProviderRequest: string;\n providerRequestExpiresAt: Date;\n nextReconcileAt: Date;\n },\n): Promise<VideoGenerationOperation> {\n return await mutateOperation(db, input, async (tx, operation) => {\n if (operation.status === \"submission_uncertain\") {\n if (!operation.providerRequestEncrypted || !operation.providerRequestExpiresAt) {\n throw new VideoGenerationConflictError(\"Video provider request is incomplete\");\n }\n return operation;\n }\n if (operation.status !== \"accepted\") {\n throw invalidTransition(operation, \"submission_uncertain\");\n }\n const now = new Date();\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({\n status: \"submission_uncertain\",\n providerRequestEncrypted: input.encryptedProviderRequest,\n providerRequestExpiresAt: input.providerRequestExpiresAt,\n nextReconcileAt: input.nextReconcileAt,\n lastError: null,\n reconcileLeaseOwner: null,\n reconcileLeaseExpiresAt: null,\n updatedAt: now,\n })\n .where(eq(schema.videoGenerationOperations.id, operation.id))\n .returning();\n await tx\n .update(schema.videoGenerationReferences)\n .set({\n grantExpiresAt: input.providerRequestExpiresAt,\n cleanupAfter: new Date(\n Math.max(\n operation.recoveryDeadlineAt.getTime(),\n input.providerRequestExpiresAt.getTime(),\n ),\n ),\n })\n .where(eq(schema.videoGenerationReferences.operationId, operation.id));\n return requireRow(updated, \"record video provider submission intent\");\n });\n}\n\nexport async function markVideoGenerationProviderStarted(\n db: Database,\n input: OperationMutationInput & {\n providerJobId: string;\n nextReconcileAt: Date;\n },\n): Promise<VideoGenerationOperation> {\n return await mutateOperation(db, input, async (tx, operation) => {\n if (\n operation.providerJobId === input.providerJobId &&\n operation.status === \"provider_started\"\n ) {\n return operation;\n }\n if (!inArrayValue(operation.status, [\"accepted\", \"submission_uncertain\"])) {\n throw invalidTransition(operation, \"provider_started\");\n }\n const now = new Date();\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({\n status: \"provider_started\",\n providerJobId: input.providerJobId.slice(0, 1_024),\n providerRequestEncrypted: null,\n providerRequestExpiresAt: null,\n providerRequestSentAt: operation.providerRequestSentAt ?? now,\n providerStartedAt: operation.providerStartedAt ?? now,\n nextReconcileAt: input.nextReconcileAt,\n lastError: null,\n reconcileLeaseOwner: null,\n reconcileLeaseExpiresAt: null,\n updatedAt: now,\n })\n .where(eq(schema.videoGenerationOperations.id, operation.id))\n .returning();\n return requireRow(updated, \"record video provider job\");\n });\n}\n\nexport async function rescheduleVideoGenerationOperation(\n db: Database,\n input: OperationMutationInput & {\n owner?: string;\n nextReconcileAt: Date;\n error?: string;\n },\n): Promise<boolean> {\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) => {\n const [updated] = await scopedDb\n .update(schema.videoGenerationOperations)\n .set({\n nextReconcileAt: input.nextReconcileAt,\n ...(input.error ? { lastError: boundPrivateError(input.error) } : {}),\n reconcileLeaseOwner: null,\n reconcileLeaseExpiresAt: null,\n updatedAt: new Date(),\n })\n .where(\n and(\n eq(schema.videoGenerationOperations.workspaceId, input.workspaceId),\n eq(schema.videoGenerationOperations.id, input.operationId),\n eq(schema.videoGenerationOperations.requestDigest, input.requestDigest),\n ...(input.owner\n ? [eq(schema.videoGenerationOperations.reconcileLeaseOwner, input.owner)]\n : []),\n ),\n )\n .returning({ id: schema.videoGenerationOperations.id });\n return updated !== undefined;\n },\n );\n}\n\nexport async function markVideoGenerationRetaining(\n db: Database,\n input: OperationMutationInput,\n): Promise<VideoGenerationOperation> {\n return await mutateOperation(db, input, async (tx, operation) => {\n if (operation.status === \"retaining\") return operation;\n if (operation.status !== \"provider_started\") throw invalidTransition(operation, \"retaining\");\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({\n status: \"retaining\",\n nextReconcileAt: new Date(),\n reconcileLeaseOwner: null,\n reconcileLeaseExpiresAt: null,\n updatedAt: new Date(),\n })\n .where(eq(schema.videoGenerationOperations.id, operation.id))\n .returning();\n return requireRow(updated, \"begin video retention\");\n });\n}\n\nexport async function settleVideoGenerationFailure(\n db: Database,\n input: OperationMutationInput & {\n status: \"provider_failed\" | \"retention_failed\" | \"outcome_unknown\";\n publicReason: string;\n privateError?: string;\n },\n): Promise<VideoGenerationOperation> {\n return await mutateOperation(db, input, async (tx, operation) => {\n if (operation.status === input.status) return operation;\n const allowed =\n input.status === \"provider_failed\"\n ? [\"accepted\", \"submission_uncertain\", \"provider_started\"]\n : input.status === \"retention_failed\"\n ? [\"retaining\"]\n : [\"submission_uncertain\", \"provider_started\"];\n if (!inArrayValue(operation.status, allowed)) throw invalidTransition(operation, input.status);\n await releaseReservedQuota(tx, operation, false);\n const now = new Date();\n const creditState = await refundVideoGenerationCredits(tx, operation, now);\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({\n status: input.status,\n creditState,\n quotaState: \"released\",\n terminalAt: now,\n nextReconcileAt: null,\n terminalUpdateState:\n operation.admissionOutputState === \"recorded\" ? \"pending\" : \"suppressed\",\n providerRequestEncrypted: null,\n providerRequestExpiresAt: null,\n credentialEncrypted: null,\n requestEncrypted: null,\n boundedPublicReason: boundPublicReason(input.publicReason),\n lastError: input.privateError ? boundPrivateError(input.privateError) : null,\n reconcileLeaseOwner: null,\n reconcileLeaseExpiresAt: null,\n privateDataEraseAfter: now,\n updatedAt: now,\n })\n .where(eq(schema.videoGenerationOperations.id, operation.id))\n .returning();\n return requireRow(updated, \"settle failed video generation\");\n });\n}\n\nexport type SettleVideoGenerationReadyInput = OperationMutationInput & {\n fileId: string;\n bucket: string;\n objectKey: string;\n sizeBytes: number;\n sha256: string;\n facts: GeneratedVideoFacts;\n};\n\nexport async function settleVideoGenerationReady(\n db: Database,\n input: SettleVideoGenerationReadyInput,\n): Promise<{\n operation: VideoGenerationOperation;\n artifact: GeneratedVideoArtifact;\n}> {\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) =>\n await scopedDb.transaction(async (tx) => {\n const [operation] = await tx\n .select()\n .from(schema.videoGenerationOperations)\n .where(\n and(\n eq(schema.videoGenerationOperations.workspaceId, input.workspaceId),\n eq(schema.videoGenerationOperations.id, input.operationId),\n eq(schema.videoGenerationOperations.requestDigest, input.requestDigest),\n ),\n )\n .for(\"update\")\n .limit(1);\n if (!operation) throw new VideoGenerationConflictError(\"Video operation not found\");\n const [existingArtifact] = await tx\n .select()\n .from(schema.generatedVideoArtifacts)\n .where(eq(schema.generatedVideoArtifacts.operationId, operation.id))\n .limit(1);\n if (operation.status === \"completed\" && existingArtifact) {\n return { operation, artifact: existingArtifact };\n }\n if (operation.status !== \"retaining\") throw invalidTransition(operation, \"completed\");\n if (operation.expectedFileId !== input.fileId) {\n throw new VideoGenerationConflictError(\"Video File identity changed during settlement\");\n }\n if (operation.expectedArtifactId === operation.expectedFileId) {\n throw new Error(\"Video artifact and File identities must be distinct\");\n }\n const now = new Date();\n await tx.insert(schema.files).values({\n id: input.fileId,\n accountId: input.accountId,\n workspaceId: input.workspaceId,\n status: \"ready\",\n filename: `generated-video-${operation.expectedArtifactId}.mp4`,\n safeFilename: `generated-video-${operation.expectedArtifactId}.mp4`,\n contentType: \"video/mp4\",\n sizeBytes: input.sizeBytes,\n sha256: input.sha256,\n bucket: input.bucket,\n objectKey: input.objectKey,\n updatedAt: now,\n });\n const [artifact] = await tx\n .insert(schema.generatedVideoArtifacts)\n .values({\n id: operation.expectedArtifactId,\n accountId: input.accountId,\n workspaceId: input.workspaceId,\n primaryFileId: input.fileId,\n operationId: operation.id,\n sessionId: operation.sessionId,\n turnId: operation.turnId,\n attemptId: operation.attemptId,\n modelId: operation.modelId,\n sourceMode: operation.sourceMode,\n promptDigest: operation.promptDigest,\n contentType: \"video/mp4\",\n sizeBytes: input.sizeBytes,\n sha256: input.sha256,\n durationMillis: Math.round(input.facts.durationSeconds * 1_000),\n width: input.facts.width,\n height: input.facts.height,\n fpsMilli: Math.round(input.facts.fps * 1_000),\n videoCodec: input.facts.videoCodec,\n audioCodec: input.facts.audioCodec,\n hasAudio: input.facts.hasAudio,\n sandboxFilename: `generated-video-${operation.expectedArtifactId}.mp4`,\n readyAt: now,\n })\n .returning();\n if (!artifact) throw new Error(\"Generated video artifact was not persisted\");\n await tx\n .update(schema.workspaceVideoGenerationQuotas)\n .set({\n reservedBytes: sql`${schema.workspaceVideoGenerationQuotas.reservedBytes} - ${operation.reservedBytes}`,\n readyBytes: sql`${schema.workspaceVideoGenerationQuotas.readyBytes} + ${input.sizeBytes}`,\n updatedAt: now,\n })\n .where(eq(schema.workspaceVideoGenerationQuotas.workspaceId, input.workspaceId));\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({\n status: \"completed\",\n quotaState: \"ready\",\n terminalAt: now,\n nextReconcileAt: null,\n terminalUpdateState:\n operation.admissionOutputState === \"recorded\" ? \"pending\" : \"suppressed\",\n providerRequestEncrypted: null,\n providerRequestExpiresAt: null,\n credentialEncrypted: null,\n requestEncrypted: null,\n boundedPublicReason: null,\n lastError: null,\n privateDataEraseAfter: now,\n reconcileLeaseOwner: null,\n reconcileLeaseExpiresAt: null,\n updatedAt: now,\n })\n .where(eq(schema.videoGenerationOperations.id, operation.id))\n .returning();\n return {\n operation: requireRow(updated, \"settle ready video generation\"),\n artifact,\n };\n }),\n );\n}\n\nexport async function getGeneratedVideoArtifact(\n db: Database,\n workspaceId: string,\n artifactId: string,\n): Promise<{\n artifact: GeneratedVideoArtifact;\n file: typeof schema.files.$inferSelect;\n} | null> {\n return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {\n const [row] = await scopedDb\n .select({ artifact: schema.generatedVideoArtifacts, file: schema.files })\n .from(schema.generatedVideoArtifacts)\n .innerJoin(schema.files, eq(schema.files.id, schema.generatedVideoArtifacts.primaryFileId))\n .where(\n and(\n eq(schema.generatedVideoArtifacts.workspaceId, workspaceId),\n eq(schema.generatedVideoArtifacts.id, artifactId),\n ),\n )\n .limit(1);\n return row ?? null;\n });\n}\n\nexport async function listSessionGeneratedVideoArtifacts(\n db: Database,\n workspaceId: string,\n sessionId: string,\n): Promise<\n Array<{\n artifact: GeneratedVideoArtifact;\n file: typeof schema.files.$inferSelect;\n }>\n> {\n return await withWorkspaceRls(\n db,\n workspaceId,\n async (scopedDb) =>\n await scopedDb\n .select({\n artifact: schema.generatedVideoArtifacts,\n file: schema.files,\n })\n .from(schema.generatedVideoArtifacts)\n .innerJoin(schema.files, eq(schema.files.id, schema.generatedVideoArtifacts.primaryFileId))\n .where(\n and(\n eq(schema.generatedVideoArtifacts.workspaceId, workspaceId),\n eq(schema.generatedVideoArtifacts.sessionId, sessionId),\n sql`${schema.generatedVideoArtifacts.deletedAt} is null`,\n ),\n )\n .orderBy(schema.generatedVideoArtifacts.createdAt, schema.generatedVideoArtifacts.id),\n );\n}\n\n/**\n * Record one staging object as erased only after the object-store delete has\n * succeeded. Deleting first is safe because object deletion is idempotent; a\n * crash before this CAS simply repeats the same delete on recovery.\n */\nexport async function markVideoGenerationReferenceCleaned(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n operationId: string;\n ordinal: number;\n stagingObjectKey: string;\n },\n): Promise<boolean> {\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) => {\n const [updated] = await scopedDb\n .update(schema.videoGenerationReferences)\n .set({\n stagingObjectKey: null,\n grantExpiresAt: null,\n cleanupAfter: null,\n cleanedAt: new Date(),\n })\n .where(\n and(\n eq(schema.videoGenerationReferences.workspaceId, input.workspaceId),\n eq(schema.videoGenerationReferences.operationId, input.operationId),\n eq(schema.videoGenerationReferences.ordinal, input.ordinal),\n eq(schema.videoGenerationReferences.stagingObjectKey, input.stagingObjectKey),\n ),\n )\n .returning({\n operationId: schema.videoGenerationReferences.operationId,\n });\n if (updated) return true;\n const [existing] = await scopedDb\n .select({ cleanedAt: schema.videoGenerationReferences.cleanedAt })\n .from(schema.videoGenerationReferences)\n .where(\n and(\n eq(schema.videoGenerationReferences.workspaceId, input.workspaceId),\n eq(schema.videoGenerationReferences.operationId, input.operationId),\n eq(schema.videoGenerationReferences.ordinal, input.ordinal),\n ),\n )\n .limit(1);\n return existing?.cleanedAt !== null && existing?.cleanedAt !== undefined;\n },\n );\n}\n\nexport async function markVideoGenerationTerminalUpdate(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n operationId: string;\n state: \"leased\" | \"delivered\" | \"suppressed\";\n updateId?: string;\n },\n): Promise<boolean> {\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) => {\n return await markVideoGenerationTerminalUpdateInTransaction(scopedDb, input);\n },\n );\n}\n\nexport async function markVideoGenerationTerminalUpdateInTransaction(\n tx: Database,\n input: {\n workspaceId: string;\n operationId: string;\n state: \"leased\" | \"delivered\" | \"suppressed\";\n updateId?: string;\n },\n): Promise<boolean> {\n const allowed =\n input.state === \"leased\"\n ? [\"pending\", \"leased\"]\n : input.state === \"delivered\"\n ? [\"leased\"]\n : [\"pending\", \"leased\"];\n const [updated] = await tx\n .update(schema.videoGenerationOperations)\n .set({\n terminalUpdateState: input.state,\n terminalUpdateId: input.state === \"suppressed\" ? null : (input.updateId ?? null),\n updatedAt: new Date(),\n })\n .where(\n and(\n eq(schema.videoGenerationOperations.workspaceId, input.workspaceId),\n eq(schema.videoGenerationOperations.id, input.operationId),\n inArray(schema.videoGenerationOperations.terminalUpdateState, allowed),\n ...(input.state === \"delivered\" && input.updateId\n ? [eq(schema.videoGenerationOperations.terminalUpdateId, input.updateId)]\n : []),\n ),\n )\n .returning({ id: schema.videoGenerationOperations.id });\n return updated !== undefined;\n}\n\nexport function mediaGenerationResultForOperation(input: {\n operation: VideoGenerationOperation;\n readyReceipt?: Extract<MediaGenerationResult, { status: \"ready\" }>[\"receipt\"];\n}): MediaGenerationResult {\n if (input.operation.status === \"completed\" && input.readyReceipt) {\n return {\n type: \"media_generation_result\",\n schemaVersion: 1,\n status: \"ready\",\n operationId: input.operation.id,\n receipt: input.readyReceipt,\n };\n }\n const failureStatus = input.operation.status;\n if (\n !inArrayValue(failureStatus, [\n \"provider_failed\",\n \"retention_failed\",\n \"cancelled_before_submit\",\n \"outcome_unknown\",\n ])\n ) {\n throw new Error(\"Video generation operation is not terminal\");\n }\n return {\n type: \"media_generation_result\",\n schemaVersion: 1,\n status: failureStatus,\n operationId: input.operation.id,\n boundedPublicReason:\n input.operation.boundedPublicReason ?? \"Video generation did not complete.\",\n } as MediaGenerationResult;\n}\n\n/** Build the compact public/model terminal envelope from durable canonical rows. */\nexport async function mediaGenerationResultForStoredOperation(\n db: Database,\n operation: VideoGenerationOperation,\n): Promise<MediaGenerationResult> {\n if (operation.status !== \"completed\") {\n return mediaGenerationResultForOperation({ operation });\n }\n const retained = await getGeneratedVideoArtifact(\n db,\n operation.workspaceId,\n operation.expectedArtifactId,\n );\n if (!retained || retained.artifact.deletedAt) {\n throw new Error(\"Completed video generation lost its retained artifact\");\n }\n const artifact = retainedGeneratedVideoReferenceFromFile({\n id: retained.artifact.id,\n workspaceId: retained.artifact.workspaceId,\n status: retained.file.status,\n contentType: retained.file.contentType,\n sizeBytes: retained.file.sizeBytes,\n sha256: retained.file.sha256,\n updatedAt: retained.artifact.readyAt.toISOString(),\n width: retained.artifact.width,\n height: retained.artifact.height,\n });\n if (!artifact) throw new Error(\"Generated video receipt could not be constructed\");\n const receipt = GeneratedVideoReceipt.parse({\n type: \"generated_video\",\n schemaVersion: 1,\n operationId: operation.id,\n artifact,\n video: {\n durationSeconds: retained.artifact.durationMillis / 1_000,\n width: retained.artifact.width,\n height: retained.artifact.height,\n fps: retained.artifact.fpsMilli / 1_000,\n hasAudio: retained.artifact.hasAudio,\n videoCodec: retained.artifact.videoCodec,\n audioCodec: retained.artifact.audioCodec,\n },\n sandboxPath: `/workspace/generated-videos/${retained.artifact.sandboxFilename}`,\n });\n return mediaGenerationResultForOperation({\n operation,\n readyReceipt: receipt,\n });\n}\n\nexport async function getVideoGenerationOperationSummary(\n db: Database,\n workspaceId: string,\n operationId: string,\n): Promise<import(\"@opengeni/contracts\").VideoGenerationOperationSummary | null> {\n const operation = await getVideoGenerationOperation(db, workspaceId, operationId);\n if (!operation) return null;\n const terminal = inArrayValue(operation.status, [\n \"completed\",\n \"provider_failed\",\n \"cancelled_before_submit\",\n \"outcome_unknown\",\n \"retention_failed\",\n ])\n ? await mediaGenerationResultForStoredOperation(db, operation)\n : null;\n return VideoGenerationOperationSummary.parse({\n schemaVersion: 1,\n operationId: operation.id,\n modelId: operation.modelId,\n status: operation.status === \"submission_uncertain\" ? \"accepted\" : operation.status,\n createdAt: operation.createdAt.toISOString(),\n updatedAt: operation.updatedAt.toISOString(),\n terminal,\n });\n}\n\ntype OperationMutationInput = {\n accountId: string;\n workspaceId: string;\n operationId: string;\n requestDigest: string;\n};\n\nasync function mutateOperation<T>(\n db: Database,\n input: OperationMutationInput,\n mutate: (tx: Database, operation: VideoGenerationOperation) => Promise<T>,\n): Promise<T> {\n return await withRlsContext(\n db,\n { accountId: input.accountId, workspaceId: input.workspaceId },\n async (scopedDb) =>\n await scopedDb.transaction(async (txRaw) => {\n const tx = txRaw as unknown as Database;\n const [operation] = await tx\n .select()\n .from(schema.videoGenerationOperations)\n .where(\n and(\n eq(schema.videoGenerationOperations.workspaceId, input.workspaceId),\n eq(schema.videoGenerationOperations.id, input.operationId),\n eq(schema.videoGenerationOperations.requestDigest, input.requestDigest),\n ),\n )\n .for(\"update\")\n .limit(1);\n if (!operation) throw new VideoGenerationConflictError(\"Video operation not found\");\n return await mutate(tx, operation);\n }),\n );\n}\n\nasync function releaseReservedQuota(\n tx: Database,\n operation: VideoGenerationOperation,\n ready: boolean,\n): Promise<void> {\n if (operation.quotaState !== \"reserved\") return;\n await tx\n .update(schema.workspaceVideoGenerationQuotas)\n .set({\n reservedBytes: sql`${schema.workspaceVideoGenerationQuotas.reservedBytes} - ${operation.reservedBytes}`,\n ...(ready\n ? {\n readyBytes: sql`${schema.workspaceVideoGenerationQuotas.readyBytes} + ${operation.reservedBytes}`,\n }\n : {}),\n updatedAt: new Date(),\n })\n .where(eq(schema.workspaceVideoGenerationQuotas.workspaceId, operation.workspaceId));\n}\n\nasync function debitVideoGenerationCredits(\n tx: Database,\n operation: VideoGenerationOperation,\n): Promise<void> {\n if (operation.pricedCostMicros <= 0 || operation.fundingSource !== \"opengeni_credits\") {\n throw new Error(\"Managed video credit debit has an invalid funding binding\");\n }\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${operation.accountId}))`);\n const [balanceRow] = await tx\n .select({\n balanceMicros: sql<number>`coalesce(sum(${schema.creditLedgerEntries.amountMicros}), 0)`,\n })\n .from(schema.creditLedgerEntries)\n .where(eq(schema.creditLedgerEntries.accountId, operation.accountId));\n const balanceMicros = Number(balanceRow?.balanceMicros ?? 0);\n if (!Number.isSafeInteger(balanceMicros) || balanceMicros < operation.pricedCostMicros) {\n throw new VideoGenerationCreditError();\n }\n const now = new Date();\n const inserted = await tx\n .insert(schema.creditLedgerEntries)\n .values({\n accountId: operation.accountId,\n workspaceId: operation.workspaceId,\n type: \"video_generation_debit\",\n amountMicros: -operation.pricedCostMicros,\n sourceType: \"video_generation_operation\",\n sourceId: operation.id,\n idempotencyKey: `credit:video_generation_debit:${operation.id}`,\n metadata: {\n modelId: operation.modelId,\n sourceMode: operation.sourceMode,\n pricedCostMicros: operation.pricedCostMicros,\n },\n occurredAt: now,\n })\n .onConflictDoNothing({ target: schema.creditLedgerEntries.idempotencyKey })\n .returning({ id: schema.creditLedgerEntries.id });\n if (inserted.length !== 1) {\n throw new VideoGenerationConflictError(\"Video generation credit debit already exists\");\n }\n await tx\n .insert(schema.usageEvents)\n .values({\n accountId: operation.accountId,\n workspaceId: operation.workspaceId,\n eventType: \"video_generation.cost\",\n quantity: operation.pricedCostMicros,\n unit: \"usd_micros\",\n sourceResourceType: \"video_generation_operation\",\n sourceResourceId: operation.id,\n sessionId: operation.sessionId,\n turnId: operation.turnId,\n turnAttemptId: operation.attemptId,\n idempotencyKey: `usage:video_generation.cost:${operation.id}`,\n occurredAt: now,\n })\n .onConflictDoNothing({ target: schema.usageEvents.idempotencyKey });\n}\n\nasync function refundVideoGenerationCredits(\n tx: Database,\n operation: VideoGenerationOperation,\n now: Date,\n): Promise<VideoGenerationOperation[\"creditState\"]> {\n if (operation.creditState !== \"debited\") return operation.creditState;\n if (operation.fundingSource !== \"opengeni_credits\" || operation.pricedCostMicros <= 0) {\n throw new Error(\"Video generation credit refund has an invalid funding binding\");\n }\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${operation.accountId}))`);\n const inserted = await tx\n .insert(schema.creditLedgerEntries)\n .values({\n accountId: operation.accountId,\n workspaceId: operation.workspaceId,\n type: \"video_generation_refund\",\n amountMicros: operation.pricedCostMicros,\n sourceType: \"video_generation_operation\",\n sourceId: operation.id,\n idempotencyKey: `credit:video_generation_refund:${operation.id}`,\n metadata: {\n modelId: operation.modelId,\n sourceMode: operation.sourceMode,\n pricedCostMicros: operation.pricedCostMicros,\n },\n occurredAt: now,\n })\n .onConflictDoNothing({ target: schema.creditLedgerEntries.idempotencyKey })\n .returning({ id: schema.creditLedgerEntries.id });\n if (inserted.length !== 1) {\n throw new VideoGenerationConflictError(\"Video generation credit refund already exists\");\n }\n await tx\n .insert(schema.usageEvents)\n .values({\n accountId: operation.accountId,\n workspaceId: operation.workspaceId,\n eventType: \"video_generation.refund\",\n quantity: operation.pricedCostMicros,\n unit: \"usd_micros\",\n sourceResourceType: \"video_generation_operation\",\n sourceResourceId: operation.id,\n sessionId: operation.sessionId,\n turnId: operation.turnId,\n turnAttemptId: operation.attemptId,\n idempotencyKey: `usage:video_generation.refund:${operation.id}`,\n occurredAt: now,\n })\n .onConflictDoNothing({ target: schema.usageEvents.idempotencyKey });\n return \"refunded\";\n}\n\nfunction policyFromRow(\n row: typeof schema.workspaceVideoGenerationPolicies.$inferSelect | undefined,\n): VideoGenerationPolicyValue {\n return VideoGenerationPolicy.parse(\n row\n ? {\n schemaVersion: 1,\n revision: row.revision,\n fundingSource: row.fundingSource,\n enabledModelIds: row.enabledModelIds,\n defaultModelId: row.defaultModelId,\n }\n : {\n schemaVersion: 1,\n revision: 0,\n fundingSource: \"workspace_gateway\",\n enabledModelIds: [],\n defaultModelId: null,\n },\n );\n}\n\nfunction assertSupportedModels(modelIds: readonly string[]): void {\n for (const modelId of modelIds) {\n if (modelId !== SEEDANCE_2_5_MODEL_ID && modelId !== GROK_IMAGINE_VIDEO_1_5_MODEL_ID) {\n throw new Error(`Unknown video generation model: ${modelId}`);\n }\n }\n}\n\nfunction assertAdmissionMatches(\n operation: VideoGenerationOperation,\n input: AdmitVideoGenerationOperationInput,\n): void {\n if (\n operation.requestDigest !== input.requestDigest ||\n operation.toolCallId !== input.toolCallId ||\n operation.sessionId !== input.sessionId ||\n operation.turnId !== input.turnId ||\n operation.fundingSource !== input.fundingSource ||\n operation.pricedCostMicros !== input.pricedCostMicros\n ) {\n throw new VideoGenerationConflictError(\n \"Video generation admission key was reused with different arguments\",\n );\n }\n}\n\nfunction inPreSubmitState(status: string): boolean {\n return inArrayValue(status, [\"preparing\", \"prepared\", \"accepted\"]);\n}\n\nfunction inArrayValue<T extends string>(value: string, candidates: readonly T[]): value is T {\n return (candidates as readonly string[]).includes(value);\n}\n\nfunction invalidTransition(operation: VideoGenerationOperation, target: string): Error {\n return new VideoGenerationConflictError(\n `Invalid video generation transition ${operation.status} -> ${target}`,\n );\n}\n\nfunction requireRow<T>(value: T | undefined, action: string): T {\n if (!value) throw new Error(`Failed to ${action}`);\n return value;\n}\n\nfunction boundPublicReason(value: string): string {\n const normalized = value.replace(/\\s+/gu, \" \").trim();\n return (normalized || \"Video generation did not complete.\").slice(0, 1_000);\n}\n\nfunction boundPrivateError(value: string): string {\n return value.replace(/\\s+/gu, \" \").trim().slice(0, 4_096);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,117 @@
1
+ import {
2
+ rawRows,
3
+ rlsContextForWorkspace,
4
+ withWorkspaceSubjectRls,
5
+ withWorkspaceSubjectSessionActivityRls
6
+ } from "./chunk-JC5QPLUM.js";
7
+
8
+ // src/session-tenancy.ts
9
+ import { createHash } from "crypto";
10
+ import { sql } from "drizzle-orm";
11
+ function canonicalSessionVisibilityTransitionHash(input) {
12
+ return createHash("sha256").update(
13
+ JSON.stringify({
14
+ version: 1,
15
+ sessionId: input.sessionId,
16
+ targetVisibility: input.targetVisibility,
17
+ expectedAuthorityEpoch: input.expectedAuthorityEpoch
18
+ })
19
+ ).digest("hex");
20
+ }
21
+ function canonicalSessionForkHash(input) {
22
+ return createHash("sha256").update(
23
+ JSON.stringify({
24
+ version: 1,
25
+ sourceSessionId: input.sourceSessionId,
26
+ destinationWorkspaceId: input.destinationWorkspaceId,
27
+ destinationVisibility: input.destinationVisibility
28
+ })
29
+ ).digest("hex");
30
+ }
31
+ async function transitionSessionVisibility(db, input) {
32
+ if (!Number.isSafeInteger(input.expectedAuthorityEpoch) || input.expectedAuthorityEpoch < 1) {
33
+ throw new Error("expectedAuthorityEpoch must be a positive safe integer");
34
+ }
35
+ if (!input.operationKey.trim()) throw new Error("operationKey must not be empty");
36
+ const requestHash = canonicalSessionVisibilityTransitionHash(input);
37
+ const { accountId } = await rlsContextForWorkspace(db, input.workspaceId);
38
+ return await withWorkspaceSubjectSessionActivityRls(
39
+ db,
40
+ input.workspaceId,
41
+ input.actorSubjectId,
42
+ async (scopedDb) => {
43
+ const rows = await rawRows(
44
+ scopedDb,
45
+ sql`select
46
+ operation_id as "operationId",
47
+ visibility,
48
+ authority_epoch as "authorityEpoch",
49
+ owner_organization_membership_id as "ownerOrganizationMembershipId",
50
+ changed,
51
+ replay,
52
+ interrupted_attempt_count as "interruptedAttemptCount",
53
+ cancelled_turn_count as "cancelledTurnCount",
54
+ cancelled_update_count as "cancelledUpdateCount",
55
+ paused_goal_count as "pausedGoalCount",
56
+ revoked_grant_count as "revokedGrantCount"
57
+ from transition_session_visibility(
58
+ ${accountId}::uuid,
59
+ ${input.workspaceId}::uuid,
60
+ ${input.sessionId}::uuid,
61
+ ${input.actorSubjectId},
62
+ ${input.targetVisibility},
63
+ ${input.expectedAuthorityEpoch},
64
+ ${input.operationKey},
65
+ ${requestHash}
66
+ )`
67
+ );
68
+ const result = rows[0];
69
+ if (!result) throw new Error("Session visibility transition returned no result");
70
+ return result;
71
+ }
72
+ );
73
+ }
74
+ async function forkSessionContent(db, input) {
75
+ if (!input.operationKey.trim()) throw new Error("operationKey must not be empty");
76
+ const { accountId } = await rlsContextForWorkspace(db, input.sourceWorkspaceId);
77
+ const requestHash = canonicalSessionForkHash(input);
78
+ return await withWorkspaceSubjectRls(
79
+ db,
80
+ input.sourceWorkspaceId,
81
+ input.actorSubjectId,
82
+ async (scopedDb) => {
83
+ const rows = await rawRows(
84
+ scopedDb,
85
+ sql`select
86
+ operation_id as "operationId",
87
+ session_id as "sessionId",
88
+ workspace_id as "workspaceId",
89
+ visibility,
90
+ authority_epoch as "authorityEpoch",
91
+ copied_history_item_count as "copiedHistoryItemCount",
92
+ replay
93
+ from fork_session_content(
94
+ ${accountId}::uuid,
95
+ ${input.sourceWorkspaceId}::uuid,
96
+ ${input.sourceSessionId}::uuid,
97
+ ${input.actorSubjectId},
98
+ ${input.destinationWorkspaceId}::uuid,
99
+ ${input.destinationVisibility},
100
+ ${input.operationKey},
101
+ ${requestHash}
102
+ )`
103
+ );
104
+ const result = rows[0];
105
+ if (!result) throw new Error("Session fork returned no result");
106
+ return result;
107
+ }
108
+ );
109
+ }
110
+
111
+ export {
112
+ canonicalSessionVisibilityTransitionHash,
113
+ canonicalSessionForkHash,
114
+ transitionSessionVisibility,
115
+ forkSessionContent
116
+ };
117
+ //# sourceMappingURL=chunk-F32YT7MP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session-tenancy.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { sql } from \"drizzle-orm\";\nimport {\n rawRows,\n type Database,\n rlsContextForWorkspace,\n withWorkspaceSubjectRls,\n withWorkspaceSubjectSessionActivityRls,\n} from \"./database\";\n\nexport type SessionTenancyVisibility = \"user_private\" | \"workspace_shared\";\n\nexport type TransitionSessionVisibilityInput = {\n workspaceId: string;\n sessionId: string;\n actorSubjectId: string;\n targetVisibility: SessionTenancyVisibility;\n expectedAuthorityEpoch: number;\n operationKey: string;\n};\n\nexport type TransitionSessionVisibilityResult = {\n operationId: string;\n visibility: SessionTenancyVisibility;\n authorityEpoch: number;\n ownerOrganizationMembershipId: string | null;\n changed: boolean;\n replay: boolean;\n interruptedAttemptCount: number;\n cancelledTurnCount: number;\n cancelledUpdateCount: number;\n pausedGoalCount: number;\n revokedGrantCount: number;\n};\n\nexport type ForkSessionContentInput = {\n sourceWorkspaceId: string;\n sourceSessionId: string;\n actorSubjectId: string;\n destinationWorkspaceId: string;\n destinationVisibility: SessionTenancyVisibility;\n operationKey: string;\n};\n\nexport type ForkSessionContentResult = {\n operationId: string;\n sessionId: string;\n workspaceId: string;\n visibility: SessionTenancyVisibility;\n authorityEpoch: number;\n copiedHistoryItemCount: number;\n replay: boolean;\n};\n\nexport function canonicalSessionVisibilityTransitionHash(\n input: Pick<\n TransitionSessionVisibilityInput,\n \"sessionId\" | \"targetVisibility\" | \"expectedAuthorityEpoch\"\n >,\n): string {\n return createHash(\"sha256\")\n .update(\n JSON.stringify({\n version: 1,\n sessionId: input.sessionId,\n targetVisibility: input.targetVisibility,\n expectedAuthorityEpoch: input.expectedAuthorityEpoch,\n }),\n )\n .digest(\"hex\");\n}\n\nexport function canonicalSessionForkHash(\n input: Pick<\n ForkSessionContentInput,\n \"sourceSessionId\" | \"destinationWorkspaceId\" | \"destinationVisibility\"\n >,\n): string {\n return createHash(\"sha256\")\n .update(\n JSON.stringify({\n version: 1,\n sourceSessionId: input.sourceSessionId,\n destinationWorkspaceId: input.destinationWorkspaceId,\n destinationVisibility: input.destinationVisibility,\n }),\n )\n .digest(\"hex\");\n}\n\nexport async function transitionSessionVisibility(\n db: Database,\n input: TransitionSessionVisibilityInput,\n): Promise<TransitionSessionVisibilityResult> {\n if (!Number.isSafeInteger(input.expectedAuthorityEpoch) || input.expectedAuthorityEpoch < 1) {\n throw new Error(\"expectedAuthorityEpoch must be a positive safe integer\");\n }\n if (!input.operationKey.trim()) throw new Error(\"operationKey must not be empty\");\n const requestHash = canonicalSessionVisibilityTransitionHash(input);\n const { accountId } = await rlsContextForWorkspace(db, input.workspaceId);\n return await withWorkspaceSubjectSessionActivityRls(\n db,\n input.workspaceId,\n input.actorSubjectId,\n async (scopedDb) => {\n const rows = await rawRows<{\n operationId: string;\n visibility: SessionTenancyVisibility;\n authorityEpoch: number;\n ownerOrganizationMembershipId: string | null;\n changed: boolean;\n replay: boolean;\n interruptedAttemptCount: number;\n cancelledTurnCount: number;\n cancelledUpdateCount: number;\n pausedGoalCount: number;\n revokedGrantCount: number;\n }>(\n scopedDb,\n sql`select\n operation_id as \"operationId\",\n visibility,\n authority_epoch as \"authorityEpoch\",\n owner_organization_membership_id as \"ownerOrganizationMembershipId\",\n changed,\n replay,\n interrupted_attempt_count as \"interruptedAttemptCount\",\n cancelled_turn_count as \"cancelledTurnCount\",\n cancelled_update_count as \"cancelledUpdateCount\",\n paused_goal_count as \"pausedGoalCount\",\n revoked_grant_count as \"revokedGrantCount\"\n from transition_session_visibility(\n ${accountId}::uuid,\n ${input.workspaceId}::uuid,\n ${input.sessionId}::uuid,\n ${input.actorSubjectId},\n ${input.targetVisibility},\n ${input.expectedAuthorityEpoch},\n ${input.operationKey},\n ${requestHash}\n )`,\n );\n const result = rows[0];\n if (!result) throw new Error(\"Session visibility transition returned no result\");\n return result;\n },\n );\n}\n\nexport async function forkSessionContent(\n db: Database,\n input: ForkSessionContentInput,\n): Promise<ForkSessionContentResult> {\n if (!input.operationKey.trim()) throw new Error(\"operationKey must not be empty\");\n const { accountId } = await rlsContextForWorkspace(db, input.sourceWorkspaceId);\n const requestHash = canonicalSessionForkHash(input);\n return await withWorkspaceSubjectRls(\n db,\n input.sourceWorkspaceId,\n input.actorSubjectId,\n async (scopedDb) => {\n const rows = await rawRows<ForkSessionContentResult>(\n scopedDb,\n sql`select\n operation_id as \"operationId\",\n session_id as \"sessionId\",\n workspace_id as \"workspaceId\",\n visibility,\n authority_epoch as \"authorityEpoch\",\n copied_history_item_count as \"copiedHistoryItemCount\",\n replay\n from fork_session_content(\n ${accountId}::uuid,\n ${input.sourceWorkspaceId}::uuid,\n ${input.sourceSessionId}::uuid,\n ${input.actorSubjectId},\n ${input.destinationWorkspaceId}::uuid,\n ${input.destinationVisibility},\n ${input.operationKey},\n ${requestHash}\n )`,\n );\n const result = rows[0];\n if (!result) throw new Error(\"Session fork returned no result\");\n return result;\n },\n );\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,WAAW;AAqDb,SAAS,yCACd,OAIQ;AACR,SAAO,WAAW,QAAQ,EACvB;AAAA,IACC,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,WAAW,MAAM;AAAA,MACjB,kBAAkB,MAAM;AAAA,MACxB,wBAAwB,MAAM;AAAA,IAChC,CAAC;AAAA,EACH,EACC,OAAO,KAAK;AACjB;AAEO,SAAS,yBACd,OAIQ;AACR,SAAO,WAAW,QAAQ,EACvB;AAAA,IACC,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,iBAAiB,MAAM;AAAA,MACvB,wBAAwB,MAAM;AAAA,MAC9B,uBAAuB,MAAM;AAAA,IAC/B,CAAC;AAAA,EACH,EACC,OAAO,KAAK;AACjB;AAEA,eAAsB,4BACpB,IACA,OAC4C;AAC5C,MAAI,CAAC,OAAO,cAAc,MAAM,sBAAsB,KAAK,MAAM,yBAAyB,GAAG;AAC3F,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,MAAI,CAAC,MAAM,aAAa,KAAK,EAAG,OAAM,IAAI,MAAM,gCAAgC;AAChF,QAAM,cAAc,yCAAyC,KAAK;AAClE,QAAM,EAAE,UAAU,IAAI,MAAM,uBAAuB,IAAI,MAAM,WAAW;AACxE,SAAO,MAAM;AAAA,IACX;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO,aAAa;AAClB,YAAM,OAAO,MAAM;AAAA,QAajB;AAAA,QACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAaI,SAAS;AAAA,YACT,MAAM,WAAW;AAAA,YACjB,MAAM,SAAS;AAAA,YACf,MAAM,cAAc;AAAA,YACpB,MAAM,gBAAgB;AAAA,YACtB,MAAM,sBAAsB;AAAA,YAC5B,MAAM,YAAY;AAAA,YAClB,WAAW;AAAA;AAAA,MAEjB;AACA,YAAM,SAAS,KAAK,CAAC;AACrB,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,kDAAkD;AAC/E,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,eAAsB,mBACpB,IACA,OACmC;AACnC,MAAI,CAAC,MAAM,aAAa,KAAK,EAAG,OAAM,IAAI,MAAM,gCAAgC;AAChF,QAAM,EAAE,UAAU,IAAI,MAAM,uBAAuB,IAAI,MAAM,iBAAiB;AAC9E,QAAM,cAAc,yBAAyB,KAAK;AAClD,SAAO,MAAM;AAAA,IACX;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO,aAAa;AAClB,YAAM,OAAO,MAAM;AAAA,QACjB;AAAA,QACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YASI,SAAS;AAAA,YACT,MAAM,iBAAiB;AAAA,YACvB,MAAM,eAAe;AAAA,YACrB,MAAM,cAAc;AAAA,YACpB,MAAM,sBAAsB;AAAA,YAC5B,MAAM,qBAAqB;AAAA,YAC3B,MAAM,YAAY;AAAA,YAClB,WAAW;AAAA;AAAA,MAEjB;AACA,YAAM,SAAS,KAAK,CAAC;AACrB,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,iCAAiC;AAC9D,aAAO;AAAA,IACT;AAAA,EACF;AACF;","names":[]}
@@ -4,7 +4,7 @@ import {
4
4
  sessions,
5
5
  workspaceSessionActivityRevisions,
6
6
  workspaces
7
- } from "./chunk-MWDVXQOL.js";
7
+ } from "./chunk-5KTIEDX7.js";
8
8
 
9
9
  // src/persistence-errors.ts
10
10
  var SQLSTATE_KEYS = ["sqlState", "sqlstate", "code"];
@@ -172,9 +172,22 @@ async function runIdempotentPersistenceTransaction(options, transaction) {
172
172
  }
173
173
 
174
174
  // src/database.ts
175
+ import { AsyncLocalStorage } from "async_hooks";
175
176
  import { eq, sql } from "drizzle-orm";
176
177
  import { drizzle } from "drizzle-orm/postgres-js";
177
178
  import postgres from "postgres";
179
+ var sessionRlsActorContext = new AsyncLocalStorage();
180
+ async function withSessionRlsActorContext(actor, fn) {
181
+ if (!actor.subjectId.trim()) {
182
+ throw new Error("withSessionRlsActorContext: a non-empty subjectId is required");
183
+ }
184
+ if (actor.initiatingHumanSubjectId !== void 0 && actor.initiatingHumanSubjectId !== null && !actor.initiatingHumanSubjectId.trim()) {
185
+ throw new Error(
186
+ "withSessionRlsActorContext: initiatingHumanSubjectId must be null or non-empty"
187
+ );
188
+ }
189
+ return await sessionRlsActorContext.run(actor, fn);
190
+ }
178
191
  var dbBindings = /* @__PURE__ */ new WeakMap();
179
192
  function rlsStrategyFor(db) {
180
193
  return dbBindings.get(db)?.rlsStrategy ?? "force";
@@ -298,7 +311,20 @@ async function setRlsContext(db, context) {
298
311
  sql`select set_config('opengeni.workspace_id', ${context.workspaceId ?? ""}, true)`
299
312
  );
300
313
  await db.execute(sql`select set_config('opengeni.lossless_content_writer', '1', true)`);
301
- await db.execute(sql`select set_config('opengeni.sandbox_recovery_protocol_v2', '1', true)`);
314
+ await db.execute(sql`select
315
+ set_config('opengeni.sandbox_recovery_protocol_v2', '1', true),
316
+ set_config('opengeni.pending_tool_event_output_v1', '1', true)`);
317
+ const sessionActor = sessionRlsActorContext.getStore();
318
+ if (sessionActor) {
319
+ await setSubjectRlsContext(db, sessionActor.subjectId);
320
+ await db.execute(
321
+ sql`select set_config(
322
+ 'opengeni.initiating_human_subject_id',
323
+ ${sessionActor.initiatingHumanSubjectId ?? ""},
324
+ true
325
+ )`
326
+ );
327
+ }
302
328
  }
303
329
  async function readRlsContextSettings(db) {
304
330
  const [settings] = await rawRows(
@@ -612,6 +638,7 @@ export {
612
638
  SessionEventPersistenceError,
613
639
  isSessionEventPersistenceError,
614
640
  runIdempotentPersistenceTransaction,
641
+ withSessionRlsActorContext,
615
642
  rlsStrategyFor,
616
643
  rawRows,
617
644
  SandboxProviderReadLockUnavailableError,
@@ -636,4 +663,4 @@ export {
636
663
  withAccountRls,
637
664
  dbBindingFor
638
665
  };
639
- //# sourceMappingURL=chunk-ISI2TIUG.js.map
666
+ //# sourceMappingURL=chunk-JC5QPLUM.js.map