5809ad3adb
Shared runtime - One agent entry point (runtime.invoke_agent_for_user / prepare_agent_turn) for web, email, iMessage, WhatsApp, scheduled and cron, so identity, permissions, memories, summaries and metrics match across channels. - Serialize turns per checkpoint thread; /query validates input and returns 409 while a durable run owns the conversation. Reconnectable chat (durable runs) - POST /runs creates an idempotent, owner-scoped run; GET .../events replays an ordered SSE log by cursor, so generation survives refresh and device switches. Stop cancels; disconnect only detaches. /stream-query is a compatibility adapter. - Coalesce streamed deltas (150 ms) and wake same-process subscribers instead of polling; keep buffered text when a run is stopped. - Drain runs on shutdown; serve via Hypercorn with a shutdown timeout covering the drain (and no longer in debug mode). CHAT_RUN_* settings are forwarded. Scheduled messages and cron - Atomic delivery claims, attempt history and explicit retries; ambiguous sends become "uncertain" and are never resent automatically. - Cron triggers need a run_id/Idempotency-Key; legacy jobs need an explicit owner. - Cancelling never rewrites a started delivery; series stop via tombstones. Legacy sent rows are not forked into new series. Malformed bodies return 400. History, integrations and retrieval - Message-content search, pinned conversations, JSON/Markdown export and a memory editor. - Integration status panel and YNAB data-freshness provenance. - Date-filtered document/note search with stable citations and a source viewer. Migration 20 is generated by aerich. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
219 lines
14 KiB
Python
219 lines
14 KiB
Python
from tortoise import BaseDBAsyncClient
|
|
|
|
RUN_IN_TRANSACTION = True
|
|
|
|
|
|
async def upgrade(db: BaseDBAsyncClient) -> str:
|
|
return """
|
|
CREATE TABLE IF NOT EXISTS "chat_runs" (
|
|
"id" UUID NOT NULL PRIMARY KEY,
|
|
"request_key" VARCHAR(128) NOT NULL,
|
|
"payload" JSONB NOT NULL,
|
|
"active_key" VARCHAR(36) UNIQUE,
|
|
"status" VARCHAR(20) NOT NULL DEFAULT 'running',
|
|
"worker_token" UUID NOT NULL,
|
|
"lease_until" TIMESTAMPTZ NOT NULL,
|
|
"cancel_requested" BOOL NOT NULL DEFAULT False,
|
|
"sequence" INT NOT NULL DEFAULT 0,
|
|
"partial" TEXT NOT NULL,
|
|
"user_saved" BOOL NOT NULL DEFAULT False,
|
|
"answer_saved" BOOL NOT NULL DEFAULT False,
|
|
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"conversation_id" UUID NOT NULL REFERENCES "conversations" ("id") ON DELETE CASCADE,
|
|
"owner_id" UUID NOT NULL REFERENCES "users" ("id") ON DELETE CASCADE,
|
|
CONSTRAINT "uid_chat_runs_owner_i_98309f" UNIQUE ("owner_id", "conversation_id", "request_key")
|
|
);
|
|
CREATE INDEX IF NOT EXISTS "idx_chat_runs_lease_u_b8a59a" ON "chat_runs" ("lease_until");
|
|
CREATE TABLE IF NOT EXISTS "chat_run_events" (
|
|
"id" BIGSERIAL NOT NULL PRIMARY KEY,
|
|
"sequence" INT NOT NULL,
|
|
"payload" JSONB NOT NULL,
|
|
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"run_id" UUID NOT NULL REFERENCES "chat_runs" ("id") ON DELETE CASCADE,
|
|
CONSTRAINT "uid_chat_run_ev_run_id_1326b1" UNIQUE ("run_id", "sequence")
|
|
);
|
|
CREATE TABLE IF NOT EXISTS "job_deliveries" (
|
|
"id" UUID NOT NULL PRIMARY KEY,
|
|
"kind" VARCHAR(20) NOT NULL,
|
|
"job_id" VARCHAR(36) NOT NULL,
|
|
"run_id" VARCHAR(255) NOT NULL,
|
|
"status" VARCHAR(20) NOT NULL DEFAULT 'pending',
|
|
"claim_token" UUID,
|
|
"claimed_at" TIMESTAMPTZ,
|
|
"error" TEXT,
|
|
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
CONSTRAINT "uid_job_deliver_kind_1add26" UNIQUE ("kind", "job_id", "run_id")
|
|
);
|
|
COMMENT ON TABLE "job_deliveries" IS 'Durable run identity; never reclaim ambiguous external deliveries.';
|
|
CREATE TABLE IF NOT EXISTS "job_attempts" (
|
|
"id" UUID NOT NULL PRIMARY KEY,
|
|
"claim_token" UUID NOT NULL UNIQUE,
|
|
"status" VARCHAR(20) NOT NULL DEFAULT 'processing',
|
|
"error" TEXT,
|
|
"started_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"finished_at" TIMESTAMPTZ,
|
|
"delivery_id" UUID NOT NULL REFERENCES "job_deliveries" ("id") ON DELETE CASCADE
|
|
);
|
|
ALTER TABLE "conversations" ADD "pinned" BOOL NOT NULL DEFAULT False;
|
|
ALTER TABLE "scheduled_messages" ADD "deleted_at" TIMESTAMPTZ;
|
|
ALTER TABLE "scheduled_messages" ADD "previous_occurrence_id" UUID UNIQUE;
|
|
ALTER TABLE "scheduled_messages" ADD "series_id" UUID;
|
|
COMMENT ON COLUMN "scheduled_messages"."status" IS 'PENDING: pending
|
|
PROCESSING: processing
|
|
UNCERTAIN: uncertain
|
|
SENT: sent
|
|
FAILED: failed
|
|
CANCELLED: cancelled';
|
|
ALTER TABLE "cron_jobs" ADD "created_by_id" UUID;
|
|
ALTER TABLE "scheduled_messages" ADD CONSTRAINT "fk_schedule_schedule_31982f9c" FOREIGN KEY ("previous_occurrence_id") REFERENCES "scheduled_messages" ("id") ON DELETE SET NULL;
|
|
ALTER TABLE "cron_jobs" ADD CONSTRAINT "fk_cron_job_users_b3e69ad6" FOREIGN KEY ("created_by_id") REFERENCES "users" ("id") ON DELETE SET NULL;"""
|
|
|
|
|
|
async def downgrade(db: BaseDBAsyncClient) -> str:
|
|
return """
|
|
ALTER TABLE "scheduled_messages" DROP CONSTRAINT IF EXISTS "fk_schedule_schedule_31982f9c";
|
|
ALTER TABLE "cron_jobs" DROP CONSTRAINT IF EXISTS "fk_cron_job_users_b3e69ad6";
|
|
ALTER TABLE "cron_jobs" DROP COLUMN "created_by_id";
|
|
ALTER TABLE "conversations" DROP COLUMN "pinned";
|
|
ALTER TABLE "scheduled_messages" DROP COLUMN "deleted_at";
|
|
ALTER TABLE "scheduled_messages" DROP COLUMN "previous_occurrence_id";
|
|
ALTER TABLE "scheduled_messages" DROP COLUMN "series_id";
|
|
COMMENT ON COLUMN "scheduled_messages"."status" IS 'PENDING: pending
|
|
SENT: sent
|
|
FAILED: failed
|
|
CANCELLED: cancelled';
|
|
DROP TABLE IF EXISTS "chat_runs";
|
|
DROP TABLE IF EXISTS "job_attempts";
|
|
DROP TABLE IF EXISTS "chat_run_events";
|
|
DROP TABLE IF EXISTS "job_deliveries";"""
|
|
|
|
|
|
MODELS_STATE = (
|
|
"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"
|
|
)
|