libre-webui 0.21.3 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +308 -328
- package/backend/dist/cli/migrateSqliteToPostgres.d.ts +2 -0
- package/backend/dist/cli/migrateSqliteToPostgres.d.ts.map +1 -0
- package/backend/dist/cli/migrateSqliteToPostgres.js +113 -0
- package/backend/dist/cli/migrateSqliteToPostgres.js.map +1 -0
- package/backend/dist/cli/recoveryBackup.d.ts +3 -0
- package/backend/dist/cli/recoveryBackup.d.ts.map +1 -0
- package/backend/dist/cli/recoveryBackup.js +251 -0
- package/backend/dist/cli/recoveryBackup.js.map +1 -0
- package/backend/dist/cli/recoveryInventory.d.ts +2 -0
- package/backend/dist/cli/recoveryInventory.d.ts.map +1 -0
- package/backend/dist/cli/recoveryInventory.js +109 -0
- package/backend/dist/cli/recoveryInventory.js.map +1 -0
- package/backend/dist/db.d.ts +27 -0
- package/backend/dist/db.d.ts.map +1 -1
- package/backend/dist/db.js +333 -16
- package/backend/dist/db.js.map +1 -1
- package/backend/dist/env.d.ts.map +1 -1
- package/backend/dist/env.js +12 -2
- package/backend/dist/env.js.map +1 -1
- package/backend/dist/index.d.ts.map +1 -1
- package/backend/dist/index.js +235 -47
- package/backend/dist/index.js.map +1 -1
- package/backend/dist/main.d.ts +2 -0
- package/backend/dist/main.d.ts.map +1 -0
- package/backend/dist/main.js +137 -0
- package/backend/dist/main.js.map +1 -0
- package/backend/dist/middleware/auth.d.ts.map +1 -1
- package/backend/dist/middleware/auth.js +7 -3
- package/backend/dist/middleware/auth.js.map +1 -1
- package/backend/dist/middleware/chatCancellationAdmission.d.ts +7 -0
- package/backend/dist/middleware/chatCancellationAdmission.d.ts.map +1 -0
- package/backend/dist/middleware/chatCancellationAdmission.js +17 -0
- package/backend/dist/middleware/chatCancellationAdmission.js.map +1 -0
- package/backend/dist/middleware/coordinatedRateLimit.d.ts +18 -0
- package/backend/dist/middleware/coordinatedRateLimit.d.ts.map +1 -0
- package/backend/dist/middleware/coordinatedRateLimit.js +52 -0
- package/backend/dist/middleware/coordinatedRateLimit.js.map +1 -0
- package/backend/dist/middleware/sharedRateLimit.d.ts +26 -0
- package/backend/dist/middleware/sharedRateLimit.d.ts.map +1 -0
- package/backend/dist/middleware/sharedRateLimit.js +99 -0
- package/backend/dist/middleware/sharedRateLimit.js.map +1 -0
- package/backend/dist/models/personaModel.d.ts +1 -26
- package/backend/dist/models/personaModel.d.ts.map +1 -1
- package/backend/dist/models/personaModel.js +54 -247
- package/backend/dist/models/personaModel.js.map +1 -1
- package/backend/dist/models/userModel.d.ts +23 -66
- package/backend/dist/models/userModel.d.ts.map +1 -1
- package/backend/dist/models/userModel.js +110 -187
- package/backend/dist/models/userModel.js.map +1 -1
- package/backend/dist/persistence/chatGenerationTypes.d.ts +24 -0
- package/backend/dist/persistence/chatGenerationTypes.d.ts.map +1 -0
- package/backend/dist/persistence/chatGenerationTypes.js +7 -0
- package/backend/dist/persistence/chatGenerationTypes.js.map +1 -0
- package/backend/dist/persistence/extensionTypes.d.ts +185 -0
- package/backend/dist/persistence/extensionTypes.d.ts.map +1 -0
- package/backend/dist/persistence/extensionTypes.js +13 -0
- package/backend/dist/persistence/extensionTypes.js.map +1 -0
- package/backend/dist/persistence/identityDeletionTypes.d.ts +16 -0
- package/backend/dist/persistence/identityDeletionTypes.d.ts.map +1 -0
- package/backend/dist/persistence/identityDeletionTypes.js +7 -0
- package/backend/dist/persistence/identityDeletionTypes.js.map +1 -0
- package/backend/dist/persistence/index.d.ts +48 -0
- package/backend/dist/persistence/index.d.ts.map +1 -0
- package/backend/dist/persistence/index.js +159 -0
- package/backend/dist/persistence/index.js.map +1 -0
- package/backend/dist/persistence/postgresConfig.d.ts +32 -0
- package/backend/dist/persistence/postgresConfig.d.ts.map +1 -0
- package/backend/dist/persistence/postgresConfig.js +91 -0
- package/backend/dist/persistence/postgresConfig.js.map +1 -0
- package/backend/dist/persistence/postgresCoreMigration.d.ts +8 -0
- package/backend/dist/persistence/postgresCoreMigration.d.ts.map +1 -0
- package/backend/dist/persistence/postgresCoreMigration.js +179 -0
- package/backend/dist/persistence/postgresCoreMigration.js.map +1 -0
- package/backend/dist/persistence/postgresDatabase.d.ts +40 -0
- package/backend/dist/persistence/postgresDatabase.d.ts.map +1 -0
- package/backend/dist/persistence/postgresDatabase.js +148 -0
- package/backend/dist/persistence/postgresDatabase.js.map +1 -0
- package/backend/dist/persistence/postgresExtensionMigration.d.ts +4 -0
- package/backend/dist/persistence/postgresExtensionMigration.d.ts.map +1 -0
- package/backend/dist/persistence/postgresExtensionMigration.js +143 -0
- package/backend/dist/persistence/postgresExtensionMigration.js.map +1 -0
- package/backend/dist/persistence/postgresExtensionRepositories.d.ts +6 -0
- package/backend/dist/persistence/postgresExtensionRepositories.d.ts.map +1 -0
- package/backend/dist/persistence/postgresExtensionRepositories.js +550 -0
- package/backend/dist/persistence/postgresExtensionRepositories.js.map +1 -0
- package/backend/dist/persistence/postgresImportState.d.ts +9 -0
- package/backend/dist/persistence/postgresImportState.d.ts.map +1 -0
- package/backend/dist/persistence/postgresImportState.js +64 -0
- package/backend/dist/persistence/postgresImportState.js.map +1 -0
- package/backend/dist/persistence/postgresMigrationRegistry.d.ts +4 -0
- package/backend/dist/persistence/postgresMigrationRegistry.d.ts.map +1 -0
- package/backend/dist/persistence/postgresMigrationRegistry.js +33 -0
- package/backend/dist/persistence/postgresMigrationRegistry.js.map +1 -0
- package/backend/dist/persistence/postgresMigrationTypes.d.ts +24 -0
- package/backend/dist/persistence/postgresMigrationTypes.d.ts.map +1 -0
- package/backend/dist/persistence/postgresMigrationTypes.js +7 -0
- package/backend/dist/persistence/postgresMigrationTypes.js.map +1 -0
- package/backend/dist/persistence/postgresMigrations.d.ts +15 -0
- package/backend/dist/persistence/postgresMigrations.d.ts.map +1 -0
- package/backend/dist/persistence/postgresMigrations.js +333 -0
- package/backend/dist/persistence/postgresMigrations.js.map +1 -0
- package/backend/dist/persistence/postgresPersistence.d.ts +17 -0
- package/backend/dist/persistence/postgresPersistence.d.ts.map +1 -0
- package/backend/dist/persistence/postgresPersistence.js +332 -0
- package/backend/dist/persistence/postgresPersistence.js.map +1 -0
- package/backend/dist/persistence/postgresPluginDefinitionMigration.d.ts +4 -0
- package/backend/dist/persistence/postgresPluginDefinitionMigration.d.ts.map +1 -0
- package/backend/dist/persistence/postgresPluginDefinitionMigration.js +40 -0
- package/backend/dist/persistence/postgresPluginDefinitionMigration.js.map +1 -0
- package/backend/dist/persistence/postgresResourceRepositories.d.ts +7 -0
- package/backend/dist/persistence/postgresResourceRepositories.d.ts.map +1 -0
- package/backend/dist/persistence/postgresResourceRepositories.js +776 -0
- package/backend/dist/persistence/postgresResourceRepositories.js.map +1 -0
- package/backend/dist/persistence/postgresSchemaInspector.d.ts +14 -0
- package/backend/dist/persistence/postgresSchemaInspector.d.ts.map +1 -0
- package/backend/dist/persistence/postgresSchemaInspector.js +817 -0
- package/backend/dist/persistence/postgresSchemaInspector.js.map +1 -0
- package/backend/dist/persistence/resourceTypes.d.ts +207 -0
- package/backend/dist/persistence/resourceTypes.d.ts.map +1 -0
- package/backend/dist/persistence/resourceTypes.js +38 -0
- package/backend/dist/persistence/resourceTypes.js.map +1 -0
- package/backend/dist/persistence/sqliteExtensionRepositories.d.ts +4 -0
- package/backend/dist/persistence/sqliteExtensionRepositories.d.ts.map +1 -0
- package/backend/dist/persistence/sqliteExtensionRepositories.js +494 -0
- package/backend/dist/persistence/sqliteExtensionRepositories.js.map +1 -0
- package/backend/dist/persistence/sqliteMigrations.d.ts +93 -0
- package/backend/dist/persistence/sqliteMigrations.d.ts.map +1 -0
- package/backend/dist/persistence/sqliteMigrations.js +2232 -0
- package/backend/dist/persistence/sqliteMigrations.js.map +1 -0
- package/backend/dist/persistence/sqlitePersistence.d.ts +23 -0
- package/backend/dist/persistence/sqlitePersistence.d.ts.map +1 -0
- package/backend/dist/persistence/sqlitePersistence.js +596 -0
- package/backend/dist/persistence/sqlitePersistence.js.map +1 -0
- package/backend/dist/persistence/sqliteResourceRepositories.d.ts +4 -0
- package/backend/dist/persistence/sqliteResourceRepositories.d.ts.map +1 -0
- package/backend/dist/persistence/sqliteResourceRepositories.js +663 -0
- package/backend/dist/persistence/sqliteResourceRepositories.js.map +1 -0
- package/backend/dist/persistence/sqliteSyncExecutor.d.ts +5 -0
- package/backend/dist/persistence/sqliteSyncExecutor.d.ts.map +1 -0
- package/backend/dist/persistence/sqliteSyncExecutor.js +19 -0
- package/backend/dist/persistence/sqliteSyncExecutor.js.map +1 -0
- package/backend/dist/persistence/sqliteToPostgresMigration.d.ts +80 -0
- package/backend/dist/persistence/sqliteToPostgresMigration.d.ts.map +1 -0
- package/backend/dist/persistence/sqliteToPostgresMigration.js +1543 -0
- package/backend/dist/persistence/sqliteToPostgresMigration.js.map +1 -0
- package/backend/dist/persistence/types.d.ts +131 -0
- package/backend/dist/persistence/types.d.ts.map +1 -0
- package/backend/dist/persistence/types.js +18 -0
- package/backend/dist/persistence/types.js.map +1 -0
- package/backend/dist/persistence/voiceProfileNameLookup.d.ts +9 -0
- package/backend/dist/persistence/voiceProfileNameLookup.d.ts.map +1 -0
- package/backend/dist/persistence/voiceProfileNameLookup.js +15 -0
- package/backend/dist/persistence/voiceProfileNameLookup.js.map +1 -0
- package/backend/dist/platform/coordination/index.d.ts +7 -0
- package/backend/dist/platform/coordination/index.d.ts.map +1 -0
- package/backend/dist/platform/coordination/index.js +24 -0
- package/backend/dist/platform/coordination/index.js.map +1 -0
- package/backend/dist/platform/coordination/localCoordinator.d.ts +49 -0
- package/backend/dist/platform/coordination/localCoordinator.d.ts.map +1 -0
- package/backend/dist/platform/coordination/localCoordinator.js +380 -0
- package/backend/dist/platform/coordination/localCoordinator.js.map +1 -0
- package/backend/dist/platform/coordination/redisCoordinator.d.ts +83 -0
- package/backend/dist/platform/coordination/redisCoordinator.d.ts.map +1 -0
- package/backend/dist/platform/coordination/redisCoordinator.js +726 -0
- package/backend/dist/platform/coordination/redisCoordinator.js.map +1 -0
- package/backend/dist/platform/coordination/service.d.ts +11 -0
- package/backend/dist/platform/coordination/service.d.ts.map +1 -0
- package/backend/dist/platform/coordination/service.js +55 -0
- package/backend/dist/platform/coordination/service.js.map +1 -0
- package/backend/dist/platform/coordination/sharedAdmission.d.ts +53 -0
- package/backend/dist/platform/coordination/sharedAdmission.d.ts.map +1 -0
- package/backend/dist/platform/coordination/sharedAdmission.js +194 -0
- package/backend/dist/platform/coordination/sharedAdmission.js.map +1 -0
- package/backend/dist/platform/coordination/types.d.ts +76 -0
- package/backend/dist/platform/coordination/types.d.ts.map +1 -0
- package/backend/dist/platform/coordination/types.js +32 -0
- package/backend/dist/platform/coordination/types.js.map +1 -0
- package/backend/dist/platform/events/durableEventGateway.d.ts +54 -0
- package/backend/dist/platform/events/durableEventGateway.d.ts.map +1 -0
- package/backend/dist/platform/events/durableEventGateway.js +262 -0
- package/backend/dist/platform/events/durableEventGateway.js.map +1 -0
- package/backend/dist/platform/events/index.d.ts +3 -0
- package/backend/dist/platform/events/index.d.ts.map +1 -0
- package/backend/dist/platform/events/index.js +8 -0
- package/backend/dist/platform/events/index.js.map +1 -0
- package/backend/dist/platform/events/service.d.ts +8 -0
- package/backend/dist/platform/events/service.d.ts.map +1 -0
- package/backend/dist/platform/events/service.js +25 -0
- package/backend/dist/platform/events/service.js.map +1 -0
- package/backend/dist/platform/jobs/chatGenerationEnqueuer.d.ts +3 -0
- package/backend/dist/platform/jobs/chatGenerationEnqueuer.d.ts.map +1 -0
- package/backend/dist/platform/jobs/chatGenerationEnqueuer.js +55 -0
- package/backend/dist/platform/jobs/chatGenerationEnqueuer.js.map +1 -0
- package/backend/dist/platform/jobs/documentIngestionEnqueuer.d.ts +3 -0
- package/backend/dist/platform/jobs/documentIngestionEnqueuer.d.ts.map +1 -0
- package/backend/dist/platform/jobs/documentIngestionEnqueuer.js +38 -0
- package/backend/dist/platform/jobs/documentIngestionEnqueuer.js.map +1 -0
- package/backend/dist/platform/jobs/domainJobContracts.d.ts +30 -0
- package/backend/dist/platform/jobs/domainJobContracts.d.ts.map +1 -0
- package/backend/dist/platform/jobs/domainJobContracts.js +53 -0
- package/backend/dist/platform/jobs/domainJobContracts.js.map +1 -0
- package/backend/dist/platform/jobs/domainJobHandlers.d.ts +11 -0
- package/backend/dist/platform/jobs/domainJobHandlers.d.ts.map +1 -0
- package/backend/dist/platform/jobs/domainJobHandlers.js +612 -0
- package/backend/dist/platform/jobs/domainJobHandlers.js.map +1 -0
- package/backend/dist/platform/jobs/durableEventIdentity.d.ts +8 -0
- package/backend/dist/platform/jobs/durableEventIdentity.d.ts.map +1 -0
- package/backend/dist/platform/jobs/durableEventIdentity.js +33 -0
- package/backend/dist/platform/jobs/durableEventIdentity.js.map +1 -0
- package/backend/dist/platform/jobs/durableJobRuntime.d.ts +57 -0
- package/backend/dist/platform/jobs/durableJobRuntime.d.ts.map +1 -0
- package/backend/dist/platform/jobs/durableJobRuntime.js +131 -0
- package/backend/dist/platform/jobs/durableJobRuntime.js.map +1 -0
- package/backend/dist/platform/jobs/durableJobRuntimeBackend.d.ts +28 -0
- package/backend/dist/platform/jobs/durableJobRuntimeBackend.d.ts.map +1 -0
- package/backend/dist/platform/jobs/durableJobRuntimeBackend.js +62 -0
- package/backend/dist/platform/jobs/durableJobRuntimeBackend.js.map +1 -0
- package/backend/dist/platform/jobs/durableJobService.d.ts +85 -0
- package/backend/dist/platform/jobs/durableJobService.d.ts.map +1 -0
- package/backend/dist/platform/jobs/durableJobService.js +726 -0
- package/backend/dist/platform/jobs/durableJobService.js.map +1 -0
- package/backend/dist/platform/jobs/durableJobTypes.d.ts +195 -0
- package/backend/dist/platform/jobs/durableJobTypes.d.ts.map +1 -0
- package/backend/dist/platform/jobs/durableJobTypes.js +72 -0
- package/backend/dist/platform/jobs/durableJobTypes.js.map +1 -0
- package/backend/dist/platform/jobs/embeddedDurableJobWorker.d.ts +87 -0
- package/backend/dist/platform/jobs/embeddedDurableJobWorker.d.ts.map +1 -0
- package/backend/dist/platform/jobs/embeddedDurableJobWorker.js +429 -0
- package/backend/dist/platform/jobs/embeddedDurableJobWorker.js.map +1 -0
- package/backend/dist/platform/jobs/identityDeletionEnqueuer.d.ts +3 -0
- package/backend/dist/platform/jobs/identityDeletionEnqueuer.d.ts.map +1 -0
- package/backend/dist/platform/jobs/identityDeletionEnqueuer.js +36 -0
- package/backend/dist/platform/jobs/identityDeletionEnqueuer.js.map +1 -0
- package/backend/dist/platform/jobs/index.d.ts +18 -0
- package/backend/dist/platform/jobs/index.d.ts.map +1 -0
- package/backend/dist/platform/jobs/index.js +34 -0
- package/backend/dist/platform/jobs/index.js.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableEventIdempotencyMigration.d.ts +4 -0
- package/backend/dist/platform/jobs/postgresDurableEventIdempotencyMigration.d.ts.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableEventIdempotencyMigration.js +25 -0
- package/backend/dist/platform/jobs/postgresDurableEventIdempotencyMigration.js.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableEventReplayIndexMigration.d.ts +4 -0
- package/backend/dist/platform/jobs/postgresDurableEventReplayIndexMigration.d.ts.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableEventReplayIndexMigration.js +23 -0
- package/backend/dist/platform/jobs/postgresDurableEventReplayIndexMigration.js.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableJobMigration.d.ts +11 -0
- package/backend/dist/platform/jobs/postgresDurableJobMigration.d.ts.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableJobMigration.js +106 -0
- package/backend/dist/platform/jobs/postgresDurableJobMigration.js.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableJobRepository.d.ts +88 -0
- package/backend/dist/platform/jobs/postgresDurableJobRepository.d.ts.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableJobRepository.js +1185 -0
- package/backend/dist/platform/jobs/postgresDurableJobRepository.js.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableJobService.d.ts +86 -0
- package/backend/dist/platform/jobs/postgresDurableJobService.d.ts.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableJobService.js +696 -0
- package/backend/dist/platform/jobs/postgresDurableJobService.js.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableJobWorker.d.ts +53 -0
- package/backend/dist/platform/jobs/postgresDurableJobWorker.d.ts.map +1 -0
- package/backend/dist/platform/jobs/postgresDurableJobWorker.js +393 -0
- package/backend/dist/platform/jobs/postgresDurableJobWorker.js.map +1 -0
- package/backend/dist/platform/jobs/resourceDeletionEnqueuer.d.ts +3 -0
- package/backend/dist/platform/jobs/resourceDeletionEnqueuer.d.ts.map +1 -0
- package/backend/dist/platform/jobs/resourceDeletionEnqueuer.js +43 -0
- package/backend/dist/platform/jobs/resourceDeletionEnqueuer.js.map +1 -0
- package/backend/dist/platform/jobs/sqliteDurableJobRepository.d.ts +166 -0
- package/backend/dist/platform/jobs/sqliteDurableJobRepository.d.ts.map +1 -0
- package/backend/dist/platform/jobs/sqliteDurableJobRepository.js +1008 -0
- package/backend/dist/platform/jobs/sqliteDurableJobRepository.js.map +1 -0
- package/backend/dist/platform/jobs/videoGenerationEnqueuer.d.ts +4 -0
- package/backend/dist/platform/jobs/videoGenerationEnqueuer.d.ts.map +1 -0
- package/backend/dist/platform/jobs/videoGenerationEnqueuer.js +46 -0
- package/backend/dist/platform/jobs/videoGenerationEnqueuer.js.map +1 -0
- package/backend/dist/platform/jobs/workExecutionEnqueuer.d.ts +3 -0
- package/backend/dist/platform/jobs/workExecutionEnqueuer.d.ts.map +1 -0
- package/backend/dist/platform/jobs/workExecutionEnqueuer.js +38 -0
- package/backend/dist/platform/jobs/workExecutionEnqueuer.js.map +1 -0
- package/backend/dist/platform/ollamaRuntimeConfig.d.ts +40 -0
- package/backend/dist/platform/ollamaRuntimeConfig.d.ts.map +1 -0
- package/backend/dist/platform/ollamaRuntimeConfig.js +72 -0
- package/backend/dist/platform/ollamaRuntimeConfig.js.map +1 -0
- package/backend/dist/platform/recovery/backupArchive.d.ts +120 -0
- package/backend/dist/platform/recovery/backupArchive.d.ts.map +1 -0
- package/backend/dist/platform/recovery/backupArchive.js +842 -0
- package/backend/dist/platform/recovery/backupArchive.js.map +1 -0
- package/backend/dist/platform/recovery/index.d.ts +3 -0
- package/backend/dist/platform/recovery/index.d.ts.map +1 -0
- package/backend/dist/platform/recovery/index.js +8 -0
- package/backend/dist/platform/recovery/index.js.map +1 -0
- package/backend/dist/platform/recovery/teamBackupArchive.d.ts +98 -0
- package/backend/dist/platform/recovery/teamBackupArchive.d.ts.map +1 -0
- package/backend/dist/platform/recovery/teamBackupArchive.js +1203 -0
- package/backend/dist/platform/recovery/teamBackupArchive.js.map +1 -0
- package/backend/dist/platform/runtimeConfig.d.ts +70 -0
- package/backend/dist/platform/runtimeConfig.d.ts.map +1 -0
- package/backend/dist/platform/runtimeConfig.js +205 -0
- package/backend/dist/platform/runtimeConfig.js.map +1 -0
- package/backend/dist/platform/storage/aesGcmKeyring.d.ts +26 -0
- package/backend/dist/platform/storage/aesGcmKeyring.d.ts.map +1 -0
- package/backend/dist/platform/storage/aesGcmKeyring.js +135 -0
- package/backend/dist/platform/storage/aesGcmKeyring.js.map +1 -0
- package/backend/dist/platform/storage/blobReferenceRepository.d.ts +36 -0
- package/backend/dist/platform/storage/blobReferenceRepository.d.ts.map +1 -0
- package/backend/dist/platform/storage/blobReferenceRepository.js +117 -0
- package/backend/dist/platform/storage/blobReferenceRepository.js.map +1 -0
- package/backend/dist/platform/storage/blobStore.d.ts +111 -0
- package/backend/dist/platform/storage/blobStore.d.ts.map +1 -0
- package/backend/dist/platform/storage/blobStore.js +46 -0
- package/backend/dist/platform/storage/blobStore.js.map +1 -0
- package/backend/dist/platform/storage/documentVectorIndex.d.ts +44 -0
- package/backend/dist/platform/storage/documentVectorIndex.d.ts.map +1 -0
- package/backend/dist/platform/storage/documentVectorIndex.js +110 -0
- package/backend/dist/platform/storage/documentVectorIndex.js.map +1 -0
- package/backend/dist/platform/storage/durableBlobQuotaPolicy.d.ts +82 -0
- package/backend/dist/platform/storage/durableBlobQuotaPolicy.d.ts.map +1 -0
- package/backend/dist/platform/storage/durableBlobQuotaPolicy.js +583 -0
- package/backend/dist/platform/storage/durableBlobQuotaPolicy.js.map +1 -0
- package/backend/dist/platform/storage/index.d.ts +19 -0
- package/backend/dist/platform/storage/index.d.ts.map +1 -0
- package/backend/dist/platform/storage/index.js +35 -0
- package/backend/dist/platform/storage/index.js.map +1 -0
- package/backend/dist/platform/storage/localEncryptedBlobStore.d.ts +120 -0
- package/backend/dist/platform/storage/localEncryptedBlobStore.d.ts.map +1 -0
- package/backend/dist/platform/storage/localEncryptedBlobStore.js +1205 -0
- package/backend/dist/platform/storage/localEncryptedBlobStore.js.map +1 -0
- package/backend/dist/platform/storage/personaMemoryIndexing.d.ts +12 -0
- package/backend/dist/platform/storage/personaMemoryIndexing.d.ts.map +1 -0
- package/backend/dist/platform/storage/personaMemoryIndexing.js +25 -0
- package/backend/dist/platform/storage/personaMemoryIndexing.js.map +1 -0
- package/backend/dist/platform/storage/pgVectorStore.d.ts +37 -0
- package/backend/dist/platform/storage/pgVectorStore.d.ts.map +1 -0
- package/backend/dist/platform/storage/pgVectorStore.js +493 -0
- package/backend/dist/platform/storage/pgVectorStore.js.map +1 -0
- package/backend/dist/platform/storage/platformDomainRepositories.d.ts +244 -0
- package/backend/dist/platform/storage/platformDomainRepositories.d.ts.map +1 -0
- package/backend/dist/platform/storage/platformDomainRepositories.js +7 -0
- package/backend/dist/platform/storage/platformDomainRepositories.js.map +1 -0
- package/backend/dist/platform/storage/platformStorageRuntime.d.ts +35 -0
- package/backend/dist/platform/storage/platformStorageRuntime.d.ts.map +1 -0
- package/backend/dist/platform/storage/platformStorageRuntime.js +299 -0
- package/backend/dist/platform/storage/platformStorageRuntime.js.map +1 -0
- package/backend/dist/platform/storage/postgresPlatformDomainRepositories.d.ts +4 -0
- package/backend/dist/platform/storage/postgresPlatformDomainRepositories.d.ts.map +1 -0
- package/backend/dist/platform/storage/postgresPlatformDomainRepositories.js +1017 -0
- package/backend/dist/platform/storage/postgresPlatformDomainRepositories.js.map +1 -0
- package/backend/dist/platform/storage/postgresResourceDeletionLifecycleMigration.d.ts +4 -0
- package/backend/dist/platform/storage/postgresResourceDeletionLifecycleMigration.d.ts.map +1 -0
- package/backend/dist/platform/storage/postgresResourceDeletionLifecycleMigration.js +40 -0
- package/backend/dist/platform/storage/postgresResourceDeletionLifecycleMigration.js.map +1 -0
- package/backend/dist/platform/storage/resourceContentCleanup.d.ts +29 -0
- package/backend/dist/platform/storage/resourceContentCleanup.d.ts.map +1 -0
- package/backend/dist/platform/storage/resourceContentCleanup.js +100 -0
- package/backend/dist/platform/storage/resourceContentCleanup.js.map +1 -0
- package/backend/dist/platform/storage/resourceDeletionLifecycle.d.ts +14 -0
- package/backend/dist/platform/storage/resourceDeletionLifecycle.d.ts.map +1 -0
- package/backend/dist/platform/storage/resourceDeletionLifecycle.js +31 -0
- package/backend/dist/platform/storage/resourceDeletionLifecycle.js.map +1 -0
- package/backend/dist/platform/storage/s3EncryptedBlobStore.d.ts +140 -0
- package/backend/dist/platform/storage/s3EncryptedBlobStore.d.ts.map +1 -0
- package/backend/dist/platform/storage/s3EncryptedBlobStore.js +1309 -0
- package/backend/dist/platform/storage/s3EncryptedBlobStore.js.map +1 -0
- package/backend/dist/platform/storage/sqliteEncryptedVectorStore.d.ts +71 -0
- package/backend/dist/platform/storage/sqliteEncryptedVectorStore.d.ts.map +1 -0
- package/backend/dist/platform/storage/sqliteEncryptedVectorStore.js +766 -0
- package/backend/dist/platform/storage/sqliteEncryptedVectorStore.js.map +1 -0
- package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.d.ts +4 -0
- package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.d.ts.map +1 -0
- package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.js +1037 -0
- package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.js.map +1 -0
- package/backend/dist/platform/storage/sqliteToTeamStorageMigration.d.ts +25 -0
- package/backend/dist/platform/storage/sqliteToTeamStorageMigration.d.ts.map +1 -0
- package/backend/dist/platform/storage/sqliteToTeamStorageMigration.js +1292 -0
- package/backend/dist/platform/storage/sqliteToTeamStorageMigration.js.map +1 -0
- package/backend/dist/platform/storage/storageFactory.d.ts +81 -0
- package/backend/dist/platform/storage/storageFactory.d.ts.map +1 -0
- package/backend/dist/platform/storage/storageFactory.js +518 -0
- package/backend/dist/platform/storage/storageFactory.js.map +1 -0
- package/backend/dist/platform/storage/storageSchemaContracts.d.ts +22 -0
- package/backend/dist/platform/storage/storageSchemaContracts.d.ts.map +1 -0
- package/backend/dist/platform/storage/storageSchemaContracts.js +299 -0
- package/backend/dist/platform/storage/storageSchemaContracts.js.map +1 -0
- package/backend/dist/platform/storage/vectorStore.d.ts +117 -0
- package/backend/dist/platform/storage/vectorStore.d.ts.map +1 -0
- package/backend/dist/platform/storage/vectorStore.js +40 -0
- package/backend/dist/platform/storage/vectorStore.js.map +1 -0
- package/backend/dist/platform/workPersistence/index.d.ts +9 -0
- package/backend/dist/platform/workPersistence/index.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/index.js +14 -0
- package/backend/dist/platform/workPersistence/index.js.map +1 -0
- package/backend/dist/platform/workPersistence/postgresWorkLifecycleMigration.d.ts +9 -0
- package/backend/dist/platform/workPersistence/postgresWorkLifecycleMigration.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/postgresWorkLifecycleMigration.js +47 -0
- package/backend/dist/platform/workPersistence/postgresWorkLifecycleMigration.js.map +1 -0
- package/backend/dist/platform/workPersistence/postgresWorkMessageContentMigration.d.ts +3 -0
- package/backend/dist/platform/workPersistence/postgresWorkMessageContentMigration.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/postgresWorkMessageContentMigration.js +28 -0
- package/backend/dist/platform/workPersistence/postgresWorkMessageContentMigration.js.map +1 -0
- package/backend/dist/platform/workPersistence/postgresWorkMigration.d.ts +3 -0
- package/backend/dist/platform/workPersistence/postgresWorkMigration.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/postgresWorkMigration.js +101 -0
- package/backend/dist/platform/workPersistence/postgresWorkMigration.js.map +1 -0
- package/backend/dist/platform/workPersistence/postgresWorkPersistence.d.ts +79 -0
- package/backend/dist/platform/workPersistence/postgresWorkPersistence.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/postgresWorkPersistence.js +521 -0
- package/backend/dist/platform/workPersistence/postgresWorkPersistence.js.map +1 -0
- package/backend/dist/platform/workPersistence/service.d.ts +6 -0
- package/backend/dist/platform/workPersistence/service.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/service.js +27 -0
- package/backend/dist/platform/workPersistence/service.js.map +1 -0
- package/backend/dist/platform/workPersistence/sqliteWorkPersistence.d.ts +77 -0
- package/backend/dist/platform/workPersistence/sqliteWorkPersistence.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/sqliteWorkPersistence.js +463 -0
- package/backend/dist/platform/workPersistence/sqliteWorkPersistence.js.map +1 -0
- package/backend/dist/platform/workPersistence/types.d.ts +159 -0
- package/backend/dist/platform/workPersistence/types.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/types.js +13 -0
- package/backend/dist/platform/workPersistence/types.js.map +1 -0
- package/backend/dist/platform/workPersistence/workExecutionTypes.d.ts +13 -0
- package/backend/dist/platform/workPersistence/workExecutionTypes.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/workExecutionTypes.js +7 -0
- package/backend/dist/platform/workPersistence/workExecutionTypes.js.map +1 -0
- package/backend/dist/platform/workPersistence/workMessageContentCodec.d.ts +8 -0
- package/backend/dist/platform/workPersistence/workMessageContentCodec.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/workMessageContentCodec.js +25 -0
- package/backend/dist/platform/workPersistence/workMessageContentCodec.js.map +1 -0
- package/backend/dist/platform/workPersistence/workTextSafety.d.ts +3 -0
- package/backend/dist/platform/workPersistence/workTextSafety.d.ts.map +1 -0
- package/backend/dist/platform/workPersistence/workTextSafety.js +8 -0
- package/backend/dist/platform/workPersistence/workTextSafety.js.map +1 -0
- package/backend/dist/routes/agentCli.js +1 -1
- package/backend/dist/routes/agentCli.js.map +1 -1
- package/backend/dist/routes/artifacts.d.ts.map +1 -1
- package/backend/dist/routes/artifacts.js +2 -1
- package/backend/dist/routes/artifacts.js.map +1 -1
- package/backend/dist/routes/auth.d.ts.map +1 -1
- package/backend/dist/routes/auth.js +64 -18
- package/backend/dist/routes/auth.js.map +1 -1
- package/backend/dist/routes/chat.d.ts.map +1 -1
- package/backend/dist/routes/chat.js +519 -85
- package/backend/dist/routes/chat.js.map +1 -1
- package/backend/dist/routes/documents.d.ts.map +1 -1
- package/backend/dist/routes/documents.js +134 -28
- package/backend/dist/routes/documents.js.map +1 -1
- package/backend/dist/routes/embeddings.d.ts.map +1 -1
- package/backend/dist/routes/embeddings.js +2 -1
- package/backend/dist/routes/embeddings.js.map +1 -1
- package/backend/dist/routes/health.d.ts +3 -0
- package/backend/dist/routes/health.d.ts.map +1 -0
- package/backend/dist/routes/health.js +52 -0
- package/backend/dist/routes/health.js.map +1 -0
- package/backend/dist/routes/huggingfaceHub.d.ts.map +1 -1
- package/backend/dist/routes/huggingfaceHub.js +2 -1
- package/backend/dist/routes/huggingfaceHub.js.map +1 -1
- package/backend/dist/routes/imageGen.d.ts.map +1 -1
- package/backend/dist/routes/imageGen.js +42 -10
- package/backend/dist/routes/imageGen.js.map +1 -1
- package/backend/dist/routes/jobs.d.ts +3 -0
- package/backend/dist/routes/jobs.d.ts.map +1 -0
- package/backend/dist/routes/jobs.js +117 -0
- package/backend/dist/routes/jobs.js.map +1 -0
- package/backend/dist/routes/libreClaw.d.ts.map +1 -1
- package/backend/dist/routes/libreClaw.js +10 -7
- package/backend/dist/routes/libreClaw.js.map +1 -1
- package/backend/dist/routes/media.d.ts.map +1 -1
- package/backend/dist/routes/media.js +523 -77
- package/backend/dist/routes/media.js.map +1 -1
- package/backend/dist/routes/notes.d.ts.map +1 -1
- package/backend/dist/routes/notes.js +21 -21
- package/backend/dist/routes/notes.js.map +1 -1
- package/backend/dist/routes/ollama.d.ts.map +1 -1
- package/backend/dist/routes/ollama.js +40 -12
- package/backend/dist/routes/ollama.js.map +1 -1
- package/backend/dist/routes/personas.d.ts.map +1 -1
- package/backend/dist/routes/personas.js +4 -2
- package/backend/dist/routes/personas.js.map +1 -1
- package/backend/dist/routes/plugins.d.ts.map +1 -1
- package/backend/dist/routes/plugins.js +79 -51
- package/backend/dist/routes/plugins.js.map +1 -1
- package/backend/dist/routes/preferences.d.ts.map +1 -1
- package/backend/dist/routes/preferences.js +290 -25
- package/backend/dist/routes/preferences.js.map +1 -1
- package/backend/dist/routes/search.d.ts.map +1 -1
- package/backend/dist/routes/search.js +23 -14
- package/backend/dist/routes/search.js.map +1 -1
- package/backend/dist/routes/stt.d.ts +9 -0
- package/backend/dist/routes/stt.d.ts.map +1 -0
- package/backend/dist/routes/stt.js +217 -0
- package/backend/dist/routes/stt.js.map +1 -0
- package/backend/dist/routes/systemDiagnostics.d.ts.map +1 -1
- package/backend/dist/routes/systemDiagnostics.js +2 -1
- package/backend/dist/routes/systemDiagnostics.js.map +1 -1
- package/backend/dist/routes/tts.d.ts.map +1 -1
- package/backend/dist/routes/tts.js +577 -28
- package/backend/dist/routes/tts.js.map +1 -1
- package/backend/dist/routes/users.d.ts.map +1 -1
- package/backend/dist/routes/users.js +16 -25
- package/backend/dist/routes/users.js.map +1 -1
- package/backend/dist/routes/work.d.ts.map +1 -1
- package/backend/dist/routes/work.js +167 -113
- package/backend/dist/routes/work.js.map +1 -1
- package/backend/dist/services/agentAccessService.d.ts +2 -2
- package/backend/dist/services/agentAccessService.d.ts.map +1 -1
- package/backend/dist/services/agentAccessService.js +5 -14
- package/backend/dist/services/agentAccessService.js.map +1 -1
- package/backend/dist/services/agentCliService.d.ts +3 -2
- package/backend/dist/services/agentCliService.d.ts.map +1 -1
- package/backend/dist/services/agentCliService.js +44 -16
- package/backend/dist/services/agentCliService.js.map +1 -1
- package/backend/dist/services/assistantCompletionService.d.ts +2 -1
- package/backend/dist/services/assistantCompletionService.d.ts.map +1 -1
- package/backend/dist/services/assistantCompletionService.js +7 -3
- package/backend/dist/services/assistantCompletionService.js.map +1 -1
- package/backend/dist/services/authService.d.ts +7 -2
- package/backend/dist/services/authService.d.ts.map +1 -1
- package/backend/dist/services/authService.js +23 -10
- package/backend/dist/services/authService.js.map +1 -1
- package/backend/dist/services/chatGenerationService.d.ts +5 -4
- package/backend/dist/services/chatGenerationService.d.ts.map +1 -1
- package/backend/dist/services/chatGenerationService.js +23 -17
- package/backend/dist/services/chatGenerationService.js.map +1 -1
- package/backend/dist/services/chatRequestService.d.ts +4 -3
- package/backend/dist/services/chatRequestService.d.ts.map +1 -1
- package/backend/dist/services/chatRequestService.js +3 -3
- package/backend/dist/services/chatRequestService.js.map +1 -1
- package/backend/dist/services/chatService.d.ts +66 -16
- package/backend/dist/services/chatService.d.ts.map +1 -1
- package/backend/dist/services/chatService.js +402 -111
- package/backend/dist/services/chatService.js.map +1 -1
- package/backend/dist/services/codexOAuthService.d.ts +2 -2
- package/backend/dist/services/codexOAuthService.d.ts.map +1 -1
- package/backend/dist/services/codexOAuthService.js +63 -7
- package/backend/dist/services/codexOAuthService.js.map +1 -1
- package/backend/dist/services/dataArchiveService.d.ts +88 -0
- package/backend/dist/services/dataArchiveService.d.ts.map +1 -0
- package/backend/dist/services/dataArchiveService.js +1027 -0
- package/backend/dist/services/dataArchiveService.js.map +1 -0
- package/backend/dist/services/documentService.d.ts +67 -14
- package/backend/dist/services/documentService.d.ts.map +1 -1
- package/backend/dist/services/documentService.js +938 -193
- package/backend/dist/services/documentService.js.map +1 -1
- package/backend/dist/services/durableChatCompletion.d.ts +16 -0
- package/backend/dist/services/durableChatCompletion.d.ts.map +1 -0
- package/backend/dist/services/durableChatCompletion.js +34 -0
- package/backend/dist/services/durableChatCompletion.js.map +1 -0
- package/backend/dist/services/durableChatGenerationService.d.ts +19 -0
- package/backend/dist/services/durableChatGenerationService.d.ts.map +1 -0
- package/backend/dist/services/durableChatGenerationService.js +341 -0
- package/backend/dist/services/durableChatGenerationService.js.map +1 -0
- package/backend/dist/services/embeddingService.d.ts +1 -1
- package/backend/dist/services/embeddingService.d.ts.map +1 -1
- package/backend/dist/services/embeddingService.js +16 -13
- package/backend/dist/services/embeddingService.js.map +1 -1
- package/backend/dist/services/encryptionService.d.ts +28 -1
- package/backend/dist/services/encryptionService.d.ts.map +1 -1
- package/backend/dist/services/encryptionService.js +131 -51
- package/backend/dist/services/encryptionService.js.map +1 -1
- package/backend/dist/services/followUpService.d.ts +1 -1
- package/backend/dist/services/followUpService.d.ts.map +1 -1
- package/backend/dist/services/followUpService.js +1 -1
- package/backend/dist/services/followUpService.js.map +1 -1
- package/backend/dist/services/galleryService.d.ts +38 -37
- package/backend/dist/services/galleryService.d.ts.map +1 -1
- package/backend/dist/services/galleryService.js +356 -251
- package/backend/dist/services/galleryService.js.map +1 -1
- package/backend/dist/services/healthService.d.ts +65 -0
- package/backend/dist/services/healthService.d.ts.map +1 -0
- package/backend/dist/services/healthService.js +379 -0
- package/backend/dist/services/healthService.js.map +1 -0
- package/backend/dist/services/legacyCiphertextIntegrity.d.ts +40 -0
- package/backend/dist/services/legacyCiphertextIntegrity.d.ts.map +1 -0
- package/backend/dist/services/legacyCiphertextIntegrity.js +406 -0
- package/backend/dist/services/legacyCiphertextIntegrity.js.map +1 -0
- package/backend/dist/services/mediaGenerationJobService.d.ts +27 -5
- package/backend/dist/services/mediaGenerationJobService.d.ts.map +1 -1
- package/backend/dist/services/mediaGenerationJobService.js +185 -55
- package/backend/dist/services/mediaGenerationJobService.js.map +1 -1
- package/backend/dist/services/memoryService.d.ts +7 -83
- package/backend/dist/services/memoryService.d.ts.map +1 -1
- package/backend/dist/services/memoryService.js +428 -573
- package/backend/dist/services/memoryService.js.map +1 -1
- package/backend/dist/services/memoryUtils.d.ts.map +1 -1
- package/backend/dist/services/memoryUtils.js +8 -1
- package/backend/dist/services/memoryUtils.js.map +1 -1
- package/backend/dist/services/modelAccessService.d.ts +3 -3
- package/backend/dist/services/modelAccessService.d.ts.map +1 -1
- package/backend/dist/services/modelAccessService.js +8 -16
- package/backend/dist/services/modelAccessService.js.map +1 -1
- package/backend/dist/services/mutationEngineService.d.ts +0 -7
- package/backend/dist/services/mutationEngineService.d.ts.map +1 -1
- package/backend/dist/services/mutationEngineService.js +7 -78
- package/backend/dist/services/mutationEngineService.js.map +1 -1
- package/backend/dist/services/ollamaService.d.ts +4 -4
- package/backend/dist/services/ollamaService.d.ts.map +1 -1
- package/backend/dist/services/ollamaService.js +62 -31
- package/backend/dist/services/ollamaService.js.map +1 -1
- package/backend/dist/services/personaService.d.ts.map +1 -1
- package/backend/dist/services/personaService.js +19 -54
- package/backend/dist/services/personaService.js.map +1 -1
- package/backend/dist/services/pluginActivationService.d.ts +6 -5
- package/backend/dist/services/pluginActivationService.d.ts.map +1 -1
- package/backend/dist/services/pluginActivationService.js +36 -76
- package/backend/dist/services/pluginActivationService.js.map +1 -1
- package/backend/dist/services/pluginAudioGenerationService.d.ts +11 -6
- package/backend/dist/services/pluginAudioGenerationService.d.ts.map +1 -1
- package/backend/dist/services/pluginAudioGenerationService.js +74 -16
- package/backend/dist/services/pluginAudioGenerationService.js.map +1 -1
- package/backend/dist/services/pluginCacheInvalidation.d.ts +38 -0
- package/backend/dist/services/pluginCacheInvalidation.d.ts.map +1 -0
- package/backend/dist/services/pluginCacheInvalidation.js +198 -0
- package/backend/dist/services/pluginCacheInvalidation.js.map +1 -0
- package/backend/dist/services/pluginCapabilityRegistryService.d.ts +3 -3
- package/backend/dist/services/pluginCapabilityRegistryService.d.ts.map +1 -1
- package/backend/dist/services/pluginCapabilityRegistryService.js +11 -7
- package/backend/dist/services/pluginCapabilityRegistryService.js.map +1 -1
- package/backend/dist/services/pluginCredentialsService.d.ts +9 -8
- package/backend/dist/services/pluginCredentialsService.d.ts.map +1 -1
- package/backend/dist/services/pluginCredentialsService.js +48 -89
- package/backend/dist/services/pluginCredentialsService.js.map +1 -1
- package/backend/dist/services/pluginEmbeddingService.d.ts +8 -7
- package/backend/dist/services/pluginEmbeddingService.d.ts.map +1 -1
- package/backend/dist/services/pluginEmbeddingService.js +13 -11
- package/backend/dist/services/pluginEmbeddingService.js.map +1 -1
- package/backend/dist/services/pluginImageGenerationService.d.ts +10 -8
- package/backend/dist/services/pluginImageGenerationService.d.ts.map +1 -1
- package/backend/dist/services/pluginImageGenerationService.js +119 -14
- package/backend/dist/services/pluginImageGenerationService.js.map +1 -1
- package/backend/dist/services/pluginSTTService.d.ts +47 -0
- package/backend/dist/services/pluginSTTService.d.ts.map +1 -0
- package/backend/dist/services/pluginSTTService.js +199 -0
- package/backend/dist/services/pluginSTTService.js.map +1 -0
- package/backend/dist/services/pluginService.d.ts +94 -40
- package/backend/dist/services/pluginService.d.ts.map +1 -1
- package/backend/dist/services/pluginService.js +799 -274
- package/backend/dist/services/pluginService.js.map +1 -1
- package/backend/dist/services/pluginTTSService.d.ts +26 -8
- package/backend/dist/services/pluginTTSService.d.ts.map +1 -1
- package/backend/dist/services/pluginTTSService.js +277 -25
- package/backend/dist/services/pluginTTSService.js.map +1 -1
- package/backend/dist/services/pluginUsageService.d.ts +4 -4
- package/backend/dist/services/pluginUsageService.d.ts.map +1 -1
- package/backend/dist/services/pluginUsageService.js +44 -93
- package/backend/dist/services/pluginUsageService.js.map +1 -1
- package/backend/dist/services/pluginVariablesService.d.ts +14 -7
- package/backend/dist/services/pluginVariablesService.d.ts.map +1 -1
- package/backend/dist/services/pluginVariablesService.js +116 -81
- package/backend/dist/services/pluginVariablesService.js.map +1 -1
- package/backend/dist/services/pluginVideoGenerationService.d.ts +19 -8
- package/backend/dist/services/pluginVideoGenerationService.d.ts.map +1 -1
- package/backend/dist/services/pluginVideoGenerationService.js +116 -20
- package/backend/dist/services/pluginVideoGenerationService.js.map +1 -1
- package/backend/dist/services/preferencesService.d.ts +31 -21
- package/backend/dist/services/preferencesService.d.ts.map +1 -1
- package/backend/dist/services/preferencesService.js +104 -102
- package/backend/dist/services/preferencesService.js.map +1 -1
- package/backend/dist/services/recoveryInventoryService.d.ts +244 -0
- package/backend/dist/services/recoveryInventoryService.d.ts.map +1 -0
- package/backend/dist/services/recoveryInventoryService.js +1436 -0
- package/backend/dist/services/recoveryInventoryService.js.map +1 -0
- package/backend/dist/services/simpleGitHubOAuth.js +3 -3
- package/backend/dist/services/simpleGitHubOAuth.js.map +1 -1
- package/backend/dist/services/simpleHuggingFaceOAuth.d.ts.map +1 -1
- package/backend/dist/services/simpleHuggingFaceOAuth.js +3 -3
- package/backend/dist/services/simpleHuggingFaceOAuth.js.map +1 -1
- package/backend/dist/services/systemDiagnosticsService.d.ts.map +1 -1
- package/backend/dist/services/systemDiagnosticsService.js +2 -2
- package/backend/dist/services/systemDiagnosticsService.js.map +1 -1
- package/backend/dist/services/systemSettingsService.d.ts +5 -0
- package/backend/dist/services/systemSettingsService.d.ts.map +1 -0
- package/backend/dist/services/systemSettingsService.js +24 -0
- package/backend/dist/services/systemSettingsService.js.map +1 -0
- package/backend/dist/services/titleGenerationService.d.ts +1 -1
- package/backend/dist/services/titleGenerationService.d.ts.map +1 -1
- package/backend/dist/services/titleGenerationService.js +1 -1
- package/backend/dist/services/titleGenerationService.js.map +1 -1
- package/backend/dist/services/voiceProfileService.d.ts +44 -0
- package/backend/dist/services/voiceProfileService.d.ts.map +1 -0
- package/backend/dist/services/voiceProfileService.js +195 -0
- package/backend/dist/services/voiceProfileService.js.map +1 -0
- package/backend/dist/services/webSearchService.d.ts +7 -7
- package/backend/dist/services/webSearchService.d.ts.map +1 -1
- package/backend/dist/services/webSearchService.js +40 -35
- package/backend/dist/services/webSearchService.js.map +1 -1
- package/backend/dist/services/websocketTicketService.d.ts +39 -0
- package/backend/dist/services/websocketTicketService.d.ts.map +1 -0
- package/backend/dist/services/websocketTicketService.js +183 -0
- package/backend/dist/services/websocketTicketService.js.map +1 -0
- package/backend/dist/services/workAccessService.d.ts +3 -3
- package/backend/dist/services/workAccessService.d.ts.map +1 -1
- package/backend/dist/services/workAccessService.js +8 -16
- package/backend/dist/services/workAccessService.js.map +1 -1
- package/backend/dist/services/workAdminService.d.ts +3 -3
- package/backend/dist/services/workAdminService.d.ts.map +1 -1
- package/backend/dist/services/workAdminService.js +4 -4
- package/backend/dist/services/workAdminService.js.map +1 -1
- package/backend/dist/services/workAgentService.d.ts +25 -1
- package/backend/dist/services/workAgentService.d.ts.map +1 -1
- package/backend/dist/services/workAgentService.js +294 -126
- package/backend/dist/services/workAgentService.js.map +1 -1
- package/backend/dist/services/workEventService.d.ts +15 -2
- package/backend/dist/services/workEventService.d.ts.map +1 -1
- package/backend/dist/services/workEventService.js +201 -3
- package/backend/dist/services/workEventService.js.map +1 -1
- package/backend/dist/services/workKubernetesDriver.d.ts +8 -7
- package/backend/dist/services/workKubernetesDriver.d.ts.map +1 -1
- package/backend/dist/services/workKubernetesDriver.js +65 -21
- package/backend/dist/services/workKubernetesDriver.js.map +1 -1
- package/backend/dist/services/workModelProviderService.d.ts +2 -2
- package/backend/dist/services/workModelProviderService.d.ts.map +1 -1
- package/backend/dist/services/workModelProviderService.js +38 -34
- package/backend/dist/services/workModelProviderService.js.map +1 -1
- package/backend/dist/services/workPolicyService.d.ts +7 -7
- package/backend/dist/services/workPolicyService.d.ts.map +1 -1
- package/backend/dist/services/workPolicyService.js +50 -51
- package/backend/dist/services/workPolicyService.js.map +1 -1
- package/backend/dist/services/workPreviewProxyService.d.ts +8 -8
- package/backend/dist/services/workPreviewProxyService.d.ts.map +1 -1
- package/backend/dist/services/workPreviewProxyService.js +47 -44
- package/backend/dist/services/workPreviewProxyService.js.map +1 -1
- package/backend/dist/services/workRuntimeDriver.d.ts +21 -18
- package/backend/dist/services/workRuntimeDriver.d.ts.map +1 -1
- package/backend/dist/services/workRuntimeDriver.js +69 -20
- package/backend/dist/services/workRuntimeDriver.js.map +1 -1
- package/backend/dist/services/workRuntimeService.d.ts +18 -13
- package/backend/dist/services/workRuntimeService.d.ts.map +1 -1
- package/backend/dist/services/workRuntimeService.js +438 -194
- package/backend/dist/services/workRuntimeService.js.map +1 -1
- package/backend/dist/services/workRuntimeShared.d.ts +2 -0
- package/backend/dist/services/workRuntimeShared.d.ts.map +1 -1
- package/backend/dist/services/workRuntimeShared.js.map +1 -1
- package/backend/dist/services/workTaskService.d.ts +42 -36
- package/backend/dist/services/workTaskService.d.ts.map +1 -1
- package/backend/dist/services/workTaskService.js +445 -350
- package/backend/dist/services/workTaskService.js.map +1 -1
- package/backend/dist/services/workTerminalService.d.ts +1 -1
- package/backend/dist/services/workTerminalService.d.ts.map +1 -1
- package/backend/dist/services/workTerminalService.js +33 -6
- package/backend/dist/services/workTerminalService.js.map +1 -1
- package/backend/dist/storage.d.ts +72 -40
- package/backend/dist/storage.d.ts.map +1 -1
- package/backend/dist/storage.js +312 -660
- package/backend/dist/storage.js.map +1 -1
- package/backend/dist/types/index.d.ts +28 -0
- package/backend/dist/types/index.d.ts.map +1 -1
- package/backend/dist/types/index.js.map +1 -1
- package/backend/dist/types/work.d.ts +7 -2
- package/backend/dist/types/work.d.ts.map +1 -1
- package/backend/dist/utils/chatCancellation.d.ts +48 -0
- package/backend/dist/utils/chatCancellation.d.ts.map +1 -0
- package/backend/dist/utils/chatCancellation.js +152 -0
- package/backend/dist/utils/chatCancellation.js.map +1 -0
- package/backend/dist/utils/chatDocumentContext.d.ts +1 -1
- package/backend/dist/utils/chatDocumentContext.d.ts.map +1 -1
- package/backend/dist/utils/chatDocumentContext.js +11 -5
- package/backend/dist/utils/chatDocumentContext.js.map +1 -1
- package/backend/dist/utils/chatStreamCoalescer.d.ts +15 -0
- package/backend/dist/utils/chatStreamCoalescer.d.ts.map +1 -0
- package/backend/dist/utils/chatStreamCoalescer.js +59 -0
- package/backend/dist/utils/chatStreamCoalescer.js.map +1 -0
- package/backend/dist/utils/dataDirectory.d.ts +49 -0
- package/backend/dist/utils/dataDirectory.d.ts.map +1 -0
- package/backend/dist/utils/dataDirectory.js +291 -0
- package/backend/dist/utils/dataDirectory.js.map +1 -0
- package/backend/dist/utils/generationUtils.d.ts.map +1 -1
- package/backend/dist/utils/generationUtils.js +18 -6
- package/backend/dist/utils/generationUtils.js.map +1 -1
- package/backend/dist/utils/jwt.d.ts.map +1 -1
- package/backend/dist/utils/jwt.js +2 -3
- package/backend/dist/utils/jwt.js.map +1 -1
- package/backend/dist/utils/ollamaModelDefaults.d.ts.map +1 -1
- package/backend/dist/utils/ollamaModelDefaults.js +2 -7
- package/backend/dist/utils/ollamaModelDefaults.js.map +1 -1
- package/backend/dist/utils/ollamaStreaming.d.ts +2 -1
- package/backend/dist/utils/ollamaStreaming.d.ts.map +1 -1
- package/backend/dist/utils/ollamaStreaming.js +49 -11
- package/backend/dist/utils/ollamaStreaming.js.map +1 -1
- package/backend/dist/utils/pluginConnectionVariables.d.ts.map +1 -1
- package/backend/dist/utils/pluginConnectionVariables.js +11 -3
- package/backend/dist/utils/pluginConnectionVariables.js.map +1 -1
- package/backend/dist/utils/pluginDefinitionTrust.d.ts.map +1 -1
- package/backend/dist/utils/pluginDefinitionTrust.js +4 -3
- package/backend/dist/utils/pluginDefinitionTrust.js.map +1 -1
- package/backend/dist/utils/pluginStreaming.d.ts +2 -1
- package/backend/dist/utils/pluginStreaming.d.ts.map +1 -1
- package/backend/dist/utils/pluginStreaming.js +5 -1
- package/backend/dist/utils/pluginStreaming.js.map +1 -1
- package/backend/dist/utils/pluginUpload.d.ts +1 -0
- package/backend/dist/utils/pluginUpload.d.ts.map +1 -1
- package/backend/dist/utils/pluginUpload.js +9 -2
- package/backend/dist/utils/pluginUpload.js.map +1 -1
- package/backend/dist/utils/pluginValidation.d.ts.map +1 -1
- package/backend/dist/utils/pluginValidation.js +29 -1
- package/backend/dist/utils/pluginValidation.js.map +1 -1
- package/backend/dist/utils/sttAudioUpload.d.ts +24 -0
- package/backend/dist/utils/sttAudioUpload.d.ts.map +1 -0
- package/backend/dist/utils/sttAudioUpload.js +500 -0
- package/backend/dist/utils/sttAudioUpload.js.map +1 -0
- package/backend/dist/utils/ttsVoiceCloneUpload.d.ts +34 -0
- package/backend/dist/utils/ttsVoiceCloneUpload.d.ts.map +1 -0
- package/backend/dist/utils/ttsVoiceCloneUpload.js +224 -0
- package/backend/dist/utils/ttsVoiceCloneUpload.js.map +1 -0
- package/backend/dist/utils/websocketMessages.d.ts +2 -1
- package/backend/dist/utils/websocketMessages.d.ts.map +1 -1
- package/backend/dist/utils/websocketMessages.js +16 -2
- package/backend/dist/utils/websocketMessages.js.map +1 -1
- package/backend/dist/websocketServer.d.ts +4 -1
- package/backend/dist/websocketServer.d.ts.map +1 -1
- package/backend/dist/websocketServer.js +290 -44
- package/backend/dist/websocketServer.js.map +1 -1
- package/backend/dist/workTerminalServer.d.ts +9 -0
- package/backend/dist/workTerminalServer.d.ts.map +1 -1
- package/backend/dist/workTerminalServer.js +221 -52
- package/backend/dist/workTerminalServer.js.map +1 -1
- package/backend/dist/worker.d.ts +2 -0
- package/backend/dist/worker.d.ts.map +1 -0
- package/backend/dist/worker.js +250 -0
- package/backend/dist/worker.js.map +1 -0
- package/backend/package.json +19 -9
- package/bin/cli.js +126 -99
- package/bin/runtime-paths.js +108 -0
- package/frontend/dist/artifact-runtime/.build-fingerprint +1 -1
- package/frontend/dist/artifact-runtime/framer-motion.js +5 -5
- package/frontend/dist/artifact-runtime/lucide-react.js +1 -1
- package/frontend/dist/assets/index-CUhEG7E2.js +33 -0
- package/frontend/dist/assets/index-kxtZQLV6.css +1 -0
- package/frontend/dist/assets/{markdown-math-ClQbWekD.css → markdown-math-ClTedVi7.css} +1 -1
- package/frontend/dist/index.html +18 -18
- package/frontend/dist/js/{ArtifactContainer-Dy2Q0iIL.js → ArtifactContainer-BTEDhBnv.js} +1 -1
- package/frontend/dist/js/{ArtifactDemoPage-K79dWshB.js → ArtifactDemoPage-B0gN3YTl.js} +1 -1
- package/frontend/dist/js/{ArtifactSandboxFrame-DhqLNUtY.js → ArtifactSandboxFrame-CLBXQkZs.js} +3 -3
- package/frontend/dist/js/{ArtifactSlideOutPanel-Cl8JG7bz.js → ArtifactSlideOutPanel-CfqHPFdE.js} +1 -1
- package/frontend/dist/js/{Button-CTXHujOd.js → Button-BV44cTnj.js} +1 -1
- package/frontend/dist/js/ChatPage-DIkAXZWA.js +23 -0
- package/frontend/dist/js/{FirstTimeSetup-kHhRzGJ8.js → FirstTimeSetup-B8phXGNA.js} +1 -1
- package/frontend/dist/js/GalleryPage-W4uI043I.js +1 -0
- package/frontend/dist/js/{HomePage-C1L8WAXL.js → HomePage-DlxehbyO.js} +1 -1
- package/frontend/dist/js/{LibreClawPage-Dyua8IUu.js → LibreClawPage-CgD0_G_F.js} +1 -1
- package/frontend/dist/js/{ModelManagerModals-CuMRGUd-.js → ModelManagerModals-D7jIT3v1.js} +1 -1
- package/frontend/dist/js/{ModelSelector-CqHc-Ln4.js → ModelSelector-BYxJU1UV.js} +1 -1
- package/frontend/dist/js/ModelsPage-C4XdCKP5.js +2 -0
- package/frontend/dist/js/NotesPage-CDECOl4V.js +1 -0
- package/frontend/dist/js/{OptimizedSyntaxHighlighter-CWYUn9Oe.js → OptimizedSyntaxHighlighter-XwqZEoTf.js} +1 -1
- package/frontend/dist/js/{PersonasPage-D_6WBCH5.js → PersonasPage-CjSLPrgS.js} +2 -2
- package/frontend/dist/js/PluginUsagePage-DJOXJuH4.js +1 -0
- package/frontend/dist/js/RichMessageContent-Debeh6bi.js +3 -0
- package/frontend/dist/js/SettingsModal-cUqAeYUP.js +1 -0
- package/frontend/dist/js/{SettingsToggle-DLHlCDBl.js → SettingsToggle-WTa0rgvY.js} +1 -1
- package/frontend/dist/js/{SystemPage-BMWEet9e.js → SystemPage-DxPw0GS7.js} +1 -1
- package/frontend/dist/js/UserManagementPage-CEdYFe_Z.js +1 -0
- package/frontend/dist/js/WorkPage-DDVeuG_9.js +6 -0
- package/frontend/dist/js/api-IzobHGND.js +14 -0
- package/frontend/dist/js/appStore-DKwC2vgn.js +2 -0
- package/frontend/dist/js/ar-xTSvTq05.js +2 -0
- package/frontend/dist/js/authStore-OaTuapL7.js +4 -0
- package/frontend/dist/js/{babel-CmENXdZw.js → babel-D24oDI9y.js} +1 -1
- package/frontend/dist/js/bn-iYAsohEA.js +2 -0
- package/frontend/dist/js/chatStore-DXGUVLXD.js +3 -0
- package/frontend/dist/js/{config-DkV1ka7I.js → config-DPEEuTAe.js} +1 -1
- package/frontend/dist/js/cs-YBHN88Hb.js +2 -0
- package/frontend/dist/js/da-D7qlLy_k.js +2 -0
- package/frontend/dist/js/de-DV671k2c.js +2 -0
- package/frontend/dist/js/es-kyBgzNq-.js +2 -0
- package/frontend/dist/js/{estree-D5KP-qbw.js → estree-ChwJsD2w.js} +1 -1
- package/frontend/dist/js/fr-Cw1vut7I.js +2 -0
- package/frontend/dist/js/hi-DWEFC024.js +2 -0
- package/frontend/dist/js/{html-Cm9c2akd.js → html-DFrVjciF.js} +1 -1
- package/frontend/dist/js/id-DlMHjjy0.js +2 -0
- package/frontend/dist/js/is-B9E_a7dG.js +2 -0
- package/frontend/dist/js/it-DawmVbLC.js +2 -0
- package/frontend/dist/js/ja-DmVvwY3W.js +2 -0
- package/frontend/dist/js/ko-DzOPpkVs.js +2 -0
- package/frontend/dist/js/{markdown-B2u7CnKN.js → markdown-FLLx7b67.js} +1 -1
- package/frontend/dist/js/markdown-core-BmPPZiuD.js +31 -0
- package/frontend/dist/js/{markdown-math-B7FlYsmr.js → markdown-math-mH7AZ_mb.js} +6 -6
- package/frontend/dist/js/{messageCodeStyles-DalG2j6U.js → messageCodeStyles-CBkkZY4n.js} +1 -1
- package/frontend/dist/js/ms-DpsaOPht.js +2 -0
- package/frontend/dist/js/nl-B1d8W22n.js +2 -0
- package/frontend/dist/js/pl-nCncRVgt.js +2 -0
- package/frontend/dist/js/{postcss-B5WIGhAY.js → postcss-Bx9CTcIc.js} +1 -1
- package/frontend/dist/js/pt-DHw8fGuu.js +2 -0
- package/frontend/dist/js/{react-vendor-DPNXrO-8.js → react-vendor-C5yShNlM.js} +1 -1
- package/frontend/dist/js/{router-vendor-Ca9zqOqT.js → router-vendor-CbPDks39.js} +1 -1
- package/frontend/dist/js/ru-Derl_YP_.js +2 -0
- package/frontend/dist/js/{standalone-Dwm1daef.js → standalone-i8-5bg5p.js} +1 -1
- package/frontend/dist/js/sv-pJAfBVo0.js +2 -0
- package/frontend/dist/js/{syntax-highlight-Ca9bHsaz.js → syntax-highlight-3EEX6CGL.js} +3 -3
- package/frontend/dist/js/th-C_7fIGnk.js +2 -0
- package/frontend/dist/js/tr-CPqsJvaP.js +2 -0
- package/frontend/dist/js/{typescript-CwieSptM.js → typescript-CQ3x-Uni.js} +1 -1
- package/frontend/dist/js/{ui-BnDZpjfc.js → ui-BHhR3Vok.js} +2 -2
- package/frontend/dist/js/ui-vendor-D3Ahl1x5.js +177 -0
- package/frontend/dist/js/uk-3o8P_kFi.js +2 -0
- package/frontend/dist/js/{useTranslation-CXY69qNk.js → useTranslation-C3ei3mJq.js} +1 -1
- package/frontend/dist/js/{utils-BM0_0iFj.js → utils-CuC1beTY.js} +1 -1
- package/frontend/dist/js/{utils-vendor-1zob7nK9.js → utils-vendor-BBa8OxtB.js} +1 -1
- package/frontend/dist/js/vi-Dv6N7OVD.js +2 -0
- package/frontend/dist/js/{workApi-BOS7crs9.js → workApi-Czu69yWS.js} +2 -2
- package/frontend/dist/js/{yaml-QD4znPfZ.js → yaml-DioTxVLA.js} +1 -1
- package/frontend/dist/js/zh-qg5iqtPi.js +2 -0
- package/package.json +16 -5
- package/plugins/huggingface.json +12 -3
- package/plugins/llama-cpp.json +18 -6
- package/plugins/longcat-audiodit.json +114 -0
- package/plugins/openai.json +18 -0
- package/frontend/dist/assets/index-BBpNbfKW.js +0 -16
- package/frontend/dist/assets/index-BLATyFmD.css +0 -1
- package/frontend/dist/js/ChatPage-BBayfMLS.js +0 -16
- package/frontend/dist/js/GalleryPage-By8VI39Q.js +0 -1
- package/frontend/dist/js/ModelsPage-ODeXhDDk.js +0 -2
- package/frontend/dist/js/NotesPage-CApzDjOq.js +0 -1
- package/frontend/dist/js/PluginUsagePage-kutS6SOd.js +0 -1
- package/frontend/dist/js/RichMessageContent-g6WT75Te.js +0 -3
- package/frontend/dist/js/SettingsModal-B7z51BCx.js +0 -1
- package/frontend/dist/js/UserManagementPage-D08lM51c.js +0 -1
- package/frontend/dist/js/WorkPage-DdVLefsK.js +0 -6
- package/frontend/dist/js/api-CLEmGcEh.js +0 -14
- package/frontend/dist/js/appStore-CGdhvp9P.js +0 -2
- package/frontend/dist/js/ar-BTmB2WVm.js +0 -2
- package/frontend/dist/js/authStore-Dh3beEOq.js +0 -4
- package/frontend/dist/js/bn-CQnH7YVT.js +0 -2
- package/frontend/dist/js/chatStore-CDeYWL_q.js +0 -3
- package/frontend/dist/js/cs-oTTZkQXr.js +0 -2
- package/frontend/dist/js/da-Br0gB6J6.js +0 -2
- package/frontend/dist/js/de-DE2iztTF.js +0 -2
- package/frontend/dist/js/es-DgthfVtl.js +0 -2
- package/frontend/dist/js/fr-BjxjFwPh.js +0 -2
- package/frontend/dist/js/hi-D1q7E-9N.js +0 -2
- package/frontend/dist/js/id-CDJZqLTF.js +0 -2
- package/frontend/dist/js/is-BU7Um_Tq.js +0 -2
- package/frontend/dist/js/it-CdAxr8P_.js +0 -2
- package/frontend/dist/js/ja-BLbQwz9u.js +0 -2
- package/frontend/dist/js/ko-CY5lpkAe.js +0 -2
- package/frontend/dist/js/markdown-core-DHnR5Hw8.js +0 -16
- package/frontend/dist/js/ms-tQ8AYXEQ.js +0 -2
- package/frontend/dist/js/nl-CRNi2oWT.js +0 -2
- package/frontend/dist/js/pl-CWtFRS_W.js +0 -2
- package/frontend/dist/js/pt-C7SPoLF8.js +0 -2
- package/frontend/dist/js/ru-Dz4AX8xc.js +0 -2
- package/frontend/dist/js/sv-ETy5-boa.js +0 -2
- package/frontend/dist/js/th-DpuMqvxU.js +0 -2
- package/frontend/dist/js/tr-C-1AYAqg.js +0 -2
- package/frontend/dist/js/ui-vendor-xUzKqAXI.js +0 -177
- package/frontend/dist/js/uk-CyS680gr.js +0 -2
- package/frontend/dist/js/vi-BG8HuiTz.js +0 -2
- package/frontend/dist/js/zh-NCs2mkHj.js +0 -2
|
@@ -0,0 +1,1185 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Libre WebUI
|
|
3
|
+
* Copyright (C) 2025 Kroonen AI, Inc.
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
*/
|
|
6
|
+
import crypto from 'node:crypto';
|
|
7
|
+
import { DurableJobError, } from './durableJobTypes.js';
|
|
8
|
+
import { DELETION_LIFECYCLE_RECOVERY_REFERENCE_PREFIX, OWNER_DELETE_CONTENT_JOB_TYPE, OWNER_DELETE_CONTENT_RECOVERABLE_ERROR_CODES, RESOURCE_DELETE_JOB_TYPE, RESOURCE_DELETE_RECOVERABLE_ERROR_CODES, } from './domainJobContracts.js';
|
|
9
|
+
const integer = (value, field) => {
|
|
10
|
+
const parsed = typeof value === 'number' ? value : Number(value);
|
|
11
|
+
if (!Number.isSafeInteger(parsed)) {
|
|
12
|
+
throw new DurableJobError('storage-error', `Invalid PostgreSQL ${field}`);
|
|
13
|
+
}
|
|
14
|
+
return parsed;
|
|
15
|
+
};
|
|
16
|
+
const optionalInteger = (value, field) => (value === null ? null : integer(value, field));
|
|
17
|
+
const metadata = (row) => ({
|
|
18
|
+
id: row.id,
|
|
19
|
+
jobType: row.job_type,
|
|
20
|
+
actorUserId: row.actor_user_id,
|
|
21
|
+
state: row.state,
|
|
22
|
+
priority: row.priority,
|
|
23
|
+
attemptCount: row.attempt_count,
|
|
24
|
+
maxAttempts: row.max_attempts,
|
|
25
|
+
availableAt: integer(row.available_at, 'available_at'),
|
|
26
|
+
cancellationRequestedAt: optionalInteger(row.cancellation_requested_at, 'cancellation_requested_at'),
|
|
27
|
+
progressCurrent: integer(row.progress_current, 'progress_current'),
|
|
28
|
+
progressTotal: integer(row.progress_total, 'progress_total'),
|
|
29
|
+
progressMessage: row.progress_message,
|
|
30
|
+
resultReference: row.result_reference,
|
|
31
|
+
errorCode: row.error_code,
|
|
32
|
+
errorSummary: row.error_summary,
|
|
33
|
+
createdAt: integer(row.created_at, 'created_at'),
|
|
34
|
+
updatedAt: integer(row.updated_at, 'updated_at'),
|
|
35
|
+
startedAt: optionalInteger(row.started_at, 'started_at'),
|
|
36
|
+
finishedAt: optionalInteger(row.finished_at, 'finished_at'),
|
|
37
|
+
});
|
|
38
|
+
const lease = (row) => {
|
|
39
|
+
if (row.state !== 'running' ||
|
|
40
|
+
!row.lease_owner ||
|
|
41
|
+
row.lease_expires_at === null) {
|
|
42
|
+
throw new DurableJobError('storage-error', 'Claimed PostgreSQL job has an invalid lease');
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
...metadata(row),
|
|
46
|
+
workerId: row.lease_owner,
|
|
47
|
+
leaseToken: integer(row.lease_token, 'lease_token'),
|
|
48
|
+
leaseExpiresAt: integer(row.lease_expires_at, 'lease_expires_at'),
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const attempt = (row) => ({
|
|
52
|
+
jobId: row.job_id,
|
|
53
|
+
attemptNumber: row.attempt_number,
|
|
54
|
+
leaseToken: integer(row.lease_token, 'attempt lease_token'),
|
|
55
|
+
workerId: row.worker_id,
|
|
56
|
+
startedAt: integer(row.started_at, 'attempt started_at'),
|
|
57
|
+
lastHeartbeatAt: integer(row.last_heartbeat_at, 'attempt last_heartbeat_at'),
|
|
58
|
+
finishedAt: optionalInteger(row.finished_at, 'attempt finished_at'),
|
|
59
|
+
outcome: row.outcome,
|
|
60
|
+
errorCode: row.error_code,
|
|
61
|
+
errorSummary: row.error_summary,
|
|
62
|
+
});
|
|
63
|
+
/** Async PostgreSQL durable queue with row locks and SKIP LOCKED claiming. */
|
|
64
|
+
export class PostgresDurableJobRepository {
|
|
65
|
+
constructor(database, now = Date.now) {
|
|
66
|
+
this.database = database;
|
|
67
|
+
this.now = now;
|
|
68
|
+
}
|
|
69
|
+
async find(executor, id, lock = false) {
|
|
70
|
+
const result = await executor.query(`SELECT * FROM platform_jobs WHERE id = $1${lock ? ' FOR UPDATE' : ''}`, [id]);
|
|
71
|
+
return result.rows[0];
|
|
72
|
+
}
|
|
73
|
+
async appendEvent(executor, input) {
|
|
74
|
+
// A transaction-scoped lock closes the absent-row race: a UNIQUE key
|
|
75
|
+
// cannot lock a row that does not exist yet. All replicas serialize the
|
|
76
|
+
// stable event identity before inspecting or advancing a stream head.
|
|
77
|
+
await executor.query('SELECT pg_advisory_xact_lock(hashtextextended($1::text, 0))', [input.eventId]);
|
|
78
|
+
const existing = await executor.query(`SELECT global_cursor, request_fingerprint
|
|
79
|
+
FROM platform_events WHERE event_id = $1`, [input.eventId]);
|
|
80
|
+
if (existing.rows[0]) {
|
|
81
|
+
if (existing.rows[0].request_fingerprint !== input.requestFingerprint) {
|
|
82
|
+
throw new DurableJobError('conflict', 'Durable event identity was reused for different content');
|
|
83
|
+
}
|
|
84
|
+
return integer(existing.rows[0].global_cursor, 'event cursor');
|
|
85
|
+
}
|
|
86
|
+
await executor.query(`INSERT INTO platform_event_stream_heads (stream_id, last_sequence)
|
|
87
|
+
VALUES ($1, 0) ON CONFLICT (stream_id) DO NOTHING`, [input.streamId]);
|
|
88
|
+
const head = await executor.query(`UPDATE platform_event_stream_heads
|
|
89
|
+
SET last_sequence = last_sequence + 1
|
|
90
|
+
WHERE stream_id = $1
|
|
91
|
+
RETURNING last_sequence`, [input.streamId]);
|
|
92
|
+
const sequence = head.rows[0]
|
|
93
|
+
? integer(head.rows[0].last_sequence, 'event stream sequence')
|
|
94
|
+
: null;
|
|
95
|
+
if (sequence === null) {
|
|
96
|
+
throw new DurableJobError('storage-error', 'PostgreSQL event stream head is unavailable');
|
|
97
|
+
}
|
|
98
|
+
const inserted = await executor.query(`INSERT INTO platform_events
|
|
99
|
+
(event_id, request_fingerprint, stream_id, stream_sequence, event_type, subject_id,
|
|
100
|
+
actor_user_id, payload_format, payload, occurred_at)
|
|
101
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
|
102
|
+
RETURNING global_cursor`, [
|
|
103
|
+
input.eventId,
|
|
104
|
+
input.requestFingerprint,
|
|
105
|
+
input.streamId,
|
|
106
|
+
sequence,
|
|
107
|
+
input.eventType,
|
|
108
|
+
input.subjectId,
|
|
109
|
+
input.actorUserId,
|
|
110
|
+
input.payload.format,
|
|
111
|
+
input.payload.data,
|
|
112
|
+
input.occurredAt,
|
|
113
|
+
]);
|
|
114
|
+
if (!inserted.rows[0]) {
|
|
115
|
+
throw new DurableJobError('storage-error', 'PostgreSQL event append returned no cursor');
|
|
116
|
+
}
|
|
117
|
+
return integer(inserted.rows[0].global_cursor, 'event cursor');
|
|
118
|
+
}
|
|
119
|
+
appendJobEvent(executor, job, eventType, occurredAt) {
|
|
120
|
+
return this.appendEvent(executor, {
|
|
121
|
+
eventId: crypto.randomUUID(),
|
|
122
|
+
requestFingerprint: crypto
|
|
123
|
+
.createHash('sha256')
|
|
124
|
+
.update(`${job.id}\n${eventType}\n${occurredAt}`)
|
|
125
|
+
.digest('hex'),
|
|
126
|
+
streamId: `job:${job.id}`,
|
|
127
|
+
eventType,
|
|
128
|
+
subjectId: job.id,
|
|
129
|
+
actorUserId: job.actor_user_id,
|
|
130
|
+
payload: { format: 'reference', data: job.id },
|
|
131
|
+
occurredAt,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
async enqueue(input) {
|
|
135
|
+
return this.database.transaction(client => this.enqueueWithExecutor(client, input));
|
|
136
|
+
}
|
|
137
|
+
/** Enqueue inside an owning domain transaction/outbox boundary. */
|
|
138
|
+
async enqueueWithExecutor(executor, input) {
|
|
139
|
+
// PostgreSQL cannot row-lock a key that does not exist yet. Serialize the
|
|
140
|
+
// absent-row decision with a transaction-scoped advisory lock so two
|
|
141
|
+
// replicas using the same idempotency tuple cannot race into the unique
|
|
142
|
+
// constraint. A 64-bit hash collision only reduces concurrency; the
|
|
143
|
+
// exact tuple and fingerprint checks below still determine correctness.
|
|
144
|
+
await executor.query(`SELECT pg_advisory_xact_lock(hashtextextended($1, 0))`, [
|
|
145
|
+
`${Buffer.byteLength(input.actorUserId, 'utf8')}:${input.actorUserId}` +
|
|
146
|
+
`${Buffer.byteLength(input.idempotencyScope, 'utf8')}:${input.idempotencyScope}` +
|
|
147
|
+
`${input.idempotencyKeyHash.length}:${input.idempotencyKeyHash}`,
|
|
148
|
+
]);
|
|
149
|
+
const existing = await executor.query(`SELECT * FROM platform_jobs
|
|
150
|
+
WHERE actor_user_id = $1 AND idempotency_scope = $2
|
|
151
|
+
AND idempotency_key_hash = $3
|
|
152
|
+
FOR UPDATE`, [input.actorUserId, input.idempotencyScope, input.idempotencyKeyHash]);
|
|
153
|
+
if (existing.rows[0]) {
|
|
154
|
+
if (existing.rows[0].request_fingerprint !== input.requestFingerprint) {
|
|
155
|
+
throw new DurableJobError('conflict', 'The idempotency key is already bound to a different request');
|
|
156
|
+
}
|
|
157
|
+
return metadata(existing.rows[0]);
|
|
158
|
+
}
|
|
159
|
+
const timestamp = this.now();
|
|
160
|
+
const inserted = await executor.query(`INSERT INTO platform_jobs
|
|
161
|
+
(id, job_type, actor_user_id, state, payload_format, payload,
|
|
162
|
+
idempotency_scope, idempotency_key_hash, request_fingerprint,
|
|
163
|
+
priority, attempt_count, max_attempts, available_at, lease_token,
|
|
164
|
+
progress_current, progress_total, created_at, updated_at)
|
|
165
|
+
VALUES ($1, $2, $3, 'queued', $4, $5, $6, $7, $8, $9, 0, $10,
|
|
166
|
+
$11, 0, 0, 100, $12, $12)
|
|
167
|
+
RETURNING *`, [
|
|
168
|
+
input.id,
|
|
169
|
+
input.jobType,
|
|
170
|
+
input.actorUserId,
|
|
171
|
+
input.payload.format,
|
|
172
|
+
input.payload.data,
|
|
173
|
+
input.idempotencyScope,
|
|
174
|
+
input.idempotencyKeyHash,
|
|
175
|
+
input.requestFingerprint,
|
|
176
|
+
input.priority,
|
|
177
|
+
input.maxAttempts,
|
|
178
|
+
input.availableAt,
|
|
179
|
+
timestamp,
|
|
180
|
+
]);
|
|
181
|
+
const row = inserted.rows[0];
|
|
182
|
+
if (!row)
|
|
183
|
+
throw new DurableJobError('storage-error', 'PostgreSQL job insert returned no row');
|
|
184
|
+
await this.appendJobEvent(executor, row, 'job.queued', timestamp);
|
|
185
|
+
return metadata(row);
|
|
186
|
+
}
|
|
187
|
+
async appendEventTransaction(input) {
|
|
188
|
+
try {
|
|
189
|
+
return await this.database.transaction(client => this.appendEvent(client, input));
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
// Resolve COMMIT-with-lost-acknowledgement on a new pooled connection.
|
|
193
|
+
// The deterministic identity/fingerprint proves this exact event rather
|
|
194
|
+
// than blindly appending a second logical occurrence.
|
|
195
|
+
try {
|
|
196
|
+
const existing = await this.database.query(`SELECT global_cursor, request_fingerprint
|
|
197
|
+
FROM platform_events WHERE event_id = $1`, [input.eventId]);
|
|
198
|
+
if (existing.rows[0]) {
|
|
199
|
+
if (existing.rows[0].request_fingerprint !== input.requestFingerprint) {
|
|
200
|
+
throw new DurableJobError('conflict', 'Durable event identity was reused for different content');
|
|
201
|
+
}
|
|
202
|
+
return integer(existing.rows[0].global_cursor, 'event cursor');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch (resolutionError) {
|
|
206
|
+
if (resolutionError instanceof DurableJobError)
|
|
207
|
+
throw resolutionError;
|
|
208
|
+
}
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async requestChatCancellation(input) {
|
|
213
|
+
try {
|
|
214
|
+
return await this.database.transaction(async (client) => {
|
|
215
|
+
await client.query(`INSERT INTO platform_event_stream_heads (stream_id, last_sequence)
|
|
216
|
+
VALUES ($1, 0) ON CONFLICT (stream_id) DO NOTHING`, [input.event.streamId]);
|
|
217
|
+
await client.query(`SELECT last_sequence FROM platform_event_stream_heads
|
|
218
|
+
WHERE stream_id = $1 FOR UPDATE`, [input.event.streamId]);
|
|
219
|
+
const completion = await client.query(`SELECT global_cursor FROM platform_events
|
|
220
|
+
WHERE event_id = $1 AND stream_id = $2
|
|
221
|
+
AND event_type = 'chat.done.v1'
|
|
222
|
+
AND subject_id = $3 AND actor_user_id = $4`, [
|
|
223
|
+
input.doneEventId,
|
|
224
|
+
input.event.streamId,
|
|
225
|
+
input.event.subjectId,
|
|
226
|
+
input.actorUserId,
|
|
227
|
+
]);
|
|
228
|
+
if (completion.rows[0]) {
|
|
229
|
+
return {
|
|
230
|
+
outcome: 'completion-won',
|
|
231
|
+
cursor: integer(completion.rows[0].global_cursor, 'event cursor'),
|
|
232
|
+
job: null,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
const cursor = await this.appendEvent(client, input.event);
|
|
236
|
+
const naturalJob = await client.query(`SELECT * FROM platform_jobs
|
|
237
|
+
WHERE actor_user_id = $1 AND idempotency_scope = $2
|
|
238
|
+
AND idempotency_key_hash = $3 FOR UPDATE`, [input.actorUserId, input.idempotencyScope, input.idempotencyKeyHash]);
|
|
239
|
+
return {
|
|
240
|
+
outcome: 'cancellation-recorded',
|
|
241
|
+
cursor,
|
|
242
|
+
job: naturalJob.rows[0]
|
|
243
|
+
? await this.requestCancellationWithExecutor(client, naturalJob.rows[0].id, input.actorUserId, 'user-requested')
|
|
244
|
+
: null,
|
|
245
|
+
};
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
// Resolve an exact decision whose COMMIT acknowledgement was lost.
|
|
250
|
+
try {
|
|
251
|
+
const cancellation = await this.database.query(`SELECT global_cursor, request_fingerprint FROM platform_events
|
|
252
|
+
WHERE event_id = $1 AND stream_id = $2
|
|
253
|
+
AND event_type = 'chat.cancel-requested.v1'
|
|
254
|
+
AND subject_id = $3 AND actor_user_id = $4`, [
|
|
255
|
+
input.event.eventId,
|
|
256
|
+
input.event.streamId,
|
|
257
|
+
input.event.subjectId,
|
|
258
|
+
input.actorUserId,
|
|
259
|
+
]);
|
|
260
|
+
if (cancellation.rows[0]) {
|
|
261
|
+
if (cancellation.rows[0].request_fingerprint !==
|
|
262
|
+
input.event.requestFingerprint) {
|
|
263
|
+
throw new DurableJobError('conflict', 'Chat cancellation identity was reused');
|
|
264
|
+
}
|
|
265
|
+
const job = await this.database.query(`SELECT * FROM platform_jobs
|
|
266
|
+
WHERE actor_user_id = $1 AND idempotency_scope = $2
|
|
267
|
+
AND idempotency_key_hash = $3`, [
|
|
268
|
+
input.actorUserId,
|
|
269
|
+
input.idempotencyScope,
|
|
270
|
+
input.idempotencyKeyHash,
|
|
271
|
+
]);
|
|
272
|
+
return {
|
|
273
|
+
outcome: 'cancellation-recorded',
|
|
274
|
+
cursor: integer(cancellation.rows[0].global_cursor, 'event cursor'),
|
|
275
|
+
job: job.rows[0] ? metadata(job.rows[0]) : null,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
const completion = await this.database.query(`SELECT global_cursor FROM platform_events
|
|
279
|
+
WHERE event_id = $1 AND stream_id = $2
|
|
280
|
+
AND event_type = 'chat.done.v1'
|
|
281
|
+
AND subject_id = $3 AND actor_user_id = $4`, [
|
|
282
|
+
input.doneEventId,
|
|
283
|
+
input.event.streamId,
|
|
284
|
+
input.event.subjectId,
|
|
285
|
+
input.actorUserId,
|
|
286
|
+
]);
|
|
287
|
+
if (completion.rows[0]) {
|
|
288
|
+
return {
|
|
289
|
+
outcome: 'completion-won',
|
|
290
|
+
cursor: integer(completion.rows[0].global_cursor, 'event cursor'),
|
|
291
|
+
job: null,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch (resolutionError) {
|
|
296
|
+
if (resolutionError instanceof DurableJobError)
|
|
297
|
+
throw resolutionError;
|
|
298
|
+
}
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
async publishChatCompletionWithExecutor(executor, input) {
|
|
303
|
+
// Lock order is stream decision -> job lease -> chat session. Enqueue and
|
|
304
|
+
// cancellation use the same prefix, so no path can invert head and job.
|
|
305
|
+
await executor.query(`INSERT INTO platform_event_stream_heads (stream_id, last_sequence)
|
|
306
|
+
VALUES ($1, 0) ON CONFLICT (stream_id) DO NOTHING`, [input.event.streamId]);
|
|
307
|
+
await executor.query(`SELECT last_sequence FROM platform_event_stream_heads
|
|
308
|
+
WHERE stream_id = $1 FOR UPDATE`, [input.event.streamId]);
|
|
309
|
+
const cancellation = await executor.query(`SELECT 1 FROM platform_events
|
|
310
|
+
WHERE event_id = $1 AND stream_id = $2
|
|
311
|
+
AND event_type = 'chat.cancel-requested.v1'
|
|
312
|
+
AND subject_id = $3 AND actor_user_id = $4`, [
|
|
313
|
+
input.cancellationEventId,
|
|
314
|
+
input.event.streamId,
|
|
315
|
+
input.message.id,
|
|
316
|
+
input.actorUserId,
|
|
317
|
+
]);
|
|
318
|
+
if (cancellation.rows[0]) {
|
|
319
|
+
throw new DurableJobError('cancelled', 'Durable job was cancelled');
|
|
320
|
+
}
|
|
321
|
+
const job = await this.find(executor, input.lease.jobId, true);
|
|
322
|
+
if (!job) {
|
|
323
|
+
throw new DurableJobError('lease-lost', 'Durable job lease was lost');
|
|
324
|
+
}
|
|
325
|
+
if (job.actor_user_id !== input.actorUserId ||
|
|
326
|
+
job.job_type !== input.expectedJobType ||
|
|
327
|
+
job.idempotency_scope !== input.expectedIdempotencyScope ||
|
|
328
|
+
job.idempotency_key_hash !== input.expectedIdempotencyKeyHash) {
|
|
329
|
+
throw new DurableJobError('conflict', 'Chat completion does not match its durable job');
|
|
330
|
+
}
|
|
331
|
+
const assertLease = (timestamp) => {
|
|
332
|
+
if (job.cancellation_requested_at !== null) {
|
|
333
|
+
throw new DurableJobError('cancelled', 'Durable job was cancelled');
|
|
334
|
+
}
|
|
335
|
+
if (job.state !== 'running' ||
|
|
336
|
+
job.lease_owner !== input.lease.workerId ||
|
|
337
|
+
integer(job.lease_token, 'lease_token') !== input.lease.leaseToken ||
|
|
338
|
+
job.lease_expires_at === null ||
|
|
339
|
+
integer(job.lease_expires_at, 'lease_expires_at') <= timestamp) {
|
|
340
|
+
throw new DurableJobError('lease-lost', 'Durable job lease was lost');
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
assertLease(this.now());
|
|
344
|
+
const session = await executor.query('SELECT user_id FROM sessions WHERE id = $1 FOR UPDATE', [input.sessionId]);
|
|
345
|
+
if (!session.rows[0] ||
|
|
346
|
+
session.rows[0].user_id !== input.actorUserId ||
|
|
347
|
+
input.message.sessionId !== input.sessionId) {
|
|
348
|
+
throw new DurableJobError('conflict', 'Chat completion session is unavailable');
|
|
349
|
+
}
|
|
350
|
+
// The session lock can wait behind another chat mutation while this
|
|
351
|
+
// transaction holds the job row, preventing its heartbeat from extending.
|
|
352
|
+
// Never authorize publication with the pre-wait lease sample.
|
|
353
|
+
assertLease(this.now());
|
|
354
|
+
const existingEvent = await executor.query('SELECT 1 FROM platform_events WHERE event_id = $1', [input.event.eventId]);
|
|
355
|
+
const existingMessage = await executor.query(`SELECT role FROM session_messages
|
|
356
|
+
WHERE id = $1 AND session_id = $2`, [input.message.id, input.sessionId]);
|
|
357
|
+
if (existingEvent.rows[0]) {
|
|
358
|
+
if (existingMessage.rows[0]?.role !== 'assistant') {
|
|
359
|
+
throw new DurableJobError('storage-error', 'Durable chat completion event has no assistant message');
|
|
360
|
+
}
|
|
361
|
+
return this.appendEvent(executor, input.event);
|
|
362
|
+
}
|
|
363
|
+
if (existingMessage.rows[0]) {
|
|
364
|
+
throw new DurableJobError('conflict', 'Assistant message identity already exists without completion');
|
|
365
|
+
}
|
|
366
|
+
let branchIndex = 0;
|
|
367
|
+
if (input.message.parentId) {
|
|
368
|
+
const branchRoot = await executor.query(`SELECT role FROM session_messages
|
|
369
|
+
WHERE id = $1 AND session_id = $2`, [input.message.parentId, input.sessionId]);
|
|
370
|
+
if (branchRoot.rows[0]?.role !== 'assistant') {
|
|
371
|
+
throw new DurableJobError('conflict', 'Chat completion branch root is unavailable');
|
|
372
|
+
}
|
|
373
|
+
const branch = await executor.query(`SELECT COALESCE(MAX(branch_index), 0) + 1 AS next_index
|
|
374
|
+
FROM session_messages
|
|
375
|
+
WHERE session_id = $1 AND (id = $2 OR parent_id = $2)`, [input.sessionId, input.message.parentId]);
|
|
376
|
+
if (!branch.rows[0]) {
|
|
377
|
+
throw new DurableJobError('storage-error', 'Chat branch index is unavailable');
|
|
378
|
+
}
|
|
379
|
+
branchIndex = integer(branch.rows[0].next_index, 'branch index');
|
|
380
|
+
}
|
|
381
|
+
const position = await executor.query(`SELECT COALESCE(MAX(message_index), -1) + 1 AS next_index
|
|
382
|
+
FROM session_messages WHERE session_id = $1`, [input.sessionId]);
|
|
383
|
+
if (!position.rows[0]) {
|
|
384
|
+
throw new DurableJobError('storage-error', 'Chat message position is unavailable');
|
|
385
|
+
}
|
|
386
|
+
// Re-sample immediately before the first publication side effect. The same
|
|
387
|
+
// fresh fence is carried through the terminal job UPDATE below.
|
|
388
|
+
const timestamp = this.now();
|
|
389
|
+
assertLease(timestamp);
|
|
390
|
+
if (input.message.parentId) {
|
|
391
|
+
await executor.query(`UPDATE session_messages SET is_active = 0
|
|
392
|
+
WHERE session_id = $1 AND (id = $2 OR parent_id = $2)`, [input.sessionId, input.message.parentId]);
|
|
393
|
+
}
|
|
394
|
+
await executor.query(`INSERT INTO session_messages
|
|
395
|
+
(id, session_id, role, content, thinking, timestamp, message_index,
|
|
396
|
+
model, provider_metadata, images, statistics, artifacts,
|
|
397
|
+
parent_id, branch_index, is_active, rating)
|
|
398
|
+
VALUES ($1, $2, 'assistant', $3, $4, $5, $6, $7, $8, $9, $10,
|
|
399
|
+
$11, $12, $13, $14, $15)`, [
|
|
400
|
+
input.message.id,
|
|
401
|
+
input.sessionId,
|
|
402
|
+
input.message.content,
|
|
403
|
+
input.message.thinking,
|
|
404
|
+
input.message.timestamp,
|
|
405
|
+
integer(position.rows[0].next_index, 'message index'),
|
|
406
|
+
input.message.model,
|
|
407
|
+
input.message.providerMetadata,
|
|
408
|
+
input.message.images,
|
|
409
|
+
input.message.statistics,
|
|
410
|
+
input.message.artifacts,
|
|
411
|
+
input.message.parentId,
|
|
412
|
+
branchIndex,
|
|
413
|
+
input.message.parentId ? 1 : input.message.isActive,
|
|
414
|
+
input.message.rating,
|
|
415
|
+
]);
|
|
416
|
+
await executor.query(`UPDATE sessions SET updated_at = GREATEST(updated_at, $1)
|
|
417
|
+
WHERE id = $2 AND user_id = $3`, [timestamp, input.sessionId, input.actorUserId]);
|
|
418
|
+
const completionCursor = await this.appendEvent(executor, input.event);
|
|
419
|
+
// Message and event writes can themselves wait. Re-sample before the
|
|
420
|
+
// attempt/job terminal fence; throwing here rolls every prior write back.
|
|
421
|
+
const terminalTimestamp = this.now();
|
|
422
|
+
assertLease(terminalTimestamp);
|
|
423
|
+
if ((await this.finishAttempt(executor, job, 'succeeded', terminalTimestamp)) !== 1) {
|
|
424
|
+
throw new DurableJobError('lease-lost', 'Durable job attempt was lost');
|
|
425
|
+
}
|
|
426
|
+
const resultReference = `chat-message:${input.message.id}`;
|
|
427
|
+
const terminal = await executor.query(`UPDATE platform_jobs
|
|
428
|
+
SET state = 'succeeded', result_reference = $1,
|
|
429
|
+
lease_owner = NULL, lease_expires_at = NULL,
|
|
430
|
+
progress_current = progress_total,
|
|
431
|
+
progress_message = 'Chat response saved',
|
|
432
|
+
finished_at = $2, updated_at = $2
|
|
433
|
+
WHERE id = $3 AND state = 'running' AND lease_owner = $4
|
|
434
|
+
AND lease_token = $5 AND lease_expires_at > $6
|
|
435
|
+
AND actor_user_id = $7 AND job_type = $8
|
|
436
|
+
AND idempotency_scope = $9 AND idempotency_key_hash = $10
|
|
437
|
+
AND cancellation_requested_at IS NULL`, [
|
|
438
|
+
resultReference,
|
|
439
|
+
terminalTimestamp,
|
|
440
|
+
job.id,
|
|
441
|
+
input.lease.workerId,
|
|
442
|
+
input.lease.leaseToken,
|
|
443
|
+
terminalTimestamp,
|
|
444
|
+
input.actorUserId,
|
|
445
|
+
input.expectedJobType,
|
|
446
|
+
input.expectedIdempotencyScope,
|
|
447
|
+
input.expectedIdempotencyKeyHash,
|
|
448
|
+
]);
|
|
449
|
+
if (terminal.rowCount !== 1) {
|
|
450
|
+
throw new DurableJobError('lease-lost', 'Durable job lease was lost');
|
|
451
|
+
}
|
|
452
|
+
await this.appendJobEvent(executor, job, 'job.succeeded', terminalTimestamp);
|
|
453
|
+
return completionCursor;
|
|
454
|
+
}
|
|
455
|
+
async publishChatCompletion(input) {
|
|
456
|
+
try {
|
|
457
|
+
return await this.database.transaction(client => this.publishChatCompletionWithExecutor(client, input), { beforeCommit: input.beforeCommit });
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
// Resolve an exact COMMIT whose acknowledgement was lost. Both rows are
|
|
461
|
+
// required; observing only one would prove an invariant violation.
|
|
462
|
+
try {
|
|
463
|
+
const committed = await this.database.query(`SELECT e.global_cursor, e.request_fingerprint, m.role,
|
|
464
|
+
j.state, j.result_reference,
|
|
465
|
+
a.outcome AS attempt_outcome,
|
|
466
|
+
a.finished_at AS attempt_finished_at
|
|
467
|
+
FROM platform_events e
|
|
468
|
+
JOIN session_messages m
|
|
469
|
+
ON m.id = $2 AND m.session_id = $3
|
|
470
|
+
JOIN platform_jobs j ON j.id = $4
|
|
471
|
+
JOIN platform_job_attempts a
|
|
472
|
+
ON a.job_id = j.id
|
|
473
|
+
AND a.attempt_number = j.attempt_count
|
|
474
|
+
AND a.lease_token = $5
|
|
475
|
+
WHERE e.event_id = $1
|
|
476
|
+
AND j.actor_user_id = $6
|
|
477
|
+
AND j.job_type = $7
|
|
478
|
+
AND j.idempotency_scope = $8
|
|
479
|
+
AND j.idempotency_key_hash = $9`, [
|
|
480
|
+
input.event.eventId,
|
|
481
|
+
input.message.id,
|
|
482
|
+
input.sessionId,
|
|
483
|
+
input.lease.jobId,
|
|
484
|
+
input.lease.leaseToken,
|
|
485
|
+
input.actorUserId,
|
|
486
|
+
input.expectedJobType,
|
|
487
|
+
input.expectedIdempotencyScope,
|
|
488
|
+
input.expectedIdempotencyKeyHash,
|
|
489
|
+
]);
|
|
490
|
+
const row = committed.rows[0];
|
|
491
|
+
if (row) {
|
|
492
|
+
if (row.request_fingerprint !== input.event.requestFingerprint ||
|
|
493
|
+
row.role !== 'assistant' ||
|
|
494
|
+
row.state !== 'succeeded' ||
|
|
495
|
+
row.result_reference !== `chat-message:${input.message.id}` ||
|
|
496
|
+
row.attempt_outcome !== 'succeeded' ||
|
|
497
|
+
row.attempt_finished_at === null) {
|
|
498
|
+
throw new DurableJobError('conflict', 'Durable chat completion identity was reused');
|
|
499
|
+
}
|
|
500
|
+
return integer(row.global_cursor, 'event cursor');
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
catch (resolutionError) {
|
|
504
|
+
if (resolutionError instanceof DurableJobError)
|
|
505
|
+
throw resolutionError;
|
|
506
|
+
}
|
|
507
|
+
throw error;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
async lockChatCancellationDecision(executor, input) {
|
|
511
|
+
await executor.query(`INSERT INTO platform_event_stream_heads (stream_id, last_sequence)
|
|
512
|
+
VALUES ($1, 0) ON CONFLICT (stream_id) DO NOTHING`, [input.streamId]);
|
|
513
|
+
await executor.query(`SELECT last_sequence FROM platform_event_stream_heads
|
|
514
|
+
WHERE stream_id = $1 FOR UPDATE`, [input.streamId]);
|
|
515
|
+
const cancellation = await executor.query(`SELECT 1 FROM platform_events
|
|
516
|
+
WHERE event_id = $1 AND stream_id = $2
|
|
517
|
+
AND event_type = 'chat.cancel-requested.v1'
|
|
518
|
+
AND subject_id = $3 AND actor_user_id = $4`, [input.eventId, input.streamId, input.subjectId, input.actorUserId]);
|
|
519
|
+
return cancellation.rows[0] !== undefined;
|
|
520
|
+
}
|
|
521
|
+
async finishAttempt(executor, row, outcome, timestamp, errorCode = null, errorSummary = null) {
|
|
522
|
+
const result = await executor.query(`UPDATE platform_job_attempts
|
|
523
|
+
SET last_heartbeat_at = $1, finished_at = $1, outcome = $2,
|
|
524
|
+
error_code = $3, error_summary = $4
|
|
525
|
+
WHERE job_id = $5 AND attempt_number = $6 AND lease_token = $7
|
|
526
|
+
AND outcome = 'running'`, [
|
|
527
|
+
timestamp,
|
|
528
|
+
outcome,
|
|
529
|
+
errorCode,
|
|
530
|
+
errorSummary,
|
|
531
|
+
row.id,
|
|
532
|
+
row.attempt_count,
|
|
533
|
+
integer(row.lease_token, 'lease_token'),
|
|
534
|
+
]);
|
|
535
|
+
return result.rowCount ?? 0;
|
|
536
|
+
}
|
|
537
|
+
async reapExpired(executor, timestamp) {
|
|
538
|
+
const expired = await executor.query(`SELECT * FROM platform_jobs
|
|
539
|
+
WHERE state = 'running' AND lease_expires_at <= $1
|
|
540
|
+
AND (cancellation_requested_at IS NOT NULL OR attempt_count >= max_attempts)
|
|
541
|
+
ORDER BY lease_expires_at ASC, id ASC
|
|
542
|
+
LIMIT 100 FOR UPDATE SKIP LOCKED`, [timestamp]);
|
|
543
|
+
const terminalLifecycleJobIds = [];
|
|
544
|
+
for (const row of expired.rows) {
|
|
545
|
+
const cancelled = row.cancellation_requested_at !== null;
|
|
546
|
+
const state = cancelled ? 'cancelled' : 'dead_letter';
|
|
547
|
+
const code = cancelled ? null : 'lease-expired';
|
|
548
|
+
const summary = cancelled
|
|
549
|
+
? null
|
|
550
|
+
: 'The worker lease expired at the retry ceiling';
|
|
551
|
+
await executor.query(`UPDATE platform_jobs SET state = $1, lease_owner = NULL,
|
|
552
|
+
lease_expires_at = NULL, finished_at = $2, updated_at = $2,
|
|
553
|
+
error_code = $3, error_summary = $4
|
|
554
|
+
WHERE id = $5 AND state = 'running' AND lease_token = $6`, [state, timestamp, code, summary, row.id, row.lease_token]);
|
|
555
|
+
await this.finishAttempt(executor, row, cancelled ? 'cancelled' : 'dead_letter', timestamp, code, summary);
|
|
556
|
+
await this.appendJobEvent(executor, row, cancelled ? 'job.cancelled' : 'job.dead-lettered', timestamp);
|
|
557
|
+
if (row.job_type === RESOURCE_DELETE_JOB_TYPE ||
|
|
558
|
+
row.job_type === OWNER_DELETE_CONTENT_JOB_TYPE) {
|
|
559
|
+
terminalLifecycleJobIds.push(row.id);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return terminalLifecycleJobIds;
|
|
563
|
+
}
|
|
564
|
+
async claimWithLifecycleRecovery(workerId, leaseMs) {
|
|
565
|
+
return this.database.transaction(async (client) => {
|
|
566
|
+
const timestamp = this.now();
|
|
567
|
+
const terminalLifecycleJobIds = await this.reapExpired(client, timestamp);
|
|
568
|
+
const selected = await client.query(`SELECT * FROM platform_jobs
|
|
569
|
+
WHERE cancellation_requested_at IS NULL
|
|
570
|
+
AND ((state = 'queued' AND available_at <= $1)
|
|
571
|
+
OR (state = 'running' AND lease_expires_at <= $1
|
|
572
|
+
AND attempt_count < max_attempts))
|
|
573
|
+
ORDER BY priority DESC, available_at ASC, created_at ASC, id ASC
|
|
574
|
+
LIMIT 1 FOR UPDATE SKIP LOCKED`, [timestamp]);
|
|
575
|
+
const candidate = selected.rows[0];
|
|
576
|
+
if (!candidate)
|
|
577
|
+
return { lease: null, terminalLifecycleJobIds };
|
|
578
|
+
if (candidate.state === 'running') {
|
|
579
|
+
await this.finishAttempt(client, candidate, 'abandoned', timestamp);
|
|
580
|
+
}
|
|
581
|
+
const nextAttempt = candidate.attempt_count + 1;
|
|
582
|
+
const nextToken = integer(candidate.lease_token, 'lease_token') + 1;
|
|
583
|
+
const expiresAt = timestamp + leaseMs;
|
|
584
|
+
const claimed = await client.query(`UPDATE platform_jobs
|
|
585
|
+
SET state = 'running', attempt_count = $1, lease_owner = $2,
|
|
586
|
+
lease_token = $3, lease_expires_at = $4,
|
|
587
|
+
started_at = COALESCE(started_at, $5), updated_at = $5,
|
|
588
|
+
error_code = NULL, error_summary = NULL
|
|
589
|
+
WHERE id = $6
|
|
590
|
+
RETURNING *`, [nextAttempt, workerId, nextToken, expiresAt, timestamp, candidate.id]);
|
|
591
|
+
const row = claimed.rows[0];
|
|
592
|
+
if (!row)
|
|
593
|
+
return { lease: null, terminalLifecycleJobIds };
|
|
594
|
+
await client.query(`INSERT INTO platform_job_attempts
|
|
595
|
+
(job_id, attempt_number, lease_token, worker_id, started_at,
|
|
596
|
+
last_heartbeat_at, outcome)
|
|
597
|
+
VALUES ($1, $2, $3, $4, $5, $5, 'running')`, [row.id, nextAttempt, nextToken, workerId, timestamp]);
|
|
598
|
+
await this.appendJobEvent(client, row, 'job.claimed', timestamp);
|
|
599
|
+
return { lease: lease(row), terminalLifecycleJobIds };
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
async claim(workerId, leaseMs) {
|
|
603
|
+
return (await this.claimWithLifecycleRecovery(workerId, leaseMs)).lease;
|
|
604
|
+
}
|
|
605
|
+
async heartbeat(job, leaseMs) {
|
|
606
|
+
return this.database.transaction(async (client) => {
|
|
607
|
+
const timestamp = this.now();
|
|
608
|
+
const updated = await client.query(`UPDATE platform_jobs SET lease_expires_at = $1, updated_at = $2
|
|
609
|
+
WHERE id = $3 AND state = 'running' AND lease_owner = $4
|
|
610
|
+
AND lease_token = $5 AND lease_expires_at > $2
|
|
611
|
+
RETURNING *`, [timestamp + leaseMs, timestamp, job.id, job.workerId, job.leaseToken]);
|
|
612
|
+
if (!updated.rows[0])
|
|
613
|
+
return { owned: false, cancellationRequested: false };
|
|
614
|
+
await client.query(`UPDATE platform_job_attempts SET last_heartbeat_at = $1
|
|
615
|
+
WHERE job_id = $2 AND attempt_number = $3 AND lease_token = $4
|
|
616
|
+
AND outcome = 'running'`, [timestamp, job.id, job.attemptCount, job.leaseToken]);
|
|
617
|
+
return {
|
|
618
|
+
owned: true,
|
|
619
|
+
cancellationRequested: updated.rows[0].cancellation_requested_at !== null,
|
|
620
|
+
};
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Read-only ownership and cancellation check. Unlike heartbeat this never
|
|
625
|
+
* extends the lease and never writes, so hot paths can call it per side
|
|
626
|
+
* effect without paying a transaction commit.
|
|
627
|
+
*/
|
|
628
|
+
async inspectLease(job) {
|
|
629
|
+
const timestamp = this.now();
|
|
630
|
+
const result = await this.database.query(`SELECT state, lease_owner, lease_token, lease_expires_at,
|
|
631
|
+
cancellation_requested_at
|
|
632
|
+
FROM platform_jobs WHERE id = $1`, [job.id]);
|
|
633
|
+
const row = result.rows[0];
|
|
634
|
+
const owned = Boolean(row &&
|
|
635
|
+
row.state === 'running' &&
|
|
636
|
+
row.lease_owner === job.workerId &&
|
|
637
|
+
row.lease_token !== null &&
|
|
638
|
+
Number(row.lease_token) === job.leaseToken &&
|
|
639
|
+
row.lease_expires_at !== null &&
|
|
640
|
+
Number(row.lease_expires_at) > timestamp);
|
|
641
|
+
return {
|
|
642
|
+
owned,
|
|
643
|
+
cancellationRequested: owned
|
|
644
|
+
? row.cancellation_requested_at !== null
|
|
645
|
+
: false,
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* `global_cursor` is a sequence and `occurred_at` comes from the same clock
|
|
650
|
+
* that orders appends, so the oldest row by cursor is also the oldest by
|
|
651
|
+
* time. The probe keeps an idle sweep at one row read instead of a scan.
|
|
652
|
+
*/
|
|
653
|
+
async oldestEventOccurredAt(eventType) {
|
|
654
|
+
const result = await this.database.query(`SELECT occurred_at FROM platform_events
|
|
655
|
+
${eventType ? 'WHERE event_type = $1' : ''}
|
|
656
|
+
ORDER BY global_cursor ASC LIMIT 1`, eventType ? [eventType] : []);
|
|
657
|
+
const row = result.rows[0];
|
|
658
|
+
return row ? integer(row.occurred_at, 'event occurred_at') : undefined;
|
|
659
|
+
}
|
|
660
|
+
async deleteOldestEvents(cutoff, limit, eventType) {
|
|
661
|
+
const oldest = await this.oldestEventOccurredAt(eventType);
|
|
662
|
+
if (oldest === undefined || oldest >= cutoff)
|
|
663
|
+
return 0;
|
|
664
|
+
const result = await this.database.query(eventType
|
|
665
|
+
? `DELETE FROM platform_events
|
|
666
|
+
WHERE global_cursor IN (
|
|
667
|
+
SELECT global_cursor FROM platform_events
|
|
668
|
+
WHERE event_type = $1 AND occurred_at < $2
|
|
669
|
+
ORDER BY global_cursor ASC LIMIT $3
|
|
670
|
+
)`
|
|
671
|
+
: `DELETE FROM platform_events
|
|
672
|
+
WHERE global_cursor IN (
|
|
673
|
+
SELECT global_cursor FROM platform_events
|
|
674
|
+
WHERE occurred_at < $1
|
|
675
|
+
ORDER BY global_cursor ASC LIMIT $2
|
|
676
|
+
)`, eventType ? [eventType, cutoff, limit] : [cutoff, limit]);
|
|
677
|
+
return result.rowCount ?? 0;
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Bounded removal of aged history. Chat stream chunks are transient live
|
|
681
|
+
* catch-up transport and dominate volume, so they get their own shorter
|
|
682
|
+
* window. Deletion-lifecycle job types are excluded: their terminal rows
|
|
683
|
+
* feed cleanup recovery and are reconciled by their own path.
|
|
684
|
+
*/
|
|
685
|
+
async pruneHistory(input) {
|
|
686
|
+
const chatStreamEvents = await this.deleteOldestEvents(input.chatStreamEventCutoff, input.limit, 'chat.stream.v1');
|
|
687
|
+
const events = await this.deleteOldestEvents(input.eventCutoff, input.limit);
|
|
688
|
+
const jobs = await this.database.query(`DELETE FROM platform_jobs
|
|
689
|
+
WHERE id IN (
|
|
690
|
+
SELECT id FROM platform_jobs
|
|
691
|
+
WHERE state IN ('succeeded', 'cancelled', 'dead_letter')
|
|
692
|
+
AND job_type NOT IN ($1, $2)
|
|
693
|
+
AND finished_at IS NOT NULL
|
|
694
|
+
AND finished_at < $3
|
|
695
|
+
LIMIT $4
|
|
696
|
+
)`, [
|
|
697
|
+
RESOURCE_DELETE_JOB_TYPE,
|
|
698
|
+
OWNER_DELETE_CONTENT_JOB_TYPE,
|
|
699
|
+
input.jobCutoff,
|
|
700
|
+
input.limit,
|
|
701
|
+
]);
|
|
702
|
+
return { chatStreamEvents, events, jobs: jobs.rowCount ?? 0 };
|
|
703
|
+
}
|
|
704
|
+
/** Remove one finished stream and its head; events cascade with the head. */
|
|
705
|
+
async deleteEventStream(streamId) {
|
|
706
|
+
return this.database.transaction(async (client) => {
|
|
707
|
+
const events = await client.query(`DELETE FROM platform_events WHERE stream_id = $1`, [streamId]);
|
|
708
|
+
await client.query(`DELETE FROM platform_event_stream_heads WHERE stream_id = $1`, [streamId]);
|
|
709
|
+
return events.rowCount ?? 0;
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
async updateProgress(job, current, total, message) {
|
|
713
|
+
const timestamp = this.now();
|
|
714
|
+
const result = await this.database.query(`UPDATE platform_jobs
|
|
715
|
+
SET progress_current = $1, progress_total = $2,
|
|
716
|
+
progress_message = $3, updated_at = $4
|
|
717
|
+
WHERE id = $5 AND state = 'running' AND lease_owner = $6
|
|
718
|
+
AND lease_token = $7 AND lease_expires_at > $4`, [current, total, message, timestamp, job.id, job.workerId, job.leaseToken]);
|
|
719
|
+
if (result.rowCount !== 1)
|
|
720
|
+
throw new DurableJobError('lease-lost', 'The durable job lease was lost');
|
|
721
|
+
}
|
|
722
|
+
async lockedLease(executor, job, timestamp) {
|
|
723
|
+
const row = await this.find(executor, job.id, true);
|
|
724
|
+
if (!row ||
|
|
725
|
+
row.state !== 'running' ||
|
|
726
|
+
row.lease_owner !== job.workerId ||
|
|
727
|
+
integer(row.lease_token, 'lease_token') !== job.leaseToken ||
|
|
728
|
+
row.lease_expires_at === null ||
|
|
729
|
+
integer(row.lease_expires_at, 'lease_expires_at') <= timestamp) {
|
|
730
|
+
throw new DurableJobError('lease-lost', 'The durable job lease was lost');
|
|
731
|
+
}
|
|
732
|
+
return row;
|
|
733
|
+
}
|
|
734
|
+
async complete(job, resultReference) {
|
|
735
|
+
await this.database.transaction(async (client) => {
|
|
736
|
+
const timestamp = this.now();
|
|
737
|
+
const row = await this.lockedLease(client, job, timestamp);
|
|
738
|
+
const cancelled = row.cancellation_requested_at !== null;
|
|
739
|
+
await client.query(`UPDATE platform_jobs SET state = $1, lease_owner = NULL,
|
|
740
|
+
lease_expires_at = NULL, result_reference = $2,
|
|
741
|
+
progress_current = progress_total, finished_at = $3,
|
|
742
|
+
updated_at = $3
|
|
743
|
+
WHERE id = $4`, [
|
|
744
|
+
cancelled ? 'cancelled' : 'succeeded',
|
|
745
|
+
cancelled ? null : resultReference,
|
|
746
|
+
timestamp,
|
|
747
|
+
row.id,
|
|
748
|
+
]);
|
|
749
|
+
await this.finishAttempt(client, row, cancelled ? 'cancelled' : 'succeeded', timestamp);
|
|
750
|
+
await this.appendJobEvent(client, row, cancelled ? 'job.cancelled' : 'job.succeeded', timestamp);
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
async fail(job, retryable, errorCode, errorSummary, nextAvailableAt) {
|
|
754
|
+
return this.database.transaction(async (client) => {
|
|
755
|
+
const timestamp = this.now();
|
|
756
|
+
const row = await this.lockedLease(client, job, timestamp);
|
|
757
|
+
const cancelled = row.cancellation_requested_at !== null;
|
|
758
|
+
const willRetry = !cancelled && retryable && row.attempt_count < row.max_attempts;
|
|
759
|
+
const state = cancelled
|
|
760
|
+
? 'cancelled'
|
|
761
|
+
: willRetry
|
|
762
|
+
? 'queued'
|
|
763
|
+
: 'dead_letter';
|
|
764
|
+
await client.query(`UPDATE platform_jobs SET state = $1, available_at = $2,
|
|
765
|
+
lease_owner = NULL, lease_expires_at = NULL,
|
|
766
|
+
error_code = $3, error_summary = $4, finished_at = $5,
|
|
767
|
+
updated_at = $6
|
|
768
|
+
WHERE id = $7`, [
|
|
769
|
+
state,
|
|
770
|
+
willRetry ? nextAvailableAt : row.available_at,
|
|
771
|
+
cancelled ? null : errorCode,
|
|
772
|
+
cancelled ? null : errorSummary,
|
|
773
|
+
willRetry ? null : timestamp,
|
|
774
|
+
timestamp,
|
|
775
|
+
row.id,
|
|
776
|
+
]);
|
|
777
|
+
await this.finishAttempt(client, row, cancelled ? 'cancelled' : willRetry ? 'retry_scheduled' : 'dead_letter', timestamp, cancelled ? null : errorCode, cancelled ? null : errorSummary);
|
|
778
|
+
await this.appendJobEvent(client, row, cancelled
|
|
779
|
+
? 'job.cancelled'
|
|
780
|
+
: willRetry
|
|
781
|
+
? 'job.retry-scheduled'
|
|
782
|
+
: 'job.dead-lettered', timestamp);
|
|
783
|
+
return state;
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
abandon(job) {
|
|
787
|
+
return this.fail(job, true, 'worker-shutdown', 'The worker stopped before completing the attempt', this.now());
|
|
788
|
+
}
|
|
789
|
+
async requestCancellationWithExecutor(client, id, actorUserId, reason) {
|
|
790
|
+
const timestamp = this.now();
|
|
791
|
+
const row = await this.find(client, id, true);
|
|
792
|
+
if (!row || row.actor_user_id !== actorUserId) {
|
|
793
|
+
throw new DurableJobError('not-found', 'Durable job not found');
|
|
794
|
+
}
|
|
795
|
+
if (['succeeded', 'cancelled', 'dead_letter'].includes(row.state) ||
|
|
796
|
+
row.cancellation_requested_at !== null) {
|
|
797
|
+
return metadata(row);
|
|
798
|
+
}
|
|
799
|
+
const queued = row.state === 'queued';
|
|
800
|
+
const updated = await client.query(`UPDATE platform_jobs
|
|
801
|
+
SET state = $1, cancellation_requested_at = $2,
|
|
802
|
+
cancellation_reason = $3, finished_at = $4, updated_at = $2
|
|
803
|
+
WHERE id = $5 RETURNING *`, [
|
|
804
|
+
queued ? 'cancelled' : 'running',
|
|
805
|
+
timestamp,
|
|
806
|
+
reason,
|
|
807
|
+
queued ? timestamp : null,
|
|
808
|
+
row.id,
|
|
809
|
+
]);
|
|
810
|
+
await this.appendJobEvent(client, row, queued ? 'job.cancelled' : 'job.cancellation-requested', timestamp);
|
|
811
|
+
if (!updated.rows[0])
|
|
812
|
+
throw new DurableJobError('storage-error', 'Cancelled PostgreSQL job disappeared');
|
|
813
|
+
return metadata(updated.rows[0]);
|
|
814
|
+
}
|
|
815
|
+
async requestCancellation(id, actorUserId, reason) {
|
|
816
|
+
return this.database.transaction(client => this.requestCancellationWithExecutor(client, id, actorUserId, reason));
|
|
817
|
+
}
|
|
818
|
+
async requestActorCancellation(actorUserId, reason, filter = {}) {
|
|
819
|
+
return this.database.transaction(async (client) => {
|
|
820
|
+
const parameters = [actorUserId];
|
|
821
|
+
const clauses = [
|
|
822
|
+
'actor_user_id = $1',
|
|
823
|
+
"state IN ('queued', 'running')",
|
|
824
|
+
'cancellation_requested_at IS NULL',
|
|
825
|
+
];
|
|
826
|
+
if (filter.jobTypes && filter.jobTypes.length > 0) {
|
|
827
|
+
parameters.push([...filter.jobTypes]);
|
|
828
|
+
clauses.push(`job_type = ANY($${parameters.length}::text[])`);
|
|
829
|
+
}
|
|
830
|
+
if (filter.excludeJobTypes && filter.excludeJobTypes.length > 0) {
|
|
831
|
+
parameters.push([...filter.excludeJobTypes]);
|
|
832
|
+
clauses.push(`NOT (job_type = ANY($${parameters.length}::text[]))`);
|
|
833
|
+
}
|
|
834
|
+
if (filter.idempotencyScopes && filter.idempotencyScopes.length > 0) {
|
|
835
|
+
parameters.push([...filter.idempotencyScopes]);
|
|
836
|
+
clauses.push(`idempotency_scope = ANY($${parameters.length}::text[])`);
|
|
837
|
+
}
|
|
838
|
+
if (filter.excludeJobIds && filter.excludeJobIds.length > 0) {
|
|
839
|
+
parameters.push([...filter.excludeJobIds]);
|
|
840
|
+
clauses.push(`NOT (id = ANY($${parameters.length}::text[]))`);
|
|
841
|
+
}
|
|
842
|
+
const selected = await client.query(`SELECT * FROM platform_jobs
|
|
843
|
+
WHERE ${clauses.join(' AND ')}
|
|
844
|
+
ORDER BY id ASC FOR UPDATE`, parameters);
|
|
845
|
+
const timestamp = this.now();
|
|
846
|
+
let cancelledQueued = 0;
|
|
847
|
+
let cancellationRequestedRunning = 0;
|
|
848
|
+
for (const row of selected.rows) {
|
|
849
|
+
const queued = row.state === 'queued';
|
|
850
|
+
const updated = await client.query(`UPDATE platform_jobs
|
|
851
|
+
SET state = $1, cancellation_requested_at = $2,
|
|
852
|
+
cancellation_reason = $3, finished_at = $4, updated_at = $2
|
|
853
|
+
WHERE id = $5 AND state = $6
|
|
854
|
+
AND cancellation_requested_at IS NULL`, [
|
|
855
|
+
queued ? 'cancelled' : 'running',
|
|
856
|
+
timestamp,
|
|
857
|
+
reason,
|
|
858
|
+
queued ? timestamp : null,
|
|
859
|
+
row.id,
|
|
860
|
+
row.state,
|
|
861
|
+
]);
|
|
862
|
+
if ((updated.rowCount ?? 0) !== 1)
|
|
863
|
+
continue;
|
|
864
|
+
if (queued)
|
|
865
|
+
cancelledQueued += 1;
|
|
866
|
+
else
|
|
867
|
+
cancellationRequestedRunning += 1;
|
|
868
|
+
await this.appendJobEvent(client, row, queued ? 'job.cancelled' : 'job.cancellation-requested', timestamp);
|
|
869
|
+
}
|
|
870
|
+
return { cancelledQueued, cancellationRequestedRunning };
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
async countActiveForActor(actorUserId, filter = {}) {
|
|
874
|
+
const parameters = [actorUserId];
|
|
875
|
+
const clauses = ['actor_user_id = $1', "state IN ('queued', 'running')"];
|
|
876
|
+
if (filter.jobTypes && filter.jobTypes.length > 0) {
|
|
877
|
+
parameters.push([...filter.jobTypes]);
|
|
878
|
+
clauses.push(`job_type = ANY($${parameters.length}::text[])`);
|
|
879
|
+
}
|
|
880
|
+
if (filter.excludeJobTypes && filter.excludeJobTypes.length > 0) {
|
|
881
|
+
parameters.push([...filter.excludeJobTypes]);
|
|
882
|
+
clauses.push(`NOT (job_type = ANY($${parameters.length}::text[]))`);
|
|
883
|
+
}
|
|
884
|
+
if (filter.idempotencyScopes && filter.idempotencyScopes.length > 0) {
|
|
885
|
+
parameters.push([...filter.idempotencyScopes]);
|
|
886
|
+
clauses.push(`idempotency_scope = ANY($${parameters.length}::text[])`);
|
|
887
|
+
}
|
|
888
|
+
if (filter.excludeJobIds && filter.excludeJobIds.length > 0) {
|
|
889
|
+
parameters.push([...filter.excludeJobIds]);
|
|
890
|
+
clauses.push(`NOT (id = ANY($${parameters.length}::text[]))`);
|
|
891
|
+
}
|
|
892
|
+
const result = await this.database.query(`SELECT COUNT(*) AS count FROM platform_jobs WHERE ${clauses.join(' AND ')}`, parameters);
|
|
893
|
+
return result.rows[0]
|
|
894
|
+
? integer(result.rows[0].count, 'active actor job count')
|
|
895
|
+
: 0;
|
|
896
|
+
}
|
|
897
|
+
async countNonSucceededForActor(actorUserId, filter = {}) {
|
|
898
|
+
const parameters = [actorUserId];
|
|
899
|
+
const clauses = ['actor_user_id = $1', "state <> 'succeeded'"];
|
|
900
|
+
if (filter.jobTypes && filter.jobTypes.length > 0) {
|
|
901
|
+
parameters.push([...filter.jobTypes]);
|
|
902
|
+
clauses.push(`job_type = ANY($${parameters.length}::text[])`);
|
|
903
|
+
}
|
|
904
|
+
if (filter.excludeJobTypes && filter.excludeJobTypes.length > 0) {
|
|
905
|
+
parameters.push([...filter.excludeJobTypes]);
|
|
906
|
+
clauses.push(`NOT (job_type = ANY($${parameters.length}::text[]))`);
|
|
907
|
+
}
|
|
908
|
+
if (filter.idempotencyScopes && filter.idempotencyScopes.length > 0) {
|
|
909
|
+
parameters.push([...filter.idempotencyScopes]);
|
|
910
|
+
clauses.push(`idempotency_scope = ANY($${parameters.length}::text[])`);
|
|
911
|
+
}
|
|
912
|
+
if (filter.excludeJobIds && filter.excludeJobIds.length > 0) {
|
|
913
|
+
parameters.push([...filter.excludeJobIds]);
|
|
914
|
+
clauses.push(`NOT (id = ANY($${parameters.length}::text[]))`);
|
|
915
|
+
}
|
|
916
|
+
if (filter.excludeHandledLifecycleJobs) {
|
|
917
|
+
parameters.push([
|
|
918
|
+
RESOURCE_DELETE_JOB_TYPE,
|
|
919
|
+
OWNER_DELETE_CONTENT_JOB_TYPE,
|
|
920
|
+
]);
|
|
921
|
+
const jobTypesParameter = parameters.length;
|
|
922
|
+
parameters.push(`${DELETION_LIFECYCLE_RECOVERY_REFERENCE_PREFIX}%`);
|
|
923
|
+
clauses.push(`NOT (
|
|
924
|
+
job_type = ANY($${jobTypesParameter}::text[])
|
|
925
|
+
AND state = ANY(ARRAY['cancelled', 'dead_letter']::text[])
|
|
926
|
+
AND result_reference LIKE $${parameters.length}
|
|
927
|
+
)`);
|
|
928
|
+
}
|
|
929
|
+
const result = await this.database.query(`SELECT COUNT(*) AS count FROM platform_jobs WHERE ${clauses.join(' AND ')}`, parameters);
|
|
930
|
+
return result.rows[0]
|
|
931
|
+
? integer(result.rows[0].count, 'non-succeeded actor job count')
|
|
932
|
+
: 0;
|
|
933
|
+
}
|
|
934
|
+
async getMetadata(id) {
|
|
935
|
+
const row = await this.find(this.database, id);
|
|
936
|
+
return row ? metadata(row) : null;
|
|
937
|
+
}
|
|
938
|
+
async listDeletionLifecycleRecoveryCandidates(afterId, limit) {
|
|
939
|
+
const result = await this.database.query(`SELECT jobs.*
|
|
940
|
+
FROM platform_jobs jobs
|
|
941
|
+
JOIN users actor ON actor.id = jobs.actor_user_id
|
|
942
|
+
WHERE jobs.id::text > $1
|
|
943
|
+
AND jobs.result_reference IS NULL
|
|
944
|
+
AND (
|
|
945
|
+
(
|
|
946
|
+
jobs.job_type = $2
|
|
947
|
+
AND actor.account_status = 'active'
|
|
948
|
+
AND (
|
|
949
|
+
(jobs.state = 'dead_letter' AND jobs.error_code = ANY($3::text[]))
|
|
950
|
+
OR jobs.state = 'cancelled'
|
|
951
|
+
)
|
|
952
|
+
)
|
|
953
|
+
OR
|
|
954
|
+
(
|
|
955
|
+
jobs.job_type = $4
|
|
956
|
+
AND actor.account_status IN ('active', 'retiring')
|
|
957
|
+
AND (
|
|
958
|
+
(jobs.state = 'dead_letter' AND jobs.error_code = ANY($5::text[]))
|
|
959
|
+
OR jobs.state = 'cancelled'
|
|
960
|
+
)
|
|
961
|
+
)
|
|
962
|
+
)
|
|
963
|
+
ORDER BY jobs.id::text ASC
|
|
964
|
+
LIMIT $6`, [
|
|
965
|
+
afterId,
|
|
966
|
+
RESOURCE_DELETE_JOB_TYPE,
|
|
967
|
+
[...RESOURCE_DELETE_RECOVERABLE_ERROR_CODES],
|
|
968
|
+
OWNER_DELETE_CONTENT_JOB_TYPE,
|
|
969
|
+
[...OWNER_DELETE_CONTENT_RECOVERABLE_ERROR_CODES],
|
|
970
|
+
limit,
|
|
971
|
+
]);
|
|
972
|
+
return result.rows.map(row => ({
|
|
973
|
+
id: row.id,
|
|
974
|
+
jobType: row.job_type,
|
|
975
|
+
actorUserId: row.actor_user_id,
|
|
976
|
+
payload: { format: row.payload_format, data: row.payload },
|
|
977
|
+
priority: row.priority,
|
|
978
|
+
updatedAt: integer(row.updated_at, 'updated_at'),
|
|
979
|
+
}));
|
|
980
|
+
}
|
|
981
|
+
async getDeletionLifecycleRecoveryCandidate(id) {
|
|
982
|
+
const result = await this.database.query(`SELECT jobs.*
|
|
983
|
+
FROM platform_jobs jobs
|
|
984
|
+
JOIN users actor ON actor.id = jobs.actor_user_id
|
|
985
|
+
WHERE jobs.id = $1
|
|
986
|
+
AND jobs.result_reference IS NULL
|
|
987
|
+
AND (
|
|
988
|
+
(
|
|
989
|
+
jobs.job_type = $2
|
|
990
|
+
AND actor.account_status = 'active'
|
|
991
|
+
AND (
|
|
992
|
+
(jobs.state = 'dead_letter' AND jobs.error_code = ANY($3::text[]))
|
|
993
|
+
OR jobs.state = 'cancelled'
|
|
994
|
+
)
|
|
995
|
+
)
|
|
996
|
+
OR
|
|
997
|
+
(
|
|
998
|
+
jobs.job_type = $4
|
|
999
|
+
AND actor.account_status IN ('active', 'retiring')
|
|
1000
|
+
AND (
|
|
1001
|
+
(jobs.state = 'dead_letter' AND jobs.error_code = ANY($5::text[]))
|
|
1002
|
+
OR jobs.state = 'cancelled'
|
|
1003
|
+
)
|
|
1004
|
+
)
|
|
1005
|
+
)`, [
|
|
1006
|
+
id,
|
|
1007
|
+
RESOURCE_DELETE_JOB_TYPE,
|
|
1008
|
+
[...RESOURCE_DELETE_RECOVERABLE_ERROR_CODES],
|
|
1009
|
+
OWNER_DELETE_CONTENT_JOB_TYPE,
|
|
1010
|
+
[...OWNER_DELETE_CONTENT_RECOVERABLE_ERROR_CODES],
|
|
1011
|
+
]);
|
|
1012
|
+
const row = result.rows[0];
|
|
1013
|
+
return row
|
|
1014
|
+
? {
|
|
1015
|
+
id: row.id,
|
|
1016
|
+
jobType: row.job_type,
|
|
1017
|
+
actorUserId: row.actor_user_id,
|
|
1018
|
+
payload: { format: row.payload_format, data: row.payload },
|
|
1019
|
+
priority: row.priority,
|
|
1020
|
+
updatedAt: integer(row.updated_at, 'updated_at'),
|
|
1021
|
+
}
|
|
1022
|
+
: null;
|
|
1023
|
+
}
|
|
1024
|
+
async markDeletionLifecycleRecoveryHandled(id, resultReference) {
|
|
1025
|
+
await this.database.transaction(async (client) => {
|
|
1026
|
+
const updated = await client.query(`UPDATE platform_jobs
|
|
1027
|
+
SET result_reference = $1
|
|
1028
|
+
WHERE id = $2
|
|
1029
|
+
AND job_type = ANY($3::text[])
|
|
1030
|
+
AND state = ANY($4::text[])
|
|
1031
|
+
AND result_reference IS NULL`, [
|
|
1032
|
+
resultReference,
|
|
1033
|
+
id,
|
|
1034
|
+
[RESOURCE_DELETE_JOB_TYPE, OWNER_DELETE_CONTENT_JOB_TYPE],
|
|
1035
|
+
['cancelled', 'dead_letter'],
|
|
1036
|
+
]);
|
|
1037
|
+
if (updated.rowCount === 1)
|
|
1038
|
+
return;
|
|
1039
|
+
const existing = await client.query(`SELECT result_reference FROM platform_jobs
|
|
1040
|
+
WHERE id = $1
|
|
1041
|
+
AND job_type = ANY($2::text[])
|
|
1042
|
+
AND state = ANY($3::text[])`, [
|
|
1043
|
+
id,
|
|
1044
|
+
[RESOURCE_DELETE_JOB_TYPE, OWNER_DELETE_CONTENT_JOB_TYPE],
|
|
1045
|
+
['cancelled', 'dead_letter'],
|
|
1046
|
+
]);
|
|
1047
|
+
const existingReference = existing.rows[0]?.result_reference;
|
|
1048
|
+
if (existingReference === resultReference ||
|
|
1049
|
+
existingReference?.startsWith(DELETION_LIFECYCLE_RECOVERY_REFERENCE_PREFIX)) {
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
throw new DurableJobError('storage-error', 'Deletion lifecycle recovery marker conflicted');
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
async isPendingResourceDeletion(input) {
|
|
1056
|
+
const table = (() => {
|
|
1057
|
+
switch (input.resourceType) {
|
|
1058
|
+
case 'document':
|
|
1059
|
+
return 'documents';
|
|
1060
|
+
case 'generated-media':
|
|
1061
|
+
return 'platform_generated_media';
|
|
1062
|
+
case 'persona':
|
|
1063
|
+
return 'personas';
|
|
1064
|
+
}
|
|
1065
|
+
})();
|
|
1066
|
+
const result = await this.database.query(`SELECT 1
|
|
1067
|
+
FROM platform_resource_deletion_tombstones tombstone
|
|
1068
|
+
WHERE tombstone.resource_type = $1
|
|
1069
|
+
AND tombstone.resource_id = $2
|
|
1070
|
+
AND tombstone.owner_user_id = $3
|
|
1071
|
+
AND tombstone.deletion_incarnation = $4
|
|
1072
|
+
AND tombstone.deletion_token = $5
|
|
1073
|
+
AND tombstone.completed_at IS NULL
|
|
1074
|
+
AND NOT EXISTS (
|
|
1075
|
+
SELECT 1 FROM ${table} resource
|
|
1076
|
+
WHERE resource.id = tombstone.resource_id
|
|
1077
|
+
AND resource.user_id = tombstone.owner_user_id
|
|
1078
|
+
)`, [
|
|
1079
|
+
input.resourceType,
|
|
1080
|
+
input.resourceId,
|
|
1081
|
+
input.ownerUserId,
|
|
1082
|
+
input.deletionIncarnation,
|
|
1083
|
+
input.deletionToken,
|
|
1084
|
+
]);
|
|
1085
|
+
return result.rowCount === 1;
|
|
1086
|
+
}
|
|
1087
|
+
async isOwnerCleanupRequired(targetUserId) {
|
|
1088
|
+
const result = await this.database.query('SELECT 1 FROM users WHERE id = $1', [targetUserId]);
|
|
1089
|
+
return result.rowCount === 0;
|
|
1090
|
+
}
|
|
1091
|
+
async getByIdempotency(actorUserId, scope, keyHash) {
|
|
1092
|
+
const result = await this.database.query(`SELECT * FROM platform_jobs
|
|
1093
|
+
WHERE actor_user_id = $1 AND idempotency_scope = $2
|
|
1094
|
+
AND idempotency_key_hash = $3`, [actorUserId, scope, keyHash]);
|
|
1095
|
+
return result.rows[0] ? metadata(result.rows[0]) : null;
|
|
1096
|
+
}
|
|
1097
|
+
async listJobs(options) {
|
|
1098
|
+
const conditions = [];
|
|
1099
|
+
const parameters = [];
|
|
1100
|
+
const add = (sql, value) => {
|
|
1101
|
+
parameters.push(value);
|
|
1102
|
+
conditions.push(sql.replace('?', `$${parameters.length}`));
|
|
1103
|
+
};
|
|
1104
|
+
if (options.actorUserId)
|
|
1105
|
+
add('actor_user_id = ?', options.actorUserId);
|
|
1106
|
+
if (options.state)
|
|
1107
|
+
add('state = ?', options.state);
|
|
1108
|
+
if (options.beforeCreatedAt !== undefined)
|
|
1109
|
+
add('created_at < ?', options.beforeCreatedAt);
|
|
1110
|
+
parameters.push(options.limit ?? 50);
|
|
1111
|
+
const result = await this.database.query(`SELECT * FROM platform_jobs
|
|
1112
|
+
${conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''}
|
|
1113
|
+
ORDER BY created_at DESC, id ASC LIMIT $${parameters.length}`, parameters);
|
|
1114
|
+
return result.rows.map(metadata);
|
|
1115
|
+
}
|
|
1116
|
+
async getStoredPayload(job) {
|
|
1117
|
+
const row = await this.find(this.database, job.id);
|
|
1118
|
+
const timestamp = this.now();
|
|
1119
|
+
if (!row ||
|
|
1120
|
+
row.state !== 'running' ||
|
|
1121
|
+
row.lease_owner !== job.workerId ||
|
|
1122
|
+
integer(row.lease_token, 'lease_token') !== job.leaseToken ||
|
|
1123
|
+
row.lease_expires_at === null ||
|
|
1124
|
+
integer(row.lease_expires_at, 'lease_expires_at') <= timestamp) {
|
|
1125
|
+
throw new DurableJobError('lease-lost', 'The durable job lease was lost');
|
|
1126
|
+
}
|
|
1127
|
+
return { format: row.payload_format, data: row.payload };
|
|
1128
|
+
}
|
|
1129
|
+
async listAttempts(id) {
|
|
1130
|
+
const result = await this.database.query(`SELECT * FROM platform_job_attempts
|
|
1131
|
+
WHERE job_id = $1 ORDER BY attempt_number ASC`, [id]);
|
|
1132
|
+
return result.rows.map(attempt);
|
|
1133
|
+
}
|
|
1134
|
+
async getStoredEvent(eventId) {
|
|
1135
|
+
const result = await this.database.query(`SELECT global_cursor AS cursor, event_id, stream_id, stream_sequence,
|
|
1136
|
+
request_fingerprint, event_type, subject_id, actor_user_id,
|
|
1137
|
+
payload_format, payload, occurred_at
|
|
1138
|
+
FROM platform_events
|
|
1139
|
+
WHERE event_id = $1`, [eventId]);
|
|
1140
|
+
const row = result.rows[0];
|
|
1141
|
+
if (!row)
|
|
1142
|
+
return null;
|
|
1143
|
+
return {
|
|
1144
|
+
...row,
|
|
1145
|
+
cursor: integer(row.cursor, 'event cursor'),
|
|
1146
|
+
stream_sequence: integer(row.stream_sequence, 'stream sequence'),
|
|
1147
|
+
occurred_at: integer(row.occurred_at, 'event occurred_at'),
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
async latestStoredEventCursor(streamId) {
|
|
1151
|
+
const result = await this.database.query(`SELECT global_cursor AS cursor
|
|
1152
|
+
FROM platform_events
|
|
1153
|
+
WHERE stream_id = $1
|
|
1154
|
+
ORDER BY stream_sequence DESC
|
|
1155
|
+
LIMIT 1`, [streamId]);
|
|
1156
|
+
const row = result.rows[0];
|
|
1157
|
+
return row ? integer(row.cursor, 'event cursor') : 0;
|
|
1158
|
+
}
|
|
1159
|
+
async replayStoredEvents(afterCursor, limit, options = {}) {
|
|
1160
|
+
const parameters = [afterCursor];
|
|
1161
|
+
const predicates = ['global_cursor > $1'];
|
|
1162
|
+
if (options.streamId) {
|
|
1163
|
+
parameters.push(options.streamId);
|
|
1164
|
+
predicates.push(`stream_id = $${parameters.length}`);
|
|
1165
|
+
}
|
|
1166
|
+
if (options.subjectId) {
|
|
1167
|
+
parameters.push(options.subjectId);
|
|
1168
|
+
predicates.push(`subject_id = $${parameters.length}`);
|
|
1169
|
+
}
|
|
1170
|
+
parameters.push(limit);
|
|
1171
|
+
const result = await this.database.query(`SELECT global_cursor AS cursor, event_id, stream_id, stream_sequence,
|
|
1172
|
+
request_fingerprint, event_type, subject_id, actor_user_id,
|
|
1173
|
+
payload_format, payload, occurred_at
|
|
1174
|
+
FROM platform_events
|
|
1175
|
+
WHERE ${predicates.join(' AND ')}
|
|
1176
|
+
ORDER BY global_cursor ASC LIMIT $${parameters.length}`, parameters);
|
|
1177
|
+
return result.rows.map(row => ({
|
|
1178
|
+
...row,
|
|
1179
|
+
cursor: integer(row.cursor, 'event cursor'),
|
|
1180
|
+
stream_sequence: integer(row.stream_sequence, 'stream sequence'),
|
|
1181
|
+
occurred_at: integer(row.occurred_at, 'event occurred_at'),
|
|
1182
|
+
}));
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
//# sourceMappingURL=postgresDurableJobRepository.js.map
|