@opengeni/db 0.31.1 → 0.36.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.
Files changed (125) 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-FPVAD4CO.js +117 -0
  13. package/dist/chunk-FPVAD4CO.js.map +1 -0
  14. package/dist/chunk-GYO7ED2Q.js +259 -0
  15. package/dist/chunk-GYO7ED2Q.js.map +1 -0
  16. package/dist/{chunk-F5FT7BEZ.js → chunk-HSOWSYOX.js} +2 -2
  17. package/dist/{chunk-YHZXQ7HP.js → chunk-VKLB2ZGI.js} +446 -19
  18. package/dist/chunk-VKLB2ZGI.js.map +1 -0
  19. package/dist/{chunk-NBE6CHRI.js → chunk-VTPRIXKG.js} +49 -9
  20. package/dist/chunk-VTPRIXKG.js.map +1 -0
  21. package/dist/{chunk-ISI2TIUG.js → chunk-Z7VYMNPZ.js} +76 -4
  22. package/dist/chunk-Z7VYMNPZ.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 +467 -29
  27. package/dist/index.js +23247 -16232
  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/persistence-errors.d.ts +8 -0
  35. package/dist/provision-roles.js +1 -1
  36. package/dist/runtime-posture.d.ts +8 -7
  37. package/dist/schema.d.ts +9464 -5412
  38. package/dist/schema.js +51 -9
  39. package/dist/session-control.d.ts +29 -3
  40. package/dist/session-tenancy.d.ts +44 -0
  41. package/dist/session-tenancy.js +16 -0
  42. package/dist/session-tenancy.js.map +1 -0
  43. package/dist/slack-task-policy-schema.d.ts +847 -0
  44. package/dist/slack-task-policy.d.ts +65 -0
  45. package/dist/task-notes-schema.d.ts +924 -0
  46. package/dist/task-notes.d.ts +85 -0
  47. package/dist/video-generation.d.ts +9 -0
  48. package/dist/video-generation.js +5 -3
  49. package/dist/xai-subscription.d.ts +326 -0
  50. package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
  51. package/drizzle/0213_browser_interaction_authority.sql +67 -0
  52. package/drizzle/0214_browser_download_saves.sql +34 -0
  53. package/drizzle/0215_browser_controller_host.sql +385 -0
  54. package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
  55. package/drizzle/0217_external_browser_auth_operations.sql +22 -0
  56. package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
  57. package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
  58. package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
  59. package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
  60. package/drizzle/0220_session_channels.sql +54 -0
  61. package/drizzle/0221_sessions_channel_index.sql +5 -0
  62. package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
  63. package/drizzle/0222_sessions_channel_fk.sql +89 -0
  64. package/drizzle/0223_pending_tool_event_output.sql +55 -0
  65. package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
  66. package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
  67. package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
  68. package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
  69. package/drizzle/0227_slack_native_actions.sql +145 -0
  70. package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
  71. package/drizzle/0228_slack_task_policy.sql +400 -0
  72. package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
  73. package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
  74. package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
  75. package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
  76. package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
  77. package/drizzle/0234_xai_subscription_authority.sql +1139 -0
  78. package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
  79. package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
  80. package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
  81. package/drizzle/0237_interaction_transition_reaper.sql +263 -0
  82. package/drizzle/0238_goal_persistence_policy.sql +471 -0
  83. package/drizzle/0238_recover_unclaimed_session_turns.sql +307 -0
  84. package/drizzle/0238_supergrok_realtime_model.sql +29 -0
  85. package/drizzle/0239_supergrok_video_funding.sql +50 -0
  86. package/drizzle/0239_task_tree_notes.sql +990 -0
  87. package/package.json +13 -5
  88. package/src/browser-auth.ts +2600 -123
  89. package/src/browser-downloads.ts +517 -0
  90. package/src/browser-identities.ts +220 -3
  91. package/src/browser-sessions.ts +334 -45
  92. package/src/browser-state-artifacts.ts +402 -12
  93. package/src/canonical-human-identities.ts +317 -0
  94. package/src/capability-integrations.ts +121 -213
  95. package/src/database.ts +41 -1
  96. package/src/index.ts +4625 -411
  97. package/src/insights.ts +109 -28
  98. package/src/integration-bindings.ts +101 -101
  99. package/src/{integration-features.ts → integration-facets.ts} +187 -184
  100. package/src/interaction-revisions.ts +33 -3
  101. package/src/interaction-schema.ts +311 -8
  102. package/src/pack-components.ts +43 -43
  103. package/src/pack-installations.ts +0 -43
  104. package/src/persistence-errors.ts +60 -1
  105. package/src/plugin-packages.ts +9 -9
  106. package/src/provision-roles.ts +232 -0
  107. package/src/runtime-posture.ts +227 -14
  108. package/src/schema.ts +1188 -75
  109. package/src/session-control.ts +122 -37
  110. package/src/session-queue-commands.ts +78 -1
  111. package/src/session-tenancy.ts +188 -0
  112. package/src/session-tool-call-settlement.ts +9 -3
  113. package/src/slack-task-policy-schema.ts +130 -0
  114. package/src/slack-task-policy.ts +341 -0
  115. package/src/task-notes-schema.ts +135 -0
  116. package/src/task-notes.ts +178 -0
  117. package/src/video-generation.ts +90 -12
  118. package/src/workspace-artifacts.ts +1 -1
  119. package/src/xai-subscription.ts +1887 -0
  120. package/dist/chunk-ISI2TIUG.js.map +0 -1
  121. package/dist/chunk-MWDVXQOL.js.map +0 -1
  122. package/dist/chunk-NBE6CHRI.js.map +0 -1
  123. package/dist/chunk-YHZXQ7HP.js.map +0 -1
  124. package/dist/integration-features.d.ts +0 -99
  125. /package/dist/{chunk-F5FT7BEZ.js.map → chunk-HSOWSYOX.js.map} +0 -0
