feat(agent): add opt-in push notifications
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
ALTER TABLE "AgentReadState" ADD COLUMN "sourceId" TEXT;
|
||||
CREATE TABLE "AgentPushInstallation" ("id" TEXT NOT NULL PRIMARY KEY, "ownerEpoch" TEXT NOT NULL, "transport" TEXT NOT NULL, "payload" TEXT NOT NULL, "fingerprint" TEXT NOT NULL, "enabled" BOOLEAN NOT NULL DEFAULT false, "version" INTEGER NOT NULL DEFAULT 1, "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" DATETIME NOT NULL, "lastClearAt" DATETIME, "revokedAt" DATETIME);
|
||||
CREATE INDEX "AgentPushInstallation_ownerEpoch_enabled_idx" ON "AgentPushInstallation"("ownerEpoch", "enabled");
|
||||
CREATE INDEX "AgentPushInstallation_fingerprint_idx" ON "AgentPushInstallation"("fingerprint");
|
||||
CREATE TABLE "AgentPushPresence" ("id" TEXT NOT NULL PRIMARY KEY, "ownerEpoch" TEXT NOT NULL, "sequence" INTEGER NOT NULL, "visible" BOOLEAN NOT NULL, "focused" BOOLEAN NOT NULL, "lastInteractionAt" DATETIME, "expiresAt" DATETIME NOT NULL);
|
||||
CREATE INDEX "AgentPushPresence_ownerEpoch_expiresAt_idx" ON "AgentPushPresence"("ownerEpoch", "expiresAt");
|
||||
CREATE TABLE "AgentPushConnection" ("id" TEXT NOT NULL PRIMARY KEY, "ownerEpoch" TEXT NOT NULL, "kind" TEXT NOT NULL, "sessionId" TEXT, "expiresAt" DATETIME NOT NULL);
|
||||
CREATE INDEX "AgentPushConnection_ownerEpoch_expiresAt_idx" ON "AgentPushConnection"("ownerEpoch", "expiresAt");
|
||||
CREATE TABLE "AgentPushCoordinator" ("id" TEXT NOT NULL PRIMARY KEY, "ownerEpoch" TEXT NOT NULL, "sourceId" TEXT, "cursor" TEXT NOT NULL DEFAULT '0', "quarantined" BOOLEAN NOT NULL DEFAULT false, "contextObservedAt" DATETIME, "latestUserMessageAt" DATETIME, "localPromptAt" DATETIME, "nativeActive" BOOLEAN NOT NULL DEFAULT false, "nativeUnknown" BOOLEAN NOT NULL DEFAULT true, "uncertain" BOOLEAN NOT NULL DEFAULT true, "lockOwner" TEXT, "lockUntil" DATETIME);
|
||||
CREATE TABLE "AgentPushDelivery" ("id" TEXT NOT NULL PRIMARY KEY, "ownerEpoch" TEXT NOT NULL, "installationId" TEXT NOT NULL, "installationVersion" INTEGER NOT NULL, "sourceId" TEXT NOT NULL, "messageId" TEXT NOT NULL, "cursor" TEXT NOT NULL, "kind" TEXT NOT NULL, "trigger" TEXT NOT NULL, "priority" INTEGER NOT NULL DEFAULT 0, "status" TEXT NOT NULL DEFAULT 'pending', "attempts" INTEGER NOT NULL DEFAULT 0, "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, "dueAt" DATETIME NOT NULL, "expiresAt" DATETIME NOT NULL, "updatedAt" DATETIME NOT NULL, "outcome" TEXT);
|
||||
CREATE INDEX "AgentPushDelivery_status_dueAt_idx" ON "AgentPushDelivery"("status", "dueAt");
|
||||
CREATE INDEX "AgentPushDelivery_installationId_status_idx" ON "AgentPushDelivery"("installationId", "status");
|
||||
CREATE INDEX "AgentPushDelivery_ownerEpoch_sourceId_cursor_idx" ON "AgentPushDelivery"("ownerEpoch", "sourceId", "cursor");
|
||||
@@ -219,7 +219,84 @@ model ProjectItem {
|
||||
// Shared personal read position for the external persistent Sybil Agent room.
|
||||
// Messages remain in the agent's durable transcript, not duplicated in Sybil Chat.
|
||||
model AgentReadState {
|
||||
sourceId String?
|
||||
id String @id
|
||||
cursor String @default("0")
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// One server-derived shared principal. Transport payloads are secret DB data.
|
||||
model AgentPushInstallation {
|
||||
id String @id
|
||||
ownerEpoch String
|
||||
transport String
|
||||
payload String
|
||||
fingerprint String
|
||||
enabled Boolean @default(false)
|
||||
version Int @default(1)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
lastClearAt DateTime?
|
||||
revokedAt DateTime?
|
||||
@@index([ownerEpoch, enabled])
|
||||
@@index([fingerprint])
|
||||
}
|
||||
|
||||
model AgentPushPresence {
|
||||
id String @id
|
||||
ownerEpoch String
|
||||
sequence Int
|
||||
visible Boolean
|
||||
focused Boolean
|
||||
lastInteractionAt DateTime?
|
||||
expiresAt DateTime
|
||||
@@index([ownerEpoch, expiresAt])
|
||||
}
|
||||
|
||||
model AgentPushConnection {
|
||||
id String @id
|
||||
ownerEpoch String
|
||||
kind String
|
||||
sessionId String?
|
||||
expiresAt DateTime
|
||||
@@index([ownerEpoch, expiresAt])
|
||||
}
|
||||
|
||||
model AgentPushCoordinator {
|
||||
id String @id
|
||||
ownerEpoch String
|
||||
sourceId String?
|
||||
cursor String @default("0")
|
||||
quarantined Boolean @default(false)
|
||||
contextObservedAt DateTime?
|
||||
latestUserMessageAt DateTime?
|
||||
localPromptAt DateTime?
|
||||
nativeActive Boolean @default(false)
|
||||
nativeUnknown Boolean @default(true)
|
||||
uncertain Boolean @default(true)
|
||||
lockOwner String?
|
||||
lockUntil DateTime?
|
||||
}
|
||||
|
||||
model AgentPushDelivery {
|
||||
id String @id
|
||||
ownerEpoch String
|
||||
installationId String
|
||||
installationVersion Int
|
||||
sourceId String
|
||||
messageId String
|
||||
cursor String
|
||||
kind String
|
||||
trigger String
|
||||
priority Int @default(0)
|
||||
status String @default("pending")
|
||||
attempts Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
dueAt DateTime
|
||||
expiresAt DateTime
|
||||
updatedAt DateTime @updatedAt
|
||||
outcome String?
|
||||
@@index([status, dueAt])
|
||||
@@index([installationId, status])
|
||||
@@index([ownerEpoch, sourceId, cursor])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user