@@ -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":";;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AACP,SAAS,KAAK,IAAI,SAAS,WAAW;AAK/B,IAAM,mCAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAUO,IAAM,+BAAN,cAA2C,MAAM;AAAA,EACtD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,+BAAN,cAA2C,MAAM;AAAA,EACtD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,6BAAN,cAAyC,MAAM;AAAA,EACpD,YAAY,UAAU,iCAAiC;AACrD,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEA,eAAsB,kCACpB,IACA,aACqC;AACrC,SAAO,MAAM,iBAAiB,IAAI,aAAa,OAAO,aAAa;AACjE,UAAM,CAAC,GAAG,IAAI,MAAM,SACjB,OAAO,EACP,KAAY,gCAAgC,EAC5C,MAAM,GAAU,iCAAiC,aAAa,WAAW,CAAC,EAC1E,MAAM,CAAC;AACV,WAAO,cAAc,GAAG;AAAA,EAC1B,CAAC;AACH;AAEA,eAAsB,qCACpB,IACA,OASqC;AACrC,QAAM,YAAY,sBAAsB,MAAM;AAAA,IAC5C,eAAe;AAAA,IACf,UAAU,MAAM,mBAAmB;AAAA,IACnC,eAAe,MAAM;AAAA,IACrB,iBAAiB,MAAM;AAAA,IACvB,gBAAgB,MAAM;AAAA,EACxB,CAAC;AACD,wBAAsB,UAAU,eAAe;AAC/C,SAAO,MAAM;AAAA,IACX;AAAA,IACA,EAAE,WAAW,MAAM,WAAW,aAAa,MAAM,YAAY;AAAA,IAC7D,OAAO,aACL,MAAM,SAAS,YAAY,OAAO,OAAO;AACvC,YAAM,CAAC,SAAS,IAAI,MAAM,GACvB,OAAO,EAAE,IAAW,WAAW,GAAG,CAAC,EACnC,KAAY,UAAU,EACtB;AAAA,QACC;AAAA,UACE,GAAU,WAAW,IAAI,MAAM,WAAW;AAAA,UAC1C,GAAU,WAAW,WAAW,MAAM,SAAS;AAAA,QACjD;AAAA,MACF,EACC,IAAI,QAAQ,EACZ,MAAM,CAAC;AACV,UAAI,CAAC,UAAW,OAAM,IAAI,MAAM,qBAAqB;AACrD,YAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAO,EACP,KAAY,gCAAgC,EAC5C,MAAM,GAAU,iCAAiC,aAAa,MAAM,WAAW,CAAC,EAChF,IAAI,QAAQ,EACZ,MAAM,CAAC;AACV,YAAM,kBAAkB,SAAS,YAAY;AAC7C,UAAI,oBAAoB,MAAM,kBAAkB;AAC9C,cAAM,IAAI,6BAA6B,iCAAiC;AAAA,MAC1E;AACA,YAAM,MAAM,oBAAI,KAAK;AACrB,YAAM,SAAS;AAAA,QACb,aAAa,MAAM;AAAA,QACnB,WAAW,MAAM;AAAA,QACjB,UAAU,kBAAkB;AAAA,QAC5B,eAAe,UAAU;AAAA,QACzB,iBAAiB,CAAC,GAAG,UAAU,eAAe;AAAA,QAC9C,gBAAgB,UAAU;AAAA,QAC1B,oBAAoB,MAAM,UAAU,MAAM,GAAG,IAAK;AAAA,QAClD,WAAW;AAAA,MACb;AACA,YAAM,CAAC,GAAG,IAAI,UACV,MAAM,GACH,OAAc,gCAAgC,EAC9C,IAAI,MAAM,EACV,MAAM,GAAU,iCAAiC,aAAa,MAAM,WAAW,CAAC,EAChF,UAAU,IACb,MAAM,GAAG,OAAc,gCAAgC,EAAE,OAAO,MAAM,EAAE,UAAU;AACtF,UAAI,CAAC,IAAK,OAAM,IAAI,MAAM,kDAAkD;AAC5E,aAAO,cAAc,GAAG;AAAA,IAC1B,CAAC;AAAA,EACL;AACF;AA0CA,eAAsB,8BACpB,IACA,OACoE;AACpE,QAAM,gBAAgB,MAAM,iBAAiB;AAC7C,SAAO,MAAM;AAAA,IACX;AAAA,IACA,EAAE,WAAW,MAAM,WAAW,aAAa,MAAM,YAAY;AAAA,IAC7D,OAAO,aACL,MAAM,SAAS,YAAY,OAAO,OAAO;AACvC,YAAM,GAAG;AAAA,QACP,oDAAoD,oBAAoB,MAAM,YAAY,EAAE;AAAA,MAC9F;AACA,YAAM,CAAC,QAAQ,IAAI,MAAM,GACtB,OAAO,EACP,KAAY,yBAAyB,EACrC;AAAA,QACC;AAAA,UACE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,UAClE,GAAU,0BAA0B,cAAc,MAAM,YAAY;AAAA,QACtE;AAAA,MACF,EACC,MAAM,CAAC;AACV,UAAI,UAAU;AACZ,+BAAuB,UAAU,KAAK;AACtC,eAAO,EAAE,WAAW,UAAU,SAAS,MAAM;AAAA,MAC/C;AACA,YAAM,CAAC,MAAM,IAAI,MAAM,GACpB,OAAO,EACP,KAAY,gCAAgC,EAC5C,MAAM,GAAU,iCAAiC,aAAa,MAAM,WAAW,CAAC,EAChF,IAAI,QAAQ,EACZ,MAAM,CAAC;AACV,UACE,CAAC,UACD,OAAO,aAAa,MAAM,kBAC1B,OAAO,kBAAkB,MAAM,iBAC/B,CAAC,OAAO,gBAAgB,SAAS,MAAM,OAAO,GAC9C;AACA,cAAM,IAAI,6BAA6B,qCAAqC;AAAA,MAC9E;AACA,YAAM,SAAS,MAAM,GAClB,OAAO,EAAE,IAAW,0BAA0B,GAAG,CAAC,EAClD,KAAY,yBAAyB,EACrC;AAAA,QACC;AAAA,UACE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,UAClE,QAAe,0BAA0B,QAAQ;AAAA,YAC/C,GAAG;AAAA,UACL,CAAC;AAAA,QACH;AAAA,MACF,EACC,IAAI,QAAQ;AACf,UAAI,OAAO,UAAU,MAAM,2BAA2B;AACpD,cAAM,IAAI,6BAA6B,0CAA0C;AAAA,MACnF;AACA,YAAM,GACH,OAAc,8BAA8B,EAC5C,OAAO;AAAA,QACN,aAAa,MAAM;AAAA,QACnB,WAAW,MAAM;AAAA,MACnB,CAAC,EACA,oBAAoB;AAAA,QACnB,QAAe,+BAA+B;AAAA,MAChD,CAAC;AACH,YAAM,CAAC,KAAK,IAAI,MAAM,GACnB,OAAO,EACP,KAAY,8BAA8B,EAC1C,MAAM,GAAU,+BAA+B,aAAa,MAAM,WAAW,CAAC,EAC9E,IAAI,QAAQ,EACZ,MAAM,CAAC;AACV,UAAI,CAAC,MAAO,OAAM,IAAI,MAAM,wCAAwC;AACpE,UAAI,MAAM,gBAAgB,MAAM,aAAa,gBAAgB,MAAM,qBAAqB;AACtF,cAAM,IAAI,6BAA6B,uCAAuC;AAAA,MAChF;AACA,YAAM,CAAC,SAAS,IAAI,MAAM,GACvB,OAAc,yBAAyB,EACvC,OAAO;AAAA,QACN,IAAI,MAAM;AAAA,QACV,WAAW,MAAM;AAAA,QACjB,aAAa,MAAM;AAAA,QACnB,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM;AAAA,QACd,WAAW,MAAM;AAAA,QACjB,YAAY,MAAM;AAAA,QAClB,cAAc,MAAM;AAAA,QACpB,eAAe,MAAM;AAAA,QACrB,cAAc,MAAM;AAAA,QACpB,kBAAkB,MAAM;AAAA,QACxB,SAAS,MAAM;AAAA,QACf,YAAY,MAAM;AAAA,QAClB,oBAAoB,MAAM;AAAA,QAC1B,eAAe,MAAM;AAAA,QACrB,kBAAkB,MAAM;AAAA,QACxB,aAAa,MAAM,mBAAmB,IAAI,YAAY;AAAA,QACtD,cAAc,MAAM;AAAA,QACpB,mBAAmB,MAAM;AAAA,QACzB,qBAAqB,MAAM;AAAA,QAC3B,wBAAwB,MAAM;AAAA,QAC9B,oBAAoB,MAAM;AAAA,QAC1B,gBAAgB,MAAM;AAAA,QACtB;AAAA,QACA,oBAAoB,MAAM;AAAA,QAC1B,QAAQ,MAAM,WAAW,WAAW,IAAI,aAAa;AAAA,QACrD,sBAAsB;AAAA,QACtB,qBAAqB;AAAA,MACvB,CAAC,EACA,UAAU;AACb,UAAI,CAAC,UAAW,OAAM,IAAI,MAAM,6CAA6C;AAC7E,UAAI,MAAM,mBAAmB,GAAG;AAC9B,YAAI,MAAM,kBAAkB,sBAAsB,MAAM,iBAAiB,MAAM;AAC7E,gBAAM,IAAI,MAAM,yDAAyD;AAAA,QAC3E;AACA,cAAM,4BAA4B,IAAI,SAAS;AAAA,MACjD;AACA,UAAI,MAAM,WAAW,SAAS,GAAG;AAC/B,cAAM,GAAG,OAAc,yBAAyB,EAAE;AAAA,UAChD,MAAM,WAAW,IAAI,CAAC,eAAe;AAAA,YACnC,aAAa,UAAU;AAAA,YACvB,aAAa,MAAM;AAAA,YACnB,WAAW,MAAM;AAAA,YACjB,gBAAgB,UAAU,kBAAkB;AAAA,YAC5C,GAAG;AAAA,UACL,EAAE;AAAA,QACJ;AAAA,MACF;AACA,YAAM,GACH,OAAc,8BAA8B,EAC5C,IAAI;AAAA,QACH,eAAe,MAAa,+BAA+B,aAAa,MAAM,aAAa;AAAA,QAC3F,WAAW,oBAAI,KAAK;AAAA,MACtB,CAAC,EACA,MAAM,GAAU,+BAA+B,aAAa,MAAM,WAAW,CAAC;AACjF,aAAO,EAAE,WAAW,SAAS,KAAK;AAAA,IACpC,CAAC;AAAA,EACL;AACF;AAGA,eAAsB,gCACpB,IACA,OAQmC;AACnC,QAAM,CAAC,GAAG,IAAI,MAAM,GACjB,OAAc,yBAAyB,EACvC,IAAI;AAAA,IACH,qBAAqB,MAAM;AAAA,IAC3B,WAAW,oBAAI,KAAK;AAAA,EACtB,CAAC,EACA;AAAA,IACC;AAAA,MACE,GAAU,0BAA0B,WAAW,MAAM,SAAS;AAAA,MAC9D,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,MAClE,GAAU,0BAA0B,IAAI,MAAM,WAAW;AAAA,MACzD,GAAU,0BAA0B,eAAe,MAAM,aAAa;AAAA,MACtE,GAAU,0BAA0B,qBAAqB,MAAM,2BAA2B;AAAA,MAC1F,QAAe,0BAA0B,QAAQ;AAAA,QAC/C;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,EACC,UAAU;AACb,MAAI,CAAC,IAAK,OAAM,IAAI,6BAA6B,mCAAmC;AACpF,SAAO;AACT;AAQA,eAAsB,4BACpB,IACA,OACmC;AACnC,SAAO,MAAM,gBAAgB,IAAI,OAAO,OAAO,IAAI,cAAc;AAC/D,QAAI,UAAU,WAAW,WAAY,QAAO;AAC5C,QAAI,UAAU,WAAW,YAAa,OAAM,kBAAkB,WAAW,UAAU;AACnF,UAAM,aAAa,MAAM,GACtB,OAAO;AAAA,MACN,kBAAyB,0BAA0B;AAAA,MACnD,WAAkB,0BAA0B;AAAA,IAC9C,CAAC,EACA,KAAY,yBAAyB,EACrC,MAAM,GAAU,0BAA0B,aAAa,UAAU,EAAE,CAAC;AACvE,QACE,WAAW,WAAW,KACtB,WAAW,KAAK,CAAC,cAAc,CAAC,UAAU,oBAAoB,UAAU,SAAS,GACjF;AACA,YAAM,IAAI,6BAA6B,iCAAiC;AAAA,IAC1E;AACA,UAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI,EAAE,QAAQ,YAAY,WAAW,oBAAI,KAAK,EAAE,CAAC,EACjD,MAAM,GAAU,0BAA0B,IAAI,UAAU,EAAE,CAAC,EAC3D,UAAU;AACb,WAAO,WAAW,SAAS,kCAAkC;AAAA,EAC/D,CAAC;AACH;AAGA,eAAsB,4BACpB,IACA,OAMmC;AACnC,SAAO,MAAM;AAAA,IACX;AAAA,IACA;AAAA,IACA,OAAO,IAAI,cACT,MAAM,yCAAyC,IAAI;AAAA,MACjD,aAAa,MAAM;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACL;AACF;AAOA,eAAsB,yCACpB,IACA,OAKmC;AACnC,QAAM,YAAY,MAAM;AACxB,MAAI,MAAM,eAAe,UAAa,UAAU,eAAe,MAAM,YAAY;AAC/E,UAAM,IAAI,6BAA6B,6CAA6C;AAAA,EACtF;AACA,MAAI,UAAU,yBAAyB,WAAY,QAAO;AAC1D,MAAI,UAAU,WAAW,YAAY;AACnC,UAAM,IAAI,6BAA6B,mDAAmD;AAAA,EAC5F;AACA,QAAM,CAAC,MAAM,IAAI,MAAM,GACpB,OAAO,EACP,KAAY,gCAAgC,EAC5C,MAAM,GAAU,iCAAiC,aAAa,MAAM,WAAW,CAAC,EAChF,IAAI,OAAO,EACX,MAAM,CAAC;AACV,QAAM,CAAC,UAAU,IAAI,UAAU,eAC3B,MAAM,GACH,OAAO;AAAA,IACN,IAAW,YAAY;AAAA,IACvB,SAAgB,YAAY;AAAA,IAC5B,QAAe,YAAY;AAAA,IAC3B,UAAiB,YAAY;AAAA,EAC/B,CAAC,EACA,KAAY,WAAW,EACvB;AAAA,IACC;AAAA,MACE,GAAU,YAAY,aAAa,MAAM,WAAW;AAAA,MACpD,GAAU,YAAY,IAAI,UAAU,YAAY;AAAA,IAClD;AAAA,EACF,EACC,IAAI,OAAO,EACX,MAAM,CAAC,IACV,CAAC;AACL,QAAM,6BACJ,UAAU,kBAAkB,uBAC5B,YAAY,WAAW,YACvB,WAAW,YAAY,UAAU,qBACjC,WAAW,SAAS,mBAAmB;AACzC,QAAM,oBACJ,UAAU,kBAAkB,sBAC5B,UAAU,iBAAiB,SAC1B,UAAU,gBAAgB,aACxB,UAAU,gBAAgB,oBAAoB,UAAU,qBAAqB;AAClF,QAAM,sBACJ,UAAU,kBAAkB,4BAC5B,UAAU,iBAAiB,QAC3B,UAAU,wBAAwB,QAClC,UAAU,qBAAqB,KAC/B,UAAU,gBAAgB;AAC5B,MACE,CAAC,UACD,OAAO,kBAAkB,UAAU,iBACnC,CAAC,OAAO,gBAAgB,SAAS,UAAU,OAAO,KACjD,CAAC,8BAA8B,CAAC,qBAAqB,CAAC,qBACvD;AACA,UAAM,IAAI,6BAA6B,wCAAwC;AAAA,EACjF;AACA,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,IACH,QAAQ;AAAA,IACR,sBAAsB;AAAA,IACtB,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,IACjB,WAAW;AAAA,EACb,CAAC,EACA,MAAM,GAAU,0BAA0B,IAAI,UAAU,EAAE,CAAC,EAC3D,UAAU;AACb,SAAO,WAAW,SAAS,oCAAoC;AACjE;AAEA,eAAsB,kCACpB,IACA,OAOmC;AACnC,SAAO,MAAM,gBAAgB,IAAI,OAAO,OAAO,IAAI,cAAc;AAC/D,QAAI,UAAU,WAAW,0BAA2B,QAAO;AAC3D,QAAI,CAAC,iBAAiB,UAAU,MAAM,KAAK,UAAU,uBAAuB;AAC1E,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,qBAAqB,IAAI,WAAW,KAAK;AAC/C,UAAM,cAAc,MAAM,6BAA6B,IAAI,WAAW,GAAG;AACzE,UAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,MACH,QAAQ;AAAA,MACR;AAAA,MACA,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,qBACE,UAAU,yBAAyB,aAAa,YAAY;AAAA,MAC9D,qBAAqB;AAAA,MACrB,kBAAkB;AAAA,MAClB,qBAAqB,kBAAkB,MAAM,MAAM;AAAA,MACnD,WAAW;AAAA,IACb,CAAC,EACA,MAAM,GAAU,0BAA0B,IAAI,UAAU,EAAE,CAAC,EAC3D,UAAU;AACb,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,gDAAgD;AAC9E,WAAO;AAAA,EACT,CAAC;AACH;AAOA,eAAsB,0DACpB,IACA,OAQmB;AACnB,QAAM,cAAc,CAAC,GAAG,IAAI,IAAI,MAAM,WAAW,CAAC;AAClD,MAAI,YAAY,WAAW,EAAG,QAAO,CAAC;AACtC,QAAM,aAAa,MAAM,GACtB,OAAO,EACP,KAAY,yBAAyB,EACrC;AAAA,IACC;AAAA,MACE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,MAClE,GAAU,0BAA0B,WAAW,MAAM,SAAS;AAAA,MAC9D,GAAU,0BAA0B,QAAQ,MAAM,MAAM;AAAA,MACxD,QAAe,0BAA0B,YAAY,WAAW;AAAA,MAChE,GAAU,0BAA0B,sBAAsB,SAAS;AAAA,MACnE,QAAe,0BAA0B,QAAQ,CAAC,aAAa,UAAU,CAAC;AAAA,MAC1E,MAAa,0BAA0B,qBAAqB;AAAA,IAC9D;AAAA,EACF,EACC,QAAe,0BAA0B,EAAE,EAC3C,IAAI,QAAQ;AACf,QAAM,YAAsB,CAAC;AAC7B,aAAW,aAAa,YAAY;AAClC,UAAM,qBAAqB,IAAI,WAAW,KAAK;AAC/C,UAAM,cAAc,MAAM,6BAA6B,IAAI,WAAW,MAAM,GAAG;AAC/E,UAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,MACH,QAAQ;AAAA,MACR;AAAA,MACA,YAAY;AAAA,MACZ,YAAY,MAAM;AAAA,MAClB,qBAAqB;AAAA,MACrB,iBAAiB,MAAM;AAAA,MACvB,0BAA0B;AAAA,MAC1B,0BAA0B;AAAA,MAC1B,qBAAqB;AAAA,MACrB,kBAAkB;AAAA,MAClB,uBAAuB,MAAM;AAAA,MAC7B,qBAAqB,kBAAkB,MAAM,MAAM;AAAA,MACnD,qBAAqB;AAAA,MACrB,yBAAyB;AAAA,MACzB,WAAW,MAAM;AAAA,IACnB,CAAC,EACA,MAAM,GAAU,0BAA0B,IAAI,UAAU,EAAE,CAAC,EAC3D,UAAU,EAAE,IAAW,0BAA0B,GAAG,CAAC;AACxD,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,gDAAgD;AAC9E,UAAM,GACH,OAAc,yBAAyB,EACvC,IAAI,EAAE,cAAc,MAAM,IAAI,CAAC,EAC/B,MAAM,GAAU,0BAA0B,aAAa,UAAU,EAAE,CAAC;AACvE,cAAU,KAAK,QAAQ,EAAE;AAAA,EAC3B;AACA,SAAO;AACT;AAEA,eAAsB,+BACpB,IACA,OACiF;AACjF,QAAM,OAAO,MAAM;AAAA,IAKjB;AAAA,IACA;AAAA,QACI,MAAM,KAAK,KAAK,MAAM,YAAY,KAAK,MAAM,KAAK;AAAA;AAAA,EAExD;AACA,SAAO,KAAK,IAAI,CAAC,SAAS;AAAA,IACxB,aAAa,IAAI;AAAA,IACjB,WAAW,IAAI;AAAA,IACf,aAAa,IAAI;AAAA,EACnB,EAAE;AACJ;AAEA,eAAsB,4BACpB,IACA,aACA,aACwD;AACxD,SAAO,MAAM,iBAAiB,IAAI,aAAa,OAAO,aAAa;AACjE,UAAM,CAAC,SAAS,IAAI,MAAM,SACvB,OAAO,EACP,KAAY,yBAAyB,EACrC;AAAA,MACC;AAAA,QACE,GAAU,0BAA0B,aAAa,WAAW;AAAA,QAC5D,GAAU,0BAA0B,IAAI,WAAW;AAAA,MACrD;AAAA,IACF,EACC,MAAM,CAAC;AACV,QAAI,CAAC,UAAW,QAAO;AACvB,UAAM,aAAa,MAAM,SACtB,OAAO,EACP,KAAY,yBAAyB,EACrC,MAAM,GAAU,0BAA0B,aAAa,WAAW,CAAC,EACnE,QAAe,0BAA0B,OAAO;AACnD,WAAO,EAAE,GAAG,WAAW,WAAW;AAAA,EACpC,CAAC;AACH;AAEA,eAAsB,uCACpB,IACA,OACmC;AACnC,SAAO,MAAM,gBAAgB,IAAI,OAAO,OAAO,IAAI,cAAc;AAC/D,QAAI,UAAU,WAAW,0BAA0B,CAAC,UAAU,0BAA0B;AACtF,YAAM,kBAAkB,WAAW,sBAAsB;AAAA,IAC3D;AACA,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,MACH,QAAQ;AAAA,MACR,uBAAuB,UAAU,yBAAyB;AAAA,MAC1D,iBAAiB,MAAM;AAAA,MACvB,WAAW,kBAAkB,MAAM,KAAK;AAAA,MACxC,qBAAqB;AAAA,MACrB,yBAAyB;AAAA,MACzB,WAAW;AAAA,IACb,CAAC,EACA,MAAM,GAAU,0BAA0B,IAAI,UAAU,EAAE,CAAC,EAC3D,UAAU;AACb,WAAO,WAAW,SAAS,mCAAmC;AAAA,EAChE,CAAC;AACH;AAOA,eAAsB,oCACpB,IACA,OAKmC;AACnC,SAAO,MAAM,gBAAgB,IAAI,OAAO,OAAO,IAAI,cAAc;AAC/D,QAAI,UAAU,WAAW,wBAAwB;AAC/C,UAAI,CAAC,UAAU,4BAA4B,CAAC,UAAU,0BAA0B;AAC9E,cAAM,IAAI,6BAA6B,sCAAsC;AAAA,MAC/E;AACA,aAAO;AAAA,IACT;AACA,QAAI,UAAU,WAAW,YAAY;AACnC,YAAM,kBAAkB,WAAW,sBAAsB;AAAA,IAC3D;AACA,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,MACH,QAAQ;AAAA,MACR,0BAA0B,MAAM;AAAA,MAChC,0BAA0B,MAAM;AAAA,MAChC,iBAAiB,MAAM;AAAA,MACvB,WAAW;AAAA,MACX,qBAAqB;AAAA,MACrB,yBAAyB;AAAA,MACzB,WAAW;AAAA,IACb,CAAC,EACA,MAAM,GAAU,0BAA0B,IAAI,UAAU,EAAE,CAAC,EAC3D,UAAU;AACb,UAAM,GACH,OAAc,yBAAyB,EACvC,IAAI;AAAA,MACH,gBAAgB,MAAM;AAAA,MACtB,cAAc,IAAI;AAAA,QAChB,KAAK;AAAA,UACH,UAAU,mBAAmB,QAAQ;AAAA,UACrC,MAAM,yBAAyB,QAAQ;AAAA,QACzC;AAAA,MACF;AAAA,IACF,CAAC,EACA,MAAM,GAAU,0BAA0B,aAAa,UAAU,EAAE,CAAC;AACvE,WAAO,WAAW,SAAS,yCAAyC;AAAA,EACtE,CAAC;AACH;AAEA,eAAsB,mCACpB,IACA,OAImC;AACnC,SAAO,MAAM,gBAAgB,IAAI,OAAO,OAAO,IAAI,cAAc;AAC/D,QACE,UAAU,kBAAkB,MAAM,iBAClC,UAAU,WAAW,oBACrB;AACA,aAAO;AAAA,IACT;AACA,QAAI,CAAC,aAAa,UAAU,QAAQ,CAAC,YAAY,sBAAsB,CAAC,GAAG;AACzE,YAAM,kBAAkB,WAAW,kBAAkB;AAAA,IACvD;AACA,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,MACH,QAAQ;AAAA,MACR,eAAe,MAAM,cAAc,MAAM,GAAG,IAAK;AAAA,MACjD,0BAA0B;AAAA,MAC1B,0BAA0B;AAAA,MAC1B,uBAAuB,UAAU,yBAAyB;AAAA,MAC1D,mBAAmB,UAAU,qBAAqB;AAAA,MAClD,iBAAiB,MAAM;AAAA,MACvB,WAAW;AAAA,MACX,qBAAqB;AAAA,MACrB,yBAAyB;AAAA,MACzB,WAAW;AAAA,IACb,CAAC,EACA,MAAM,GAAU,0BAA0B,IAAI,UAAU,EAAE,CAAC,EAC3D,UAAU;AACb,WAAO,WAAW,SAAS,2BAA2B;AAAA,EACxD,CAAC;AACH;AAEA,eAAsB,mCACpB,IACA,OAKkB;AAClB,SAAO,MAAM;AAAA,IACX;AAAA,IACA,EAAE,WAAW,MAAM,WAAW,aAAa,MAAM,YAAY;AAAA,IAC7D,OAAO,aAAa;AAClB,YAAM,CAAC,OAAO,IAAI,MAAM,SACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,QACH,iBAAiB,MAAM;AAAA,QACvB,GAAI,MAAM,QAAQ,EAAE,WAAW,kBAAkB,MAAM,KAAK,EAAE,IAAI,CAAC;AAAA,QACnE,qBAAqB;AAAA,QACrB,yBAAyB;AAAA,QACzB,WAAW,oBAAI,KAAK;AAAA,MACtB,CAAC,EACA;AAAA,QACC;AAAA,UACE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,UAClE,GAAU,0BAA0B,IAAI,MAAM,WAAW;AAAA,UACzD,GAAU,0BAA0B,eAAe,MAAM,aAAa;AAAA,UACtE,GAAI,MAAM,QACN,CAAC,GAAU,0BAA0B,qBAAqB,MAAM,KAAK,CAAC,IACtE,CAAC;AAAA,QACP;AAAA,MACF,EACC,UAAU,EAAE,IAAW,0BAA0B,GAAG,CAAC;AACxD,aAAO,YAAY;AAAA,IACrB;AAAA,EACF;AACF;AAEA,eAAsB,6BACpB,IACA,OACmC;AACnC,SAAO,MAAM,gBAAgB,IAAI,OAAO,OAAO,IAAI,cAAc;AAC/D,QAAI,UAAU,WAAW,YAAa,QAAO;AAC7C,QAAI,UAAU,WAAW,mBAAoB,OAAM,kBAAkB,WAAW,WAAW;AAC3F,UAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,MACH,QAAQ;AAAA,MACR,iBAAiB,oBAAI,KAAK;AAAA,MAC1B,qBAAqB;AAAA,MACrB,yBAAyB;AAAA,MACzB,WAAW,oBAAI,KAAK;AAAA,IACtB,CAAC,EACA,MAAM,GAAU,0BAA0B,IAAI,UAAU,EAAE,CAAC,EAC3D,UAAU;AACb,WAAO,WAAW,SAAS,uBAAuB;AAAA,EACpD,CAAC;AACH;AAEA,eAAsB,6BACpB,IACA,OAKmC;AACnC,SAAO,MAAM,gBAAgB,IAAI,OAAO,OAAO,IAAI,cAAc;AAC/D,QAAI,UAAU,WAAW,MAAM,OAAQ,QAAO;AAC9C,UAAM,UACJ,MAAM,WAAW,oBACb,CAAC,YAAY,wBAAwB,kBAAkB,IACvD,MAAM,WAAW,qBACf,CAAC,WAAW,IACZ,CAAC,wBAAwB,kBAAkB;AACnD,QAAI,CAAC,aAAa,UAAU,QAAQ,OAAO,EAAG,OAAM,kBAAkB,WAAW,MAAM,MAAM;AAC7F,UAAM,qBAAqB,IAAI,WAAW,KAAK;AAC/C,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,cAAc,MAAM,6BAA6B,IAAI,WAAW,GAAG;AACzE,UAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,MACH,QAAQ,MAAM;AAAA,MACd;AAAA,MACA,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,iBAAiB;AAAA,MACjB,qBACE,UAAU,yBAAyB,aAAa,YAAY;AAAA,MAC9D,0BAA0B;AAAA,MAC1B,0BAA0B;AAAA,MAC1B,qBAAqB;AAAA,MACrB,kBAAkB;AAAA,MAClB,qBAAqB,kBAAkB,MAAM,YAAY;AAAA,MACzD,WAAW,MAAM,eAAe,kBAAkB,MAAM,YAAY,IAAI;AAAA,MACxE,qBAAqB;AAAA,MACrB,yBAAyB;AAAA,MACzB,uBAAuB;AAAA,MACvB,WAAW;AAAA,IACb,CAAC,EACA,MAAM,GAAU,0BAA0B,IAAI,UAAU,EAAE,CAAC,EAC3D,UAAU;AACb,WAAO,WAAW,SAAS,gCAAgC;AAAA,EAC7D,CAAC;AACH;AAWA,eAAsB,2BACpB,IACA,OAIC;AACD,SAAO,MAAM;AAAA,IACX;AAAA,IACA,EAAE,WAAW,MAAM,WAAW,aAAa,MAAM,YAAY;AAAA,IAC7D,OAAO,aACL,MAAM,SAAS,YAAY,OAAO,OAAO;AACvC,YAAM,CAAC,SAAS,IAAI,MAAM,GACvB,OAAO,EACP,KAAY,yBAAyB,EACrC;AAAA,QACC;AAAA,UACE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,UAClE,GAAU,0BAA0B,IAAI,MAAM,WAAW;AAAA,UACzD,GAAU,0BAA0B,eAAe,MAAM,aAAa;AAAA,QACxE;AAAA,MACF,EACC,IAAI,QAAQ,EACZ,MAAM,CAAC;AACV,UAAI,CAAC,UAAW,OAAM,IAAI,6BAA6B,2BAA2B;AAClF,YAAM,CAAC,gBAAgB,IAAI,MAAM,GAC9B,OAAO,EACP,KAAY,uBAAuB,EACnC,MAAM,GAAU,wBAAwB,aAAa,UAAU,EAAE,CAAC,EAClE,MAAM,CAAC;AACV,UAAI,UAAU,WAAW,eAAe,kBAAkB;AACxD,eAAO,EAAE,WAAW,UAAU,iBAAiB;AAAA,MACjD;AACA,UAAI,UAAU,WAAW,YAAa,OAAM,kBAAkB,WAAW,WAAW;AACpF,UAAI,UAAU,mBAAmB,MAAM,QAAQ;AAC7C,cAAM,IAAI,6BAA6B,+CAA+C;AAAA,MACxF;AACA,UAAI,UAAU,uBAAuB,UAAU,gBAAgB;AAC7D,cAAM,IAAI,MAAM,qDAAqD;AAAA,MACvE;AACA,YAAM,MAAM,oBAAI,KAAK;AACrB,YAAM,GAAG,OAAc,KAAK,EAAE,OAAO;AAAA,QACnC,IAAI,MAAM;AAAA,QACV,WAAW,MAAM;AAAA,QACjB,aAAa,MAAM;AAAA,QACnB,QAAQ;AAAA,QACR,UAAU,mBAAmB,UAAU,kBAAkB;AAAA,QACzD,cAAc,mBAAmB,UAAU,kBAAkB;AAAA,QAC7D,aAAa;AAAA,QACb,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM;AAAA,QACd,QAAQ,MAAM;AAAA,QACd,WAAW,MAAM;AAAA,QACjB,WAAW;AAAA,MACb,CAAC;AACD,YAAM,CAAC,QAAQ,IAAI,MAAM,GACtB,OAAc,uBAAuB,EACrC,OAAO;AAAA,QACN,IAAI,UAAU;AAAA,QACd,WAAW,MAAM;AAAA,QACjB,aAAa,MAAM;AAAA,QACnB,eAAe,MAAM;AAAA,QACrB,aAAa,UAAU;AAAA,QACvB,WAAW,UAAU;AAAA,QACrB,QAAQ,UAAU;AAAA,QAClB,WAAW,UAAU;AAAA,QACrB,SAAS,UAAU;AAAA,QACnB,YAAY,UAAU;AAAA,QACtB,cAAc,UAAU;AAAA,QACxB,aAAa;AAAA,QACb,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM;AAAA,QACd,gBAAgB,KAAK,MAAM,MAAM,MAAM,kBAAkB,GAAK;AAAA,QAC9D,OAAO,MAAM,MAAM;AAAA,QACnB,QAAQ,MAAM,MAAM;AAAA,QACpB,UAAU,KAAK,MAAM,MAAM,MAAM,MAAM,GAAK;AAAA,QAC5C,YAAY,MAAM,MAAM;AAAA,QACxB,YAAY,MAAM,MAAM;AAAA,QACxB,UAAU,MAAM,MAAM;AAAA,QACtB,iBAAiB,mBAAmB,UAAU,kBAAkB;AAAA,QAChE,SAAS;AAAA,MACX,CAAC,EACA,UAAU;AACb,UAAI,CAAC,SAAU,OAAM,IAAI,MAAM,4CAA4C;AAC3E,YAAM,GACH,OAAc,8BAA8B,EAC5C,IAAI;AAAA,QACH,eAAe,MAAa,+BAA+B,aAAa,MAAM,UAAU,aAAa;AAAA,QACrG,YAAY,MAAa,+BAA+B,UAAU,MAAM,MAAM,SAAS;AAAA,QACvF,WAAW;AAAA,MACb,CAAC,EACA,MAAM,GAAU,+BAA+B,aAAa,MAAM,WAAW,CAAC;AACjF,YAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,QACH,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,iBAAiB;AAAA,QACjB,qBACE,UAAU,yBAAyB,aAAa,YAAY;AAAA,QAC9D,0BAA0B;AAAA,QAC1B,0BAA0B;AAAA,QAC1B,qBAAqB;AAAA,QACrB,kBAAkB;AAAA,QAClB,qBAAqB;AAAA,QACrB,WAAW;AAAA,QACX,uBAAuB;AAAA,QACvB,qBAAqB;AAAA,QACrB,yBAAyB;AAAA,QACzB,WAAW;AAAA,MACb,CAAC,EACA,MAAM,GAAU,0BAA0B,IAAI,UAAU,EAAE,CAAC,EAC3D,UAAU;AACb,aAAO;AAAA,QACL,WAAW,WAAW,SAAS,+BAA+B;AAAA,QAC9D;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACL;AACF;AAEA,eAAsB,0BACpB,IACA,aACA,YAIQ;AACR,SAAO,MAAM,iBAAiB,IAAI,aAAa,OAAO,aAAa;AACjE,UAAM,CAAC,GAAG,IAAI,MAAM,SACjB,OAAO,EAAE,UAAiB,yBAAyB,MAAa,MAAM,CAAC,EACvE,KAAY,uBAAuB,EACnC,UAAiB,OAAO,GAAU,MAAM,IAAW,wBAAwB,aAAa,CAAC,EACzF;AAAA,MACC;AAAA,QACE,GAAU,wBAAwB,aAAa,WAAW;AAAA,QAC1D,GAAU,wBAAwB,IAAI,UAAU;AAAA,MAClD;AAAA,IACF,EACC,MAAM,CAAC;AACV,WAAO,OAAO;AAAA,EAChB,CAAC;AACH;AAEA,eAAsB,mCACpB,IACA,aACA,WAMA;AACA,SAAO,MAAM;AAAA,IACX;AAAA,IACA;AAAA,IACA,OAAO,aACL,MAAM,SACH,OAAO;AAAA,MACN,UAAiB;AAAA,MACjB,MAAa;AAAA,IACf,CAAC,EACA,KAAY,uBAAuB,EACnC,UAAiB,OAAO,GAAU,MAAM,IAAW,wBAAwB,aAAa,CAAC,EACzF;AAAA,MACC;AAAA,QACE,GAAU,wBAAwB,aAAa,WAAW;AAAA,QAC1D,GAAU,wBAAwB,WAAW,SAAS;AAAA,QACtD,MAAa,wBAAwB,SAAS;AAAA,MAChD;AAAA,IACF,EACC,QAAe,wBAAwB,WAAkB,wBAAwB,EAAE;AAAA,EAC1F;AACF;AAOA,eAAsB,oCACpB,IACA,OAOkB;AAClB,SAAO,MAAM;AAAA,IACX;AAAA,IACA,EAAE,WAAW,MAAM,WAAW,aAAa,MAAM,YAAY;AAAA,IAC7D,OAAO,aAAa;AAClB,YAAM,CAAC,OAAO,IAAI,MAAM,SACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,QACH,kBAAkB;AAAA,QAClB,gBAAgB;AAAA,QAChB,cAAc;AAAA,QACd,WAAW,oBAAI,KAAK;AAAA,MACtB,CAAC,EACA;AAAA,QACC;AAAA,UACE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,UAClE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,UAClE,GAAU,0BAA0B,SAAS,MAAM,OAAO;AAAA,UAC1D,GAAU,0BAA0B,kBAAkB,MAAM,gBAAgB;AAAA,QAC9E;AAAA,MACF,EACC,UAAU;AAAA,QACT,aAAoB,0BAA0B;AAAA,MAChD,CAAC;AACH,UAAI,QAAS,QAAO;AACpB,YAAM,CAAC,QAAQ,IAAI,MAAM,SACtB,OAAO,EAAE,WAAkB,0BAA0B,UAAU,CAAC,EAChE,KAAY,yBAAyB,EACrC;AAAA,QACC;AAAA,UACE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,UAClE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,UAClE,GAAU,0BAA0B,SAAS,MAAM,OAAO;AAAA,QAC5D;AAAA,MACF,EACC,MAAM,CAAC;AACV,aAAO,UAAU,cAAc,QAAQ,UAAU,cAAc;AAAA,IACjE;AAAA,EACF;AACF;AAEA,eAAsB,kCACpB,IACA,OAOkB;AAClB,SAAO,MAAM;AAAA,IACX;AAAA,IACA,EAAE,WAAW,MAAM,WAAW,aAAa,MAAM,YAAY;AAAA,IAC7D,OAAO,aAAa;AAClB,aAAO,MAAM,+CAA+C,UAAU,KAAK;AAAA,IAC7E;AAAA,EACF;AACF;AAEA,eAAsB,+CACpB,IACA,OAMkB;AAClB,QAAM,UACJ,MAAM,UAAU,WACZ,CAAC,WAAW,QAAQ,IACpB,MAAM,UAAU,cACd,CAAC,QAAQ,IACT,CAAC,WAAW,QAAQ;AAC5B,QAAM,CAAC,OAAO,IAAI,MAAM,GACrB,OAAc,yBAAyB,EACvC,IAAI;AAAA,IACH,qBAAqB,MAAM;AAAA,IAC3B,kBAAkB,MAAM,UAAU,eAAe,OAAQ,MAAM,YAAY;AAAA,IAC3E,WAAW,oBAAI,KAAK;AAAA,EACtB,CAAC,EACA;AAAA,IACC;AAAA,MACE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,MAClE,GAAU,0BAA0B,IAAI,MAAM,WAAW;AAAA,MACzD,QAAe,0BAA0B,qBAAqB,OAAO;AAAA,MACrE,GAAI,MAAM,UAAU,eAAe,MAAM,WACrC,CAAC,GAAU,0BAA0B,kBAAkB,MAAM,QAAQ,CAAC,IACtE,CAAC;AAAA,IACP;AAAA,EACF,EACC,UAAU,EAAE,IAAW,0BAA0B,GAAG,CAAC;AACxD,SAAO,YAAY;AACrB;AAEO,SAAS,kCAAkC,OAGxB;AACxB,MAAI,MAAM,UAAU,WAAW,eAAe,MAAM,cAAc;AAChE,WAAO;AAAA,MACL,MAAM;AAAA,MACN,eAAe;AAAA,MACf,QAAQ;AAAA,MACR,aAAa,MAAM,UAAU;AAAA,MAC7B,SAAS,MAAM;AAAA,IACjB;AAAA,EACF;AACA,QAAM,gBAAgB,MAAM,UAAU;AACtC,MACE,CAAC,aAAa,eAAe;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,GACD;AACA,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,aAAa,MAAM,UAAU;AAAA,IAC7B,qBACE,MAAM,UAAU,uBAAuB;AAAA,EAC3C;AACF;AAGA,eAAsB,wCACpB,IACA,WACgC;AAChC,MAAI,UAAU,WAAW,aAAa;AACpC,WAAO,kCAAkC,EAAE,UAAU,CAAC;AAAA,EACxD;AACA,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AACA,MAAI,CAAC,YAAY,SAAS,SAAS,WAAW;AAC5C,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,QAAM,WAAW,wCAAwC;AAAA,IACvD,IAAI,SAAS,SAAS;AAAA,IACtB,aAAa,SAAS,SAAS;AAAA,IAC/B,QAAQ,SAAS,KAAK;AAAA,IACtB,aAAa,SAAS,KAAK;AAAA,IAC3B,WAAW,SAAS,KAAK;AAAA,IACzB,QAAQ,SAAS,KAAK;AAAA,IACtB,WAAW,SAAS,SAAS,QAAQ,YAAY;AAAA,IACjD,OAAO,SAAS,SAAS;AAAA,IACzB,QAAQ,SAAS,SAAS;AAAA,EAC5B,CAAC;AACD,MAAI,CAAC,SAAU,OAAM,IAAI,MAAM,kDAAkD;AACjF,QAAM,UAAU,sBAAsB,MAAM;AAAA,IAC1C,MAAM;AAAA,IACN,eAAe;AAAA,IACf,aAAa,UAAU;AAAA,IACvB;AAAA,IACA,OAAO;AAAA,MACL,iBAAiB,SAAS,SAAS,iBAAiB;AAAA,MACpD,OAAO,SAAS,SAAS;AAAA,MACzB,QAAQ,SAAS,SAAS;AAAA,MAC1B,KAAK,SAAS,SAAS,WAAW;AAAA,MAClC,UAAU,SAAS,SAAS;AAAA,MAC5B,YAAY,SAAS,SAAS;AAAA,MAC9B,YAAY,SAAS,SAAS;AAAA,IAChC;AAAA,IACA,aAAa,+BAA+B,SAAS,SAAS,eAAe;AAAA,EAC/E,CAAC;AACD,SAAO,kCAAkC;AAAA,IACvC;AAAA,IACA,cAAc;AAAA,EAChB,CAAC;AACH;AAEA,eAAsB,mCACpB,IACA,aACA,aAC+E;AAC/E,QAAM,YAAY,MAAM,4BAA4B,IAAI,aAAa,WAAW;AAChF,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,WAAW,aAAa,UAAU,QAAQ;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,IACG,MAAM,wCAAwC,IAAI,SAAS,IAC3D;AACJ,SAAO,gCAAgC,MAAM;AAAA,IAC3C,eAAe;AAAA,IACf,aAAa,UAAU;AAAA,IACvB,SAAS,UAAU;AAAA,IACnB,QAAQ,UAAU,WAAW,yBAAyB,aAAa,UAAU;AAAA,IAC7E,WAAW,UAAU,UAAU,YAAY;AAAA,IAC3C,WAAW,UAAU,UAAU,YAAY;AAAA,IAC3C;AAAA,EACF,CAAC;AACH;AASA,eAAe,gBACb,IACA,OACA,QACY;AACZ,SAAO,MAAM;AAAA,IACX;AAAA,IACA,EAAE,WAAW,MAAM,WAAW,aAAa,MAAM,YAAY;AAAA,IAC7D,OAAO,aACL,MAAM,SAAS,YAAY,OAAO,UAAU;AAC1C,YAAM,KAAK;AACX,YAAM,CAAC,SAAS,IAAI,MAAM,GACvB,OAAO,EACP,KAAY,yBAAyB,EACrC;AAAA,QACC;AAAA,UACE,GAAU,0BAA0B,aAAa,MAAM,WAAW;AAAA,UAClE,GAAU,0BAA0B,IAAI,MAAM,WAAW;AAAA,UACzD,GAAU,0BAA0B,eAAe,MAAM,aAAa;AAAA,QACxE;AAAA,MACF,EACC,IAAI,QAAQ,EACZ,MAAM,CAAC;AACV,UAAI,CAAC,UAAW,OAAM,IAAI,6BAA6B,2BAA2B;AAClF,aAAO,MAAM,OAAO,IAAI,SAAS;AAAA,IACnC,CAAC;AAAA,EACL;AACF;AAEA,eAAe,qBACb,IACA,WACA,OACe;AACf,MAAI,UAAU,eAAe,WAAY;AACzC,QAAM,GACH,OAAc,8BAA8B,EAC5C,IAAI;AAAA,IACH,eAAe,MAAa,+BAA+B,aAAa,MAAM,UAAU,aAAa;AAAA,IACrG,GAAI,QACA;AAAA,MACE,YAAY,MAAa,+BAA+B,UAAU,MAAM,UAAU,aAAa;AAAA,IACjG,IACA,CAAC;AAAA,IACL,WAAW,oBAAI,KAAK;AAAA,EACtB,CAAC,EACA,MAAM,GAAU,+BAA+B,aAAa,UAAU,WAAW,CAAC;AACvF;AAEA,eAAe,4BACb,IACA,WACe;AACf,MAAI,UAAU,oBAAoB,KAAK,UAAU,kBAAkB,oBAAoB;AACrF,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACA,QAAM,GAAG,QAAQ,4CAA4C,UAAU,SAAS,IAAI;AACpF,QAAM,CAAC,UAAU,IAAI,MAAM,GACxB,OAAO;AAAA,IACN,eAAe,mBAAkC,oBAAoB,YAAY;AAAA,EACnF,CAAC,EACA,KAAY,mBAAmB,EAC/B,MAAM,GAAU,oBAAoB,WAAW,UAAU,SAAS,CAAC;AACtE,QAAM,gBAAgB,OAAO,YAAY,iBAAiB,CAAC;AAC3D,MAAI,CAAC,OAAO,cAAc,aAAa,KAAK,gBAAgB,UAAU,kBAAkB;AACtF,UAAM,IAAI,2BAA2B;AAAA,EACvC;AACA,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,WAAW,MAAM,GACpB,OAAc,mBAAmB,EACjC,OAAO;AAAA,IACN,WAAW,UAAU;AAAA,IACrB,aAAa,UAAU;AAAA,IACvB,MAAM;AAAA,IACN,cAAc,CAAC,UAAU;AAAA,IACzB,YAAY;AAAA,IACZ,UAAU,UAAU;AAAA,IACpB,gBAAgB,iCAAiC,UAAU,EAAE;AAAA,IAC7D,UAAU;AAAA,MACR,SAAS,UAAU;AAAA,MACnB,YAAY,UAAU;AAAA,MACtB,kBAAkB,UAAU;AAAA,IAC9B;AAAA,IACA,YAAY;AAAA,EACd,CAAC,EACA,oBAAoB,EAAE,QAAe,oBAAoB,eAAe,CAAC,EACzE,UAAU,EAAE,IAAW,oBAAoB,GAAG,CAAC;AAClD,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,IAAI,6BAA6B,8CAA8C;AAAA,EACvF;AACA,QAAM,GACH,OAAc,WAAW,EACzB,OAAO;AAAA,IACN,WAAW,UAAU;AAAA,IACrB,aAAa,UAAU;AAAA,IACvB,WAAW;AAAA,IACX,UAAU,UAAU;AAAA,IACpB,MAAM;AAAA,IACN,oBAAoB;AAAA,IACpB,kBAAkB,UAAU;AAAA,IAC5B,WAAW,UAAU;AAAA,IACrB,QAAQ,UAAU;AAAA,IAClB,eAAe,UAAU;AAAA,IACzB,gBAAgB,+BAA+B,UAAU,EAAE;AAAA,IAC3D,YAAY;AAAA,EACd,CAAC,EACA,oBAAoB,EAAE,QAAe,YAAY,eAAe,CAAC;AACtE;AAEA,eAAe,6BACb,IACA,WACA,KACkD;AAClD,MAAI,UAAU,gBAAgB,UAAW,QAAO,UAAU;AAC1D,MAAI,UAAU,kBAAkB,sBAAsB,UAAU,oBAAoB,GAAG;AACrF,UAAM,IAAI,MAAM,+DAA+D;AAAA,EACjF;AACA,QAAM,GAAG,QAAQ,4CAA4C,UAAU,SAAS,IAAI;AACpF,QAAM,WAAW,MAAM,GACpB,OAAc,mBAAmB,EACjC,OAAO;AAAA,IACN,WAAW,UAAU;AAAA,IACrB,aAAa,UAAU;AAAA,IACvB,MAAM;AAAA,IACN,cAAc,UAAU;AAAA,IACxB,YAAY;AAAA,IACZ,UAAU,UAAU;AAAA,IACpB,gBAAgB,kCAAkC,UAAU,EAAE;AAAA,IAC9D,UAAU;AAAA,MACR,SAAS,UAAU;AAAA,MACnB,YAAY,UAAU;AAAA,MACtB,kBAAkB,UAAU;AAAA,IAC9B;AAAA,IACA,YAAY;AAAA,EACd,CAAC,EACA,oBAAoB,EAAE,QAAe,oBAAoB,eAAe,CAAC,EACzE,UAAU,EAAE,IAAW,oBAAoB,GAAG,CAAC;AAClD,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,IAAI,6BAA6B,+CAA+C;AAAA,EACxF;AACA,QAAM,GACH,OAAc,WAAW,EACzB,OAAO;AAAA,IACN,WAAW,UAAU;AAAA,IACrB,aAAa,UAAU;AAAA,IACvB,WAAW;AAAA,IACX,UAAU,UAAU;AAAA,IACpB,MAAM;AAAA,IACN,oBAAoB;AAAA,IACpB,kBAAkB,UAAU;AAAA,IAC5B,WAAW,UAAU;AAAA,IACrB,QAAQ,UAAU;AAAA,IAClB,eAAe,UAAU;AAAA,IACzB,gBAAgB,iCAAiC,UAAU,EAAE;AAAA,IAC7D,YAAY;AAAA,EACd,CAAC,EACA,oBAAoB,EAAE,QAAe,YAAY,eAAe,CAAC;AACpE,SAAO;AACT;AAEA,SAAS,cACP,KAC4B;AAC5B,SAAO,sBAAsB;AAAA,IAC3B,MACI;AAAA,MACE,eAAe;AAAA,MACf,UAAU,IAAI;AAAA,MACd,eAAe,IAAI;AAAA,MACnB,iBAAiB,IAAI;AAAA,MACrB,gBAAgB,IAAI;AAAA,IACtB,IACA;AAAA,MACE,eAAe;AAAA,MACf,UAAU;AAAA,MACV,eAAe;AAAA,MACf,iBAAiB,CAAC;AAAA,MAClB,gBAAgB;AAAA,IAClB;AAAA,EACN;AACF;AAEA,SAAS,sBAAsB,UAAmC;AAChE,aAAW,WAAW,UAAU;AAC9B,QAAI,YAAY,yBAAyB,YAAY,iCAAiC;AACpF,YAAM,IAAI,MAAM,mCAAmC,OAAO,EAAE;AAAA,IAC9D;AAAA,EACF;AACF;AAEA,SAAS,uBACP,WACA,OACM;AACN,MACE,UAAU,kBAAkB,MAAM,iBAClC,UAAU,eAAe,MAAM,cAC/B,UAAU,cAAc,MAAM,aAC9B,UAAU,WAAW,MAAM,UAC3B,UAAU,kBAAkB,MAAM,iBAClC,UAAU,qBAAqB,MAAM,kBACrC;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,QAAyB;AACjD,SAAO,aAAa,QAAQ,CAAC,aAAa,YAAY,UAAU,CAAC;AACnE;AAEA,SAAS,aAA+B,OAAe,YAAsC;AAC3F,SAAQ,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAS,kBAAkB,WAAqC,QAAuB;AACrF,SAAO,IAAI;AAAA,IACT,uCAAuC,UAAU,MAAM,OAAO,MAAM;AAAA,EACtE;AACF;AAEA,SAAS,WAAc,OAAsB,QAAmB;AAC9D,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,aAAa,MAAM,EAAE;AACjD,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAuB;AAChD,QAAM,aAAa,MAAM,QAAQ,SAAS,GAAG,EAAE,KAAK;AACpD,UAAQ,cAAc,sCAAsC,MAAM,GAAG,GAAK;AAC5E;AAEA,SAAS,kBAAkB,OAAuB;AAChD,SAAO,MAAM,QAAQ,SAAS,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,IAAK;AAC1D;","names":[]}
@@ -4,11 +4,31 @@ 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"];
11
11
  var NESTED_ERROR_KEYS = ["cause", "original", "driverError", "error", "errors"];
12
+ var RETRYABLE_DATABASE_TRANSPORT_CODES = /* @__PURE__ */ new Set([
13
+ // postgres.js connection lifecycle failures.
14
+ "CONNECTION_CLOSED",
15
+ "CONNECTION_DESTROYED",
16
+ "CONNECTION_ENDED",
17
+ "CONNECT_TIMEOUT",
18
+ // Node socket/DNS failures surfaced unchanged by postgres.js.
19
+ "EAI_AGAIN",
20
+ "ECONNABORTED",
21
+ "ECONNREFUSED",
22
+ "ECONNRESET",
23
+ "EHOSTDOWN",
24
+ "EHOSTUNREACH",
25
+ "ENETDOWN",
26
+ "ENETRESET",
27
+ "ENETUNREACH",
28
+ "ENOTFOUND",
29
+ "EPIPE",
30
+ "ETIMEDOUT"
31
+ ]);
12
32
  var DATABASE_ERROR_NAMES = /* @__PURE__ */ new Set(["DatabaseError", "DrizzleQueryError", "PostgresError"]);
13
33
  var DATABASE_DIAGNOSTIC_KEYS = [
14
34
  "severity",
@@ -52,6 +72,7 @@ function nestedPostgresSqlState(error) {
52
72
  const value = current[key];
53
73
  if (typeof value !== "string" || !/^[0-9A-Z]{5}$/i.test(value)) continue;
54
74
  const normalized = value.toUpperCase();
75
+ if (RETRYABLE_DATABASE_TRANSPORT_CODES.has(normalized)) continue;
55
76
  if (normalized === "40P01" || normalized === "40001") return normalized;
56
77
  fallback ??= normalized;
57
78
  }
@@ -71,8 +92,31 @@ function databaseFailureCode(sqlState) {
71
92
  function isRetryablePersistenceSqlState(sqlState) {
72
93
  return sqlState === "40P01" || sqlState === "40001";
73
94
  }
95
+ function isRetryableDatabaseTransportFailure(error) {
96
+ const queue = [error];
97
+ const seen = /* @__PURE__ */ new Set();
98
+ while (queue.length > 0 && seen.size < 64) {
99
+ const current = queue.shift();
100
+ if (!isRecord(current) || seen.has(current)) continue;
101
+ seen.add(current);
102
+ for (const key of ["code", "errno"]) {
103
+ const value = current[key];
104
+ if (typeof value === "string" && RETRYABLE_DATABASE_TRANSPORT_CODES.has(value.toUpperCase())) {
105
+ return true;
106
+ }
107
+ }
108
+ for (const key of NESTED_ERROR_KEYS) {
109
+ const nested = current[key];
110
+ if (Array.isArray(nested)) queue.push(...nested);
111
+ else if (nested !== void 0) queue.push(nested);
112
+ }
113
+ }
114
+ return false;
115
+ }
74
116
  function isDatabasePersistenceFailure(error) {
75
- if (nestedPostgresSqlState(error) !== null) return true;
117
+ if (isRetryableDatabaseTransportFailure(error) || nestedPostgresSqlState(error) !== null) {
118
+ return true;
119
+ }
76
120
  const queue = [error];
77
121
  const seen = /* @__PURE__ */ new Set();
78
122
  while (queue.length > 0 && seen.size < 64) {
@@ -172,9 +216,22 @@ async function runIdempotentPersistenceTransaction(options, transaction) {
172
216
  }
173
217
 
174
218
  // src/database.ts
219
+ import { AsyncLocalStorage } from "async_hooks";
175
220
  import { eq, sql } from "drizzle-orm";
176
221
  import { drizzle } from "drizzle-orm/postgres-js";
177
222
  import postgres from "postgres";
223
+ var sessionRlsActorContext = new AsyncLocalStorage();
224
+ async function withSessionRlsActorContext(actor, fn) {
225
+ if (!actor.subjectId.trim()) {
226
+ throw new Error("withSessionRlsActorContext: a non-empty subjectId is required");
227
+ }
228
+ if (actor.initiatingHumanSubjectId !== void 0 && actor.initiatingHumanSubjectId !== null && !actor.initiatingHumanSubjectId.trim()) {
229
+ throw new Error(
230
+ "withSessionRlsActorContext: initiatingHumanSubjectId must be null or non-empty"
231
+ );
232
+ }
233
+ return await sessionRlsActorContext.run(actor, fn);
234
+ }
178
235
  var dbBindings = /* @__PURE__ */ new WeakMap();
179
236
  function rlsStrategyFor(db) {
180
237
  return dbBindings.get(db)?.rlsStrategy ?? "force";
@@ -298,7 +355,20 @@ async function setRlsContext(db, context) {
298
355
  sql`select set_config('opengeni.workspace_id', ${context.workspaceId ?? ""}, true)`
299
356
  );
300
357
  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)`);
358
+ await db.execute(sql`select
359
+ set_config('opengeni.sandbox_recovery_protocol_v2', '1', true),
360
+ set_config('opengeni.pending_tool_event_output_v1', '1', true)`);
361
+ const sessionActor = sessionRlsActorContext.getStore();
362
+ if (sessionActor) {
363
+ await setSubjectRlsContext(db, sessionActor.subjectId);
364
+ await db.execute(
365
+ sql`select set_config(
366
+ 'opengeni.initiating_human_subject_id',
367
+ ${sessionActor.initiatingHumanSubjectId ?? ""},
368
+ true
369
+ )`
370
+ );
371
+ }
302
372
  }
303
373
  async function readRlsContextSettings(db) {
304
374
  const [settings] = await rawRows(
@@ -607,11 +677,13 @@ export {
607
677
  nestedPostgresSqlState,
608
678
  databaseFailureCode,
609
679
  isRetryablePersistenceSqlState,
680
+ isRetryableDatabaseTransportFailure,
610
681
  isDatabasePersistenceFailure,
611
682
  safeDatabaseErrorFacts,
612
683
  SessionEventPersistenceError,
613
684
  isSessionEventPersistenceError,
614
685
  runIdempotentPersistenceTransaction,
686
+ withSessionRlsActorContext,
615
687
  rlsStrategyFor,
616
688
  rawRows,
617
689
  SandboxProviderReadLockUnavailableError,
@@ -636,4 +708,4 @@ export {
636
708
  withAccountRls,
637
709
  dbBindingFor
638
710
  };
639
- //# sourceMappingURL=chunk-ISI2TIUG.js.map
711
+ //# sourceMappingURL=chunk-Z7VYMNPZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/persistence-errors.ts","../src/database.ts"],"sourcesContent":["export type DatabaseFailureCode = \"db_deadlock\" | \"db_serialization_failure\" | \"db_failure\";\n\nexport type PersistenceRetryOutcome = \"not_retryable\" | \"exhausted\";\n\nexport type SafeDatabaseErrorFacts = {\n severity?: string;\n schema?: string;\n table?: string;\n column?: string;\n dataType?: string;\n constraint?: string;\n routine?: string;\n};\n\nexport type PersistenceFailureDetails = {\n code: DatabaseFailureCode;\n sqlState: string | null;\n stage: string;\n eventTypes: string[];\n correlationId: string;\n attempts: number;\n retryOutcome: PersistenceRetryOutcome;\n database: SafeDatabaseErrorFacts;\n};\n\nconst SQLSTATE_KEYS = [\"sqlState\", \"sqlstate\", \"code\"] as const;\nconst NESTED_ERROR_KEYS = [\"cause\", \"original\", \"driverError\", \"error\", \"errors\"] as const;\nconst RETRYABLE_DATABASE_TRANSPORT_CODES = new Set([\n // postgres.js connection lifecycle failures.\n \"CONNECTION_CLOSED\",\n \"CONNECTION_DESTROYED\",\n \"CONNECTION_ENDED\",\n \"CONNECT_TIMEOUT\",\n // Node socket/DNS failures surfaced unchanged by postgres.js.\n \"EAI_AGAIN\",\n \"ECONNABORTED\",\n \"ECONNREFUSED\",\n \"ECONNRESET\",\n \"EHOSTDOWN\",\n \"EHOSTUNREACH\",\n \"ENETDOWN\",\n \"ENETRESET\",\n \"ENETUNREACH\",\n \"ENOTFOUND\",\n \"EPIPE\",\n \"ETIMEDOUT\",\n]);\nconst DATABASE_ERROR_NAMES = new Set([\"DatabaseError\", \"DrizzleQueryError\", \"PostgresError\"]);\nconst DATABASE_DIAGNOSTIC_KEYS = [\n \"severity\",\n \"schema_name\",\n \"table_name\",\n \"column_name\",\n \"data_type_name\",\n \"constraint_name\",\n \"routine\",\n] as const;\nconst SAFE_FACT_KEYS = [\n [\"severity\", \"severity\"],\n [\"schema_name\", \"schema\"],\n [\"schema\", \"schema\"],\n [\"table_name\", \"table\"],\n [\"table\", \"table\"],\n [\"column_name\", \"column\"],\n [\"column\", \"column\"],\n [\"data_type_name\", \"dataType\"],\n [\"dataType\", \"dataType\"],\n [\"constraint_name\", \"constraint\"],\n [\"constraint\", \"constraint\"],\n [\"routine\", \"routine\"],\n] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === \"object\");\n}\n\nfunction safeFact(value: unknown): string | undefined {\n if (typeof value !== \"string\" || value.length === 0) return undefined;\n return value;\n}\n\n/** Find the driver SQLSTATE even when Drizzle wrapped it under nested causes. */\nexport function nestedPostgresSqlState(error: unknown): string | null {\n const queue: unknown[] = [error];\n const seen = new Set<unknown>();\n let fallback: string | null = null;\n while (queue.length > 0 && seen.size < 64) {\n const current = queue.shift();\n if (!isRecord(current) || seen.has(current)) continue;\n seen.add(current);\n for (const key of SQLSTATE_KEYS) {\n const value = current[key];\n if (typeof value !== \"string\" || !/^[0-9A-Z]{5}$/i.test(value)) continue;\n const normalized = value.toUpperCase();\n // Node transport codes such as EPIPE happen to be five characters but\n // are not PostgreSQL SQLSTATEs.\n if (RETRYABLE_DATABASE_TRANSPORT_CODES.has(normalized)) continue;\n if (normalized === \"40P01\" || normalized === \"40001\") return normalized;\n fallback ??= normalized;\n }\n for (const key of NESTED_ERROR_KEYS) {\n const nested = current[key];\n if (Array.isArray(nested)) queue.push(...nested);\n else if (nested !== undefined) queue.push(nested);\n }\n }\n return fallback;\n}\n\nexport function databaseFailureCode(sqlState: string | null): DatabaseFailureCode {\n if (sqlState === \"40P01\") return \"db_deadlock\";\n if (sqlState === \"40001\") return \"db_serialization_failure\";\n return \"db_failure\";\n}\n\nexport function isRetryablePersistenceSqlState(sqlState: string | null): boolean {\n return sqlState === \"40P01\" || sqlState === \"40001\";\n}\n\n/**\n * Recognize only explicit postgres.js/Node transport codes, including nested\n * driver causes. These failures can arrive as plain Errors with no SQLSTATE or\n * database diagnostic fields when the connection dies before PostgreSQL can\n * answer. Messages are intentionally ignored: they are unstable and may\n * contain connection detail.\n */\nexport function isRetryableDatabaseTransportFailure(error: unknown): boolean {\n const queue: unknown[] = [error];\n const seen = new Set<unknown>();\n while (queue.length > 0 && seen.size < 64) {\n const current = queue.shift();\n if (!isRecord(current) || seen.has(current)) continue;\n seen.add(current);\n\n for (const key of [\"code\", \"errno\"] as const) {\n const value = current[key];\n if (\n typeof value === \"string\" &&\n RETRYABLE_DATABASE_TRANSPORT_CODES.has(value.toUpperCase())\n ) {\n return true;\n }\n }\n\n for (const key of NESTED_ERROR_KEYS) {\n const nested = current[key];\n if (Array.isArray(nested)) queue.push(...nested);\n else if (nested !== undefined) queue.push(nested);\n }\n }\n return false;\n}\n\n/**\n * Distinguish database/ORM failures from expected domain exceptions when a\n * driver omitted SQLSTATE. This checks shape only; callers retain the original\n * failure independently as canonical error evidence.\n */\nexport function isDatabasePersistenceFailure(error: unknown): boolean {\n if (isRetryableDatabaseTransportFailure(error) || nestedPostgresSqlState(error) !== null) {\n return true;\n }\n\n const queue: unknown[] = [error];\n const seen = new Set<unknown>();\n while (queue.length > 0 && seen.size < 64) {\n const current = queue.shift();\n if (!isRecord(current) || seen.has(current)) continue;\n seen.add(current);\n\n if (typeof current.name === \"string\" && DATABASE_ERROR_NAMES.has(current.name)) {\n return true;\n }\n if (\n typeof current.query === \"string\" &&\n (Object.hasOwn(current, \"params\") || Object.hasOwn(current, \"parameters\"))\n ) {\n return true;\n }\n if (DATABASE_DIAGNOSTIC_KEYS.some((key) => Object.hasOwn(current, key))) {\n return true;\n }\n\n for (const key of NESTED_ERROR_KEYS) {\n const nested = current[key];\n if (Array.isArray(nested)) queue.push(...nested);\n else if (nested !== undefined) queue.push(nested);\n }\n }\n return false;\n}\n\n/** Extract only PostgreSQL diagnostic identifiers; never query text/parameters. */\nexport function safeDatabaseErrorFacts(error: unknown): SafeDatabaseErrorFacts {\n const queue: unknown[] = [error];\n const seen = new Set<unknown>();\n const facts: SafeDatabaseErrorFacts = {};\n while (queue.length > 0 && seen.size < 64) {\n const current = queue.shift();\n if (!isRecord(current) || seen.has(current)) continue;\n seen.add(current);\n for (const [source, destination] of SAFE_FACT_KEYS) {\n if (facts[destination] !== undefined) continue;\n const value = safeFact(current[source]);\n if (value !== undefined) facts[destination] = value;\n }\n for (const key of NESTED_ERROR_KEYS) {\n const nested = current[key];\n if (Array.isArray(nested)) queue.push(...nested);\n else if (nested !== undefined) queue.push(nested);\n }\n }\n return facts;\n}\n\n/**\n * Typed persistence classification that retains the exact original failure as\n * `cause` for internal diagnostics. The ordinary Error message is deliberately\n * stable and source-free so a generic presentation path can never disclose SQL,\n * parameters, or driver detail by rendering `.message`.\n */\nexport class SessionEventPersistenceError extends Error {\n readonly name = \"SessionEventPersistenceError\";\n\n constructor(\n readonly details: PersistenceFailureDetails,\n cause?: unknown,\n ) {\n const label =\n details.code === \"db_deadlock\"\n ? \"Database deadlock\"\n : details.code === \"db_serialization_failure\"\n ? \"Database serialization failure\"\n : \"Database failure\";\n const operation = `${label} while persisting ${details.eventTypes.join(\", \") || \"session events\"}`;\n super(operation, cause === undefined ? undefined : { cause });\n }\n\n get code(): DatabaseFailureCode {\n return this.details.code;\n }\n}\n\nexport function isSessionEventPersistenceError(\n error: unknown,\n): error is SessionEventPersistenceError {\n return error instanceof SessionEventPersistenceError;\n}\n\nexport type IdempotentPersistenceTransactionOptions = {\n stage: string;\n eventTypes?: string[];\n maxAttempts?: number;\n correlationId?: string;\n onRetry?: (input: { attempt: number; sqlState: \"40P01\" | \"40001\" }) => void | Promise<void>;\n};\n\n/**\n * Retry only the supplied idempotent database transaction/savepoint. Provider\n * inference, tools, NATS, and all other external effects must remain outside\n * this function. A single correlation ID follows every persistence attempt.\n */\nexport async function runIdempotentPersistenceTransaction<T>(\n options: IdempotentPersistenceTransactionOptions,\n transaction: (attempt: number) => Promise<T>,\n): Promise<T> {\n const maxAttempts = options.maxAttempts ?? 3;\n if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {\n throw new Error(\"Persistence maxAttempts must be a positive integer\");\n }\n const correlationId = options.correlationId ?? crypto.randomUUID();\n const eventTypes = [...new Set(options.eventTypes ?? [])].sort();\n for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {\n try {\n return await transaction(attempt);\n } catch (error) {\n const sqlState = nestedPostgresSqlState(error);\n const retryable = isRetryablePersistenceSqlState(sqlState);\n if (retryable && attempt < maxAttempts) {\n await options.onRetry?.({\n attempt,\n sqlState: sqlState as \"40P01\" | \"40001\",\n });\n continue;\n }\n if (!isDatabasePersistenceFailure(error)) throw error;\n throw new SessionEventPersistenceError(\n {\n code: databaseFailureCode(sqlState),\n sqlState,\n stage: options.stage,\n eventTypes,\n correlationId,\n attempts: attempt,\n retryOutcome: retryable ? \"exhausted\" : \"not_retryable\",\n database: safeDatabaseErrorFacts(error),\n },\n error,\n );\n }\n }\n throw new Error(\"Unreachable persistence retry state\");\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { eq, sql, type SQL } from \"drizzle-orm\";\nimport type { PgDatabase, PgTransactionConfig } from \"drizzle-orm/pg-core\";\nimport { drizzle } from \"drizzle-orm/postgres-js\";\nimport postgres from \"postgres\";\n\nimport {\n runIdempotentPersistenceTransaction,\n type IdempotentPersistenceTransactionOptions,\n} from \"./persistence-errors\";\nimport { LOSSLESS_CONTENT_WRITER_APPLICATION_NAME } from \"./lossless-json\";\nimport * as schema from \"./schema\";\n\n// §7.7 driver widening (Step I). `Database` is the structural, cross-driver\n// query-layer port: every helper in this file accepts `db: Database` and uses\n// only the methods present on drizzle's base `PgDatabase` (select/insert/update/\n// delete/transaction/execute). Widening from the concrete\n// `PostgresJsDatabase<typeof schema>` to `PgDatabase<any, typeof schema>` is a\n// pure TYPE change — no runtime behavior changes — that lets an embedded host\n// inject ANY drizzle pg driver handle (node-postgres, neon-http, etc.) bound to\n// OpenGeni's schema, not just the postgres-js handle `createDb` builds. The\n// `any` for the query-result HKT is deliberate: it keeps `db.execute(sql\\`…\\`)`\n// callable across drivers whose raw-result shapes differ (postgres-js returns a\n// row array; node-postgres returns `{ rows }`). The three raw `db.execute(…)`\n// reads that index a row array (`getManagedUserByEmail` here is the only\n// host-facing one — see `userLookup`) stay postgres-js-shaped for standalone;\n// `userLookup` is the injection seam for hosts on a different driver.\n// `PostgresJsDatabase<typeof schema>` is assignable to this, so standalone is\n// unaffected.\n\nexport type Database = PgDatabase<any, typeof schema>;\n\ndeclare const sessionActivityDatabaseBrand: unique symbol;\n\n/**\n * A workspace-scoped transaction whose session activity commit gate is open.\n * Session-row writers accept this narrower handle so new call sites cannot\n * accidentally bypass the once-per-transaction revision finalizer.\n */\nexport type SessionActivityDatabase = Database & {\n readonly [sessionActivityDatabaseBrand]: true;\n};\n\nexport type DbClient = {\n db: Database;\n close: () => Promise<void>;\n};\n\nexport type RlsContext = {\n accountId: string;\n workspaceId?: string | null;\n};\n\nexport type SessionRlsActorContext = {\n subjectId: string;\n initiatingHumanSubjectId?: string | null;\n};\n\nconst sessionRlsActorContext = new AsyncLocalStorage<SessionRlsActorContext>();\n\nexport async function withSessionRlsActorContext<T>(\n actor: SessionRlsActorContext,\n fn: () => Promise<T>,\n): Promise<T> {\n if (!actor.subjectId.trim()) {\n throw new Error(\"withSessionRlsActorContext: a non-empty subjectId is required\");\n }\n if (\n actor.initiatingHumanSubjectId !== undefined &&\n actor.initiatingHumanSubjectId !== null &&\n !actor.initiatingHumanSubjectId.trim()\n ) {\n throw new Error(\n \"withSessionRlsActorContext: initiatingHumanSubjectId must be null or non-empty\",\n );\n }\n return await sessionRlsActorContext.run(actor, fn);\n}\n\ntype RlsContextSettings = {\n accountId: string;\n workspaceId: string;\n};\n\n/**\n * RLS posture for the connection OpenGeni's query layer runs over (Step I, §7.7).\n *\n * - `\"force\"` (DEFAULT — today's standalone behavior, byte-for-byte): OpenGeni\n * connects as a NON-OWNER role (`opengeni_app`) and every table carries\n * `FORCE ROW LEVEL SECURITY`, so the workspace/account GUCs set by\n * `setRlsContext` are the ONLY thing that admits rows — even the table owner\n * is subject to RLS. This is the Fork-A isolation guarantee.\n * - `\"scoped\"` (embedded Fork-B opt-in): the host runs OpenGeni's queries over a\n * role that OWNS the dedicated schema (RLS need not be forced for that role),\n * relying on the host's own tenant boundary. OpenGeni STILL emits the\n * `set_config('opengeni.account_id'/'workspace_id', …)` GUCs defensively on\n * every scoped query, so the application query path is byte-identical between\n * the two strategies and the app code is RLS-mode-agnostic. The strategy is a\n * declared posture (consumed by `provisionRoles` and as a documented\n * invariant), NOT a query-path branch — there is deliberately no `if\n * (strategy === …)` anywhere in the helpers below. Picking `\"scoped\"` does not\n * relax any GUC; it only changes which DB role the host provisions/connects as\n * and asserts that the host accepts owning the isolation boundary.\n */\nexport type RlsStrategy = \"force\" | \"scoped\";\n\n/**\n * Resolve a host-IdP/Better-Auth user *identifier* by email. Injected via\n * `createDb({ userLookup })` (Step I). UNSET → today's raw parameterized select\n * against Better Auth's `auth_users` table (see `getManagedUserByEmail`), which\n * relies on the postgres-js array-shaped `db.execute` result. An embedded host\n * whose identity lives elsewhere (a different IdP table, a different driver, or\n * a non-`auth_users` user store) injects this closure so OpenGeni never touches\n * `auth_users` directly. Returns the user id, or null when no such user exists.\n */\nexport type UserLookup = (db: Database, email: string) => Promise<string | null>;\n\nexport type CreateDbOptions = {\n /**\n * The Postgres `search_path` for this connection (Step I, §7.8 runtime half).\n * UNSET → today's behavior: NO `search_path` startup parameter is sent, so the\n * server default applies (`public` for standalone, where every table + the\n * `vector` extension + `gen_random_uuid()` live). For an embedded dedicated\n * schema, pass e.g. `\"opengeni,opengeni_private,public\"` — postgres-js sends\n * it as a per-session startup parameter (the supported, query-param-free way;\n * URL `?search_path=` is IGNORED by postgres-js). Keep `public` LAST so the\n * `vector` type and `gen_random_uuid()` (which live in `public` on the\n * pgvector image) still resolve — the schema-isolation contract live footgun.\n */\n searchPath?: string;\n /** RLS posture; defaults to `\"force\"` (today's standalone). */\n rlsStrategy?: RlsStrategy;\n /** Host-provided user-by-email resolver; unset → today's raw `auth_users` query. */\n userLookup?: UserLookup;\n /** postgres-js pool size; defaults to today's `10`. */\n max?: number;\n /**\n * Connection-local default transaction isolation sent in the postgres-js\n * startup parameters. This is intentionally not a role/database default:\n * tests and embedded callers can exercise a different ambient isolation\n * without mutating a shared PostgreSQL role or affecting other connections.\n */\n isolationLevel?: postgres.ConnectionParameters[\"default_transaction_isolation\"];\n};\n\n/**\n * The active RLS strategy + userLookup for an injected `Database`, recorded in a\n * side WeakMap so helpers (and `getManagedUserByEmail`) can consult the host's\n * binding without changing every call signature. A handle with no recorded\n * config (e.g. one built outside `createDb`, or in a test) falls back to the\n * standalone defaults: `rlsStrategy: \"force\"`, raw `auth_users` lookup.\n */\ntype DbBinding = { rlsStrategy: RlsStrategy; userLookup?: UserLookup };\n\nconst dbBindings = new WeakMap<object, DbBinding>();\n\n/** The strategy bound to a handle (or the `\"force\"` default). */\nexport function rlsStrategyFor(db: Database): RlsStrategy {\n return dbBindings.get(db as unknown as object)?.rlsStrategy ?? \"force\";\n}\n\n/**\n * Run a raw SQL query and read its rows as a typed array.\n *\n * Why this exists: the Step I driver widening (`Database = PgDatabase<any, …>`)\n * deliberately sets the query-result HKT to `any` so `db.execute(…)` is callable\n * across drivers whose raw-result shapes differ (postgres-js → row array;\n * node-postgres → `{ rows }`). A side effect is that `db.execute<T>(…)` now\n * resolves to `any`, erasing the per-row element type at the call site. OpenGeni's\n * OWN internal raw queries usually run over the postgres-js handle `createDb`\n * builds (array result), while an embedded host may inject a node-postgres style\n * driver (`{ rows }`). Normalize those two standard shapes in one place; reject\n * an unknown driver result rather than silently treating it as an empty query.\n */\nexport async function rawRows<T extends Record<string, unknown>>(\n executor: Pick<Database, \"execute\">,\n query: SQL,\n): Promise<T[]> {\n const result = await executor.execute<T>(query);\n if (Array.isArray(result)) {\n return result as unknown as T[];\n }\n const rows = (result as unknown as { rows?: unknown }).rows;\n if (Array.isArray(rows)) {\n return rows as T[];\n }\n throw new Error(\"Unsupported database execute() result shape\");\n}\n\nexport type SandboxProviderReadLockIdentity = {\n workspaceId: string;\n sandboxGroupId: string;\n leaseEpoch: number;\n instanceId: string;\n};\n\nexport class SandboxProviderReadLockUnavailableError extends Error {\n constructor() {\n super(\"Sandbox provider reads are temporarily busy. Retry the request.\");\n this.name = \"SandboxProviderReadLockUnavailableError\";\n }\n}\n\nconst SANDBOX_PROVIDER_READ_LOCK_WAIT_MS = 15_000;\nconst SANDBOX_PROVIDER_READ_LOCK_POLL_MAX_MS = 200;\n\nfunction sandboxProviderReadLockKey(identity: SandboxProviderReadLockIdentity): string {\n return [\n \"sandbox-provider-read\",\n identity.workspaceId,\n identity.sandboxGroupId,\n identity.leaseEpoch,\n identity.instanceId,\n ].join(\":\");\n}\n\nasync function waitForSandboxProviderReadLockPoll(\n delayMs: number,\n signal?: AbortSignal | undefined,\n): Promise<void> {\n if (signal?.aborted) {\n throw signal.reason ?? new DOMException(\"The operation was aborted\", \"AbortError\");\n }\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout>;\n const cleanup = () => signal?.removeEventListener(\"abort\", abort);\n const finish = () => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve();\n };\n const abort = () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n cleanup();\n reject(signal?.reason ?? new DOMException(\"The operation was aborted\", \"AbortError\"));\n };\n timer = setTimeout(finish, delayMs);\n signal?.addEventListener(\"abort\", abort, { once: true });\n if (signal?.aborted) abort();\n });\n}\n\n/**\n * Cross-process exclusive boundary for one exact live provider instance's\n * API-direct read request. Modal accepts concurrent commands from one attached\n * handle, but independent API replicas reconstruct different handles; issuing\n * overlapping command groups through those handles can make an otherwise valid\n * read fail transiently. Keep concurrency inside one batched request while\n * serializing only separate requests that target the same lease identity.\n *\n * The callback intentionally runs while one transaction-pinned DB connection\n * holds the advisory lock. The direct lease holder separately prevents drain,\n * and the abort-aware bounded poll prevents a disconnected HTTP request from\n * occupying the connection indefinitely.\n */\nexport async function withSandboxProviderReadLock<T>(\n db: Database,\n identity: SandboxProviderReadLockIdentity,\n signal: AbortSignal | undefined,\n fn: () => Promise<T>,\n): Promise<T> {\n const key = sandboxProviderReadLockKey(identity);\n const deadline = Date.now() + SANDBOX_PROVIDER_READ_LOCK_WAIT_MS;\n return await db.transaction(async (lockedDb) => {\n let pollMs = 20;\n while (true) {\n if (signal?.aborted) {\n throw signal.reason ?? new DOMException(\"The operation was aborted\", \"AbortError\");\n }\n const [row] = await rawRows<{ acquired: boolean }>(\n lockedDb,\n sql`select pg_try_advisory_xact_lock(hashtextextended(${key}, 0)) as acquired`,\n );\n if (row?.acquired === true) return await fn();\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) throw new SandboxProviderReadLockUnavailableError();\n await waitForSandboxProviderReadLockPoll(Math.min(pollMs, remainingMs), signal);\n pollMs = Math.min(pollMs * 2, SANDBOX_PROVIDER_READ_LOCK_POLL_MAX_MS);\n }\n });\n}\n\nexport function createDb(databaseUrl: string, options: CreateDbOptions = {}): DbClient {\n // `prepare: false` is REQUIRED for Azure Database for PostgreSQL Flexible\n // Server's transaction-pooling PgBouncer: postgres-js's default named prepared\n // statements (`s_N`) are bound to one backend, but a transaction pooler hands\n // each transaction a different backend, so a later `execute` intermittently\n // throws `prepared statement \"s_N\" does not exist`. Every RLS read in this\n // module (set_config + SELECT inside one db.transaction) rides on this pool, so\n // the failure surfaces as a \"worked, then didn't\" credential/permission read.\n // idle_timeout + max_lifetime recycle connections so a pooler-recycled backend\n // is never reused indefinitely; application_name aids server-side diagnostics.\n const client = postgres(databaseUrl, {\n max: options.max ?? 10,\n prepare: false,\n idle_timeout: 30,\n max_lifetime: 1800,\n // `connection` carries per-session Postgres STARTUP parameters. `application_name`\n // (always) aids server-side diagnostics; `search_path` (embedded only) is the\n // supported, query-param-free way to scope a connection to a dedicated schema —\n // postgres-js IGNORES a URL `?search_path=`. Unset searchPath → omit it so the\n // server default (`public`) is unchanged for standalone.\n connection: {\n application_name: LOSSLESS_CONTENT_WRITER_APPLICATION_NAME,\n ...(options.searchPath ? { search_path: options.searchPath } : {}),\n ...(options.isolationLevel ? { default_transaction_isolation: options.isolationLevel } : {}),\n },\n });\n const db = drizzle(client, { schema });\n dbBindings.set(db as unknown as object, {\n rlsStrategy: options.rlsStrategy ?? \"force\",\n ...(options.userLookup ? { userLookup: options.userLookup } : {}),\n });\n return {\n db,\n close: async () => {\n await client.end();\n },\n };\n}\n\n/**\n * Register a host's `rlsStrategy`/`userLookup` against an externally-constructed\n * `Database` handle (e.g. one the embedded host built from its own driver and\n * injected, rather than via `createDb`). Lets the same WeakMap-backed lookups\n * work for injected handles. Standalone never calls this (it uses `createDb`).\n */\nexport function registerDbBinding(\n db: Database,\n binding: { rlsStrategy?: RlsStrategy; userLookup?: UserLookup },\n): void {\n dbBindings.set(db as unknown as object, {\n rlsStrategy: binding.rlsStrategy ?? \"force\",\n ...(binding.userLookup ? { userLookup: binding.userLookup } : {}),\n });\n}\n\nexport async function setRlsContext(db: Database, context: RlsContext): Promise<void> {\n // Fail loud on an empty/blank account id: a \"\" account would set an RLS GUC\n // that matches no tenant row, silently returning zero rows from every scoped\n // read (a phantom \"not found\" / \"no active subscription\"). An RLS context with\n // no account is always a bug at the call site, never a valid query scope.\n if (typeof context.accountId !== \"string\" || context.accountId.trim() === \"\") {\n throw new Error(\"setRlsContext: a non-empty accountId is required to establish an RLS context\");\n }\n await db.execute(sql`select set_config('opengeni.account_id', ${context.accountId}, true)`);\n await db.execute(\n sql`select set_config('opengeni.workspace_id', ${context.workspaceId ?? \"\"}, true)`,\n );\n // Transaction-local writer identity covers supported injected/embedded\n // database handles whose connection-level application_name is host-owned.\n // Old OpenGeni binaries do not set this GUC, so migration-installed update\n // fences can distinguish their partial writes without inspecting content.\n await db.execute(sql`select set_config('opengeni.lossless_content_writer', '1', true)`);\n await db.execute(sql`select\n set_config('opengeni.sandbox_recovery_protocol_v2', '1', true),\n set_config('opengeni.pending_tool_event_output_v1', '1', true)`);\n const sessionActor = sessionRlsActorContext.getStore();\n if (sessionActor) {\n await setSubjectRlsContext(db, sessionActor.subjectId);\n await db.execute(\n sql`select set_config(\n 'opengeni.initiating_human_subject_id',\n ${sessionActor.initiatingHumanSubjectId ?? \"\"},\n true\n )`,\n );\n }\n}\n\nasync function readRlsContextSettings(db: Database): Promise<RlsContextSettings> {\n const [settings] = await rawRows<{\n account_id: string | null;\n workspace_id: string | null;\n }>(\n db,\n sql`select\n current_setting('opengeni.account_id', true) as account_id,\n current_setting('opengeni.workspace_id', true) as workspace_id`,\n );\n return {\n accountId: settings?.account_id ?? \"\",\n workspaceId: settings?.workspace_id ?? \"\",\n };\n}\n\nasync function assertRlsContextApplied(db: Database, context: RlsContext): Promise<void> {\n const applied = await readRlsContextSettings(db);\n const expectedWorkspaceId = context.workspaceId ?? \"\";\n if (applied.accountId !== context.accountId) {\n throw new Error(\n `RLS context not applied on the active backend: expected account ${context.accountId}, got \"${applied.accountId}\"`,\n );\n }\n if (applied.workspaceId !== expectedWorkspaceId) {\n throw new Error(\n `RLS context not applied on the active backend: expected workspace \"${expectedWorkspaceId}\", got \"${applied.workspaceId}\"`,\n );\n }\n}\n\nasync function restoreRlsContextSettings(\n db: Database,\n settings: RlsContextSettings,\n): Promise<void> {\n const [restored] = await rawRows<{\n account_id: string;\n workspace_id: string;\n }>(\n db,\n sql`select\n set_config('opengeni.account_id', ${settings.accountId}, true) as account_id,\n set_config('opengeni.workspace_id', ${settings.workspaceId}, true) as workspace_id`,\n );\n if (\n restored?.account_id !== settings.accountId ||\n restored.workspace_id !== settings.workspaceId\n ) {\n throw new Error(\"RLS context could not be restored after a nested scope\");\n }\n}\n\nexport async function withRlsContext<T>(\n db: Database,\n context: RlsContext,\n fn: (db: Database) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n): Promise<T> {\n const restoreParentScope = isTransactionHandle(db);\n return await db.transaction(async (tx) => {\n const scoped = tx as unknown as Database;\n const parentScope = restoreParentScope ? await readRlsContextSettings(scoped) : null;\n await setRlsContext(scoped, context);\n // Defense-in-depth: read the LOCAL GUC back on THIS backend BEFORE running\n // the scoped query. The set_config and this read share one db.transaction,\n // which a transaction pooler pins to a single backend — so a mismatch here\n // means the context was genuinely lost (a torn transaction / pooler backend\n // swap), not normal operation. Without this guard such an event runs the\n // scoped read with an empty account_id and returns zero RLS-visible rows,\n // manufacturing a phantom \"no active subscription\" from a credential that is\n // in fact active. Convert that silent false into a loud, root-cause-bearing\n // error so the caller can retry rather than permanently mis-decide.\n await assertRlsContextApplied(scoped, context);\n const value = await fn(scoped);\n // A nested transaction is a savepoint, and SET LOCAL survives successful\n // savepoint release. Restore only the tenant scope the nested helper owns;\n // writer/protocol capabilities intentionally remain transaction-wide.\n if (parentScope) await restoreRlsContextSettings(scoped, parentScope);\n return value;\n }, transactionConfig);\n}\n\n/**\n * Run one bounded database operation on a transaction-pinned backend.\n *\n * Callers that also have an application deadline should check their abort\n * signal before returning from `fn`; throwing there rolls the transaction back\n * even when the application deadline won a surrounding Promise race.\n */\nexport async function withDatabaseStatementTimeout<T>(\n db: Database,\n timeoutMs: number,\n fn: (db: Database) => Promise<T>,\n): Promise<T> {\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new Error(\"withDatabaseStatementTimeout requires a positive timeout\");\n }\n const boundedTimeoutMs = Math.max(1, Math.floor(timeoutMs));\n return await db.transaction(async (tx) => {\n const scoped = tx as unknown as Database;\n await scoped.execute(\n sql`select set_config('statement_timeout', ${`${boundedTimeoutMs}ms`}, true)`,\n );\n return await fn(scoped);\n });\n}\n\nexport async function rlsContextForWorkspace(\n db: Database,\n workspaceId: string,\n): Promise<RlsContext> {\n const [row] = await db\n .select({ accountId: schema.workspaces.accountId })\n .from(schema.workspaces)\n .where(eq(schema.workspaces.id, workspaceId))\n .limit(1);\n if (!row) {\n throw new Error(`Workspace not found: ${workspaceId}`);\n }\n return { accountId: row.accountId, workspaceId };\n}\n\nexport async function withWorkspaceRls<T>(\n db: Database,\n workspaceId: string,\n fn: (db: Database) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n): Promise<T> {\n return await withRlsContext(\n db,\n await rlsContextForWorkspace(db, workspaceId),\n fn,\n transactionConfig,\n );\n}\n\ntype SessionActivityGate = {\n db: SessionActivityDatabase;\n owner: boolean;\n};\n\nfunction isTransactionHandle(db: Database): boolean {\n return typeof (db as Database & { rollback?: unknown }).rollback === \"function\";\n}\n\nasync function assertSessionActivityGateEntry(db: Database): Promise<void> {\n if (!isTransactionHandle(db)) return;\n const [gate] = await rawRows<{ state: string | null }>(\n db,\n sql`\n select nullif(\n current_setting('opengeni.session_activity_gate_state', true),\n ''\n ) as state\n `,\n );\n if (gate?.state === null || gate === undefined) {\n throw new Error(\"Session activity commit gate must start at the outer transaction boundary\");\n }\n}\n\nasync function beginSessionActivityGate(\n db: Database,\n workspaceId: string,\n): Promise<SessionActivityGate> {\n const [gate] = await rawRows<{\n prior_state: string | null;\n prior_workspace_id: string | null;\n }>(\n db,\n sql`\n with current_gate as materialized (\n select\n nullif(current_setting('opengeni.session_activity_gate_state', true), '') as prior_state,\n nullif(current_setting('opengeni.session_activity_gate_workspace_id', true), '') as prior_workspace_id\n )\n select\n prior_state,\n prior_workspace_id,\n case\n when prior_state is null\n then set_config('opengeni.session_activity_gate_state', 'open', true)\n else prior_state\n end as effective_state,\n case\n when prior_state is null\n then set_config('opengeni.session_activity_gate_workspace_id', ${workspaceId}, true)\n else prior_workspace_id\n end as effective_workspace_id\n from current_gate\n `,\n );\n if (!gate) {\n throw new Error(\"Session activity commit gate could not be opened\");\n }\n if (gate.prior_state === null) {\n return { db: db as SessionActivityDatabase, owner: true };\n }\n if (gate.prior_state === \"open\" && gate.prior_workspace_id === workspaceId) {\n return { db: db as SessionActivityDatabase, owner: false };\n }\n throw new Error(\"Session activity commit gate is already owned by another transaction scope\");\n}\n\nasync function finalizeSessionActivityGate(\n db: SessionActivityDatabase,\n workspaceId: string,\n): Promise<void> {\n // Resolve every deferred FK/constraint before taking the shared workspace\n // counter. The only row writes after that point stamp session rows already\n // modified and therefore already owned by this transaction.\n await db.execute(\n sql`select set_config('opengeni.session_activity_gate_state', 'preparing', true)`,\n );\n await db.execute(sql`set constraints all immediate`);\n // The first flush proves every pre-existing deferred obligation. Re-defer\n // only our commit guard so the marker-clearing writes below queue a fresh\n // proof against the final row state, then force that proof before returning.\n await db.execute(\n sql`set constraints sessions_activity_insert_commit_guard, sessions_activity_update_commit_guard deferred`,\n );\n const [result] = await rawRows<{\n had_pending: boolean;\n pending_count: number;\n revision: string | null;\n stamped_count: number;\n }>(\n db,\n sql`\n with gate as materialized (\n select set_config('opengeni.session_activity_gate_state', 'finalizing', true) as state\n ),\n pending as materialized (\n select ${schema.sessions.id}\n from ${schema.sessions}\n cross join gate\n where ${schema.sessions.workspaceId} = ${workspaceId}\n and ${schema.sessions.activityRevisionPendingXid}\n = pg_current_xact_id()::text::bigint\n ),\n advanced as (\n update ${schema.workspaceSessionActivityRevisions} as counter\n set revision = counter.revision + 1\n where counter.workspace_id = ${workspaceId}\n and exists (select 1 from pending)\n returning counter.revision\n ),\n stamped as (\n update ${schema.sessions} as session\n set\n activity_revision = advanced.revision,\n activity_revision_pending_xid = null\n from advanced\n where session.workspace_id = ${workspaceId}\n and session.activity_revision_pending_xid\n = pg_current_xact_id()::text::bigint\n returning session.id\n ),\n stats as materialized (\n select\n exists (select 1 from pending) as had_pending,\n (select count(*)::integer from pending) as pending_count,\n (select revision::text from advanced) as revision,\n (select count(*)::integer from stamped) as stamped_count\n ),\n finalized as materialized (\n select\n had_pending,\n pending_count,\n revision,\n stamped_count,\n set_config('opengeni.session_activity_gate_state', 'finalized', true) as state\n from stats\n )\n select had_pending, pending_count, revision, stamped_count\n from finalized\n `,\n );\n if (!result) {\n throw new Error(\"Session activity commit gate did not return a finalization result\");\n }\n if (result.had_pending && result.revision === null) {\n throw new Error(\"Workspace session activity counter is unavailable\");\n }\n if (result.stamped_count !== result.pending_count) {\n throw new Error(\"Session activity commit gate did not stamp every pending row\");\n }\n await db.execute(\n sql`set constraints sessions_activity_insert_commit_guard, sessions_activity_update_commit_guard immediate`,\n );\n}\n\n/**\n * Run one workspace transaction with explicit once-per-transaction session\n * activity finalization. Nested callers reuse the outer gate; only its owner\n * finalizes immediately before the enclosing RLS transaction commits.\n */\nexport async function withSessionActivityRlsContext<T>(\n db: Database,\n context: RlsContext & { workspaceId: string },\n fn: (db: SessionActivityDatabase) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n): Promise<T> {\n await assertSessionActivityGateEntry(db);\n return await withRlsContext(\n db,\n context,\n async (scopedDb) => {\n const gate = await beginSessionActivityGate(scopedDb, context.workspaceId);\n const value = await fn(gate.db);\n // The finalizer must never trust tenant GUCs that arbitrary callback code\n // could have changed. Nested RLS helpers restore their parent scope; this\n // assertion is the fail-closed commit-boundary proof for every other path.\n await assertRlsContextApplied(gate.db, context);\n if (gate.owner) {\n await finalizeSessionActivityGate(gate.db, context.workspaceId);\n }\n return value;\n },\n transactionConfig,\n );\n}\n\nexport async function withWorkspaceSessionActivityRls<T>(\n db: Database,\n workspaceId: string,\n fn: (db: SessionActivityDatabase) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n): Promise<T> {\n return await withSessionActivityRlsContext(\n db,\n { ...(await rlsContextForWorkspace(db, workspaceId)), workspaceId },\n fn,\n transactionConfig,\n );\n}\n\n/**\n * Open one nested savepoint without losing the gate brand. Drizzle correctly\n * preserves the backend-local gate GUCs, but its structural transaction type\n * cannot express that provenance; keep the single trusted rebrand here.\n */\nexport async function withSessionActivitySavepoint<T>(\n db: SessionActivityDatabase,\n fn: (db: SessionActivityDatabase) => Promise<T>,\n): Promise<T> {\n return await db.transaction(async (tx) => await fn(tx as unknown as SessionActivityDatabase));\n}\n\nexport async function retrySessionActivityRls<T>(\n db: Database,\n workspaceId: string,\n options: IdempotentPersistenceTransactionOptions,\n fn: (db: SessionActivityDatabase) => Promise<T>,\n): Promise<T> {\n return await runIdempotentPersistenceTransaction(options, async () => {\n return await withWorkspaceSessionActivityRls(db, workspaceId, fn);\n });\n}\n\nexport async function retryWorkspacePersistence<T>(\n db: Database,\n workspaceId: string,\n options: IdempotentPersistenceTransactionOptions,\n fn: (db: Database) => Promise<T>,\n): Promise<T> {\n return await runIdempotentPersistenceTransaction(options, async () => {\n return await withWorkspaceRls(db, workspaceId, fn);\n });\n}\n\nexport async function retryRlsPersistence<T>(\n db: Database,\n context: RlsContext,\n options: IdempotentPersistenceTransactionOptions,\n fn: (db: Database) => Promise<T>,\n): Promise<T> {\n return await runIdempotentPersistenceTransaction(options, async () => {\n return await withRlsContext(db, context, fn);\n });\n}\n\n/**\n * Personal workspace data needs both tenant and authenticated-principal GUCs.\n * `session_pins` uses this helper so FORCE RLS rejects another member's rows\n * even if a future query accidentally omits its explicit subject predicate.\n */\nexport async function withWorkspaceSubjectRls<T>(\n db: Database,\n workspaceId: string,\n subjectId: string,\n fn: (db: Database) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n): Promise<T> {\n if (!subjectId.trim()) {\n throw new Error(\"withWorkspaceSubjectRls: a non-empty subjectId is required\");\n }\n const context = await rlsContextForWorkspace(db, workspaceId);\n return await withRlsContext(\n db,\n context,\n async (scopedDb) => {\n await setSubjectRlsContext(scopedDb, subjectId);\n return await fn(scopedDb);\n },\n transactionConfig,\n );\n}\n\nexport async function withWorkspaceSubjectSessionActivityRls<T>(\n db: Database,\n workspaceId: string,\n subjectId: string,\n fn: (db: SessionActivityDatabase) => Promise<T>,\n transactionConfig?: PgTransactionConfig,\n): Promise<T> {\n if (!subjectId.trim()) {\n throw new Error(\"withWorkspaceSubjectSessionActivityRls: a non-empty subjectId is required\");\n }\n const context = await rlsContextForWorkspace(db, workspaceId);\n return await withSessionActivityRlsContext(\n db,\n { ...context, workspaceId },\n async (scopedDb) => {\n await setSubjectRlsContext(scopedDb, subjectId);\n return await fn(scopedDb);\n },\n transactionConfig,\n );\n}\n\n/** Apply and verify actor-private RLS on an already transaction-pinned handle. */\nexport async function setSubjectRlsContext(db: Database, subjectId: string): Promise<void> {\n if (!subjectId.trim()) {\n throw new Error(\"setSubjectRlsContext: a non-empty subjectId is required\");\n }\n await db.execute(sql`select set_config('opengeni.subject_id', ${subjectId}, true)`);\n const applied = await db.execute<{ subject_id: string | null }>(\n sql`select current_setting('opengeni.subject_id', true) as subject_id`,\n );\n if ((applied[0]?.subject_id ?? \"\") !== subjectId) {\n throw new Error(\"Authenticated subject RLS context was not applied on the active backend\");\n }\n}\n\nexport async function withWorkspaceUsageLock<T>(\n db: Database,\n workspaceId: string,\n fn: (db: Database) => Promise<T>,\n): Promise<T> {\n const context = await rlsContextForWorkspace(db, workspaceId);\n return await withRlsContext(db, context, async (scopedDb) => {\n await scopedDb.execute(sql`select pg_advisory_xact_lock(hashtext(${`usage:${workspaceId}`}))`);\n return await fn(scopedDb);\n });\n}\n\nexport async function withAccountRls<T>(\n db: Database,\n accountId: string,\n fn: (db: Database) => Promise<T>,\n): Promise<T> {\n return await withRlsContext(db, { accountId, workspaceId: null }, fn);\n}\n\n/** Internal lookup for the host binding attached to a database handle. */\nexport function dbBindingFor(db: Database): DbBinding | undefined {\n return dbBindings.get(db as unknown as object);\n}\n"],"mappings":"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","names":[]}
@@ -21,6 +21,11 @@ export type RlsContext = {
21
21
  accountId: string;
22
22
  workspaceId?: string | null;
23
23
  };
24
+ export type SessionRlsActorContext = {
25
+ subjectId: string;
26
+ initiatingHumanSubjectId?: string | null;
27
+ };
28
+ export declare function withSessionRlsActorContext<T>(actor: SessionRlsActorContext, fn: () => Promise<T>): Promise<T>;
24
29
  /**
25
30
  * RLS posture for the connection OpenGeni's query layer runs over (Step I, §7.7).
26
31
  *
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  rawRows,
3
3
  withRlsContext
4
- } from "./chunk-ISI2TIUG.js";
5
- import "./chunk-MWDVXQOL.js";
4
+ } from "./chunk-Z7VYMNPZ.js";
5
+ import "./chunk-5KTIEDX7.js";
6
6
  import "./chunk-PZ5AY32C.js";
7
7
 
8
8
  // src/editable-artifact-durable-export.ts
@@ -8,9 +8,9 @@ import {
8
8
  PostgresEditableArtifactStore,
9
9
  listEditableArtifactIdsForSession,
10
10
  touchEditableArtifactSessionLink
11
- } from "./chunk-F5FT7BEZ.js";
12
- import "./chunk-ISI2TIUG.js";
13
- import "./chunk-MWDVXQOL.js";
11
+ } from "./chunk-HSOWSYOX.js";
12
+ import "./chunk-Z7VYMNPZ.js";
13
+ import "./chunk-5KTIEDX7.js";
14
14
  import "./chunk-PZ5AY32C.js";
15
15
  export {
16
16
  EDITABLE_ARTIFACT_INTENT_MAX_BYTES,