feat(tess): persist durable session state (#729)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful

This commit was merged in pull request #729.
This commit is contained in:
2026-07-13 05:14:11 +00:00
parent e3b5113be2
commit 99a2d0fc9d
27 changed files with 19237 additions and 15 deletions

View File

@@ -0,0 +1,71 @@
CREATE TYPE "public"."interaction_handoff_status" AS ENUM('pending', 'accepted');--> statement-breakpoint
CREATE TYPE "public"."interaction_inbox_status" AS ENUM('pending', 'processing', 'processed');--> statement-breakpoint
CREATE TYPE "public"."interaction_outbox_status" AS ENUM('pending', 'processing', 'delivered');--> statement-breakpoint
CREATE TABLE "interaction_checkpoints" (
"session_id" text PRIMARY KEY NOT NULL,
"checkpoint_id" text NOT NULL,
"cursor" text NOT NULL,
"summary" text NOT NULL,
"compaction_epoch" integer NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "interaction_checkpoints_checkpoint_id_unique" UNIQUE("checkpoint_id")
);
--> statement-breakpoint
CREATE TABLE "interaction_handoffs" (
"handoff_id" text PRIMARY KEY NOT NULL,
"session_id" text NOT NULL,
"destination" text NOT NULL,
"correlation_id" text NOT NULL,
"checkpoint_id" text NOT NULL,
"status" "interaction_handoff_status" DEFAULT 'pending' NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "interaction_inbox" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"session_id" text NOT NULL,
"idempotency_key" text NOT NULL,
"correlation_id" text NOT NULL,
"content" text NOT NULL,
"content_digest" text NOT NULL,
"status" "interaction_inbox_status" DEFAULT 'pending' NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "interaction_outbox" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"session_id" text NOT NULL,
"idempotency_key" text NOT NULL,
"correlation_id" text NOT NULL,
"kind" text NOT NULL,
"content" text NOT NULL,
"content_digest" text NOT NULL,
"status" "interaction_outbox_status" DEFAULT 'pending' NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "interaction_sessions" (
"id" text PRIMARY KEY NOT NULL,
"agent_name" text NOT NULL,
"tenant_id" text NOT NULL,
"owner_id" text NOT NULL,
"provider_id" text NOT NULL,
"runtime_session_id" text NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "interaction_checkpoints" ADD CONSTRAINT "interaction_checkpoints_session_id_interaction_sessions_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."interaction_sessions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "interaction_handoffs" ADD CONSTRAINT "interaction_handoffs_session_id_interaction_sessions_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."interaction_sessions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "interaction_inbox" ADD CONSTRAINT "interaction_inbox_session_id_interaction_sessions_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."interaction_sessions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "interaction_outbox" ADD CONSTRAINT "interaction_outbox_session_id_interaction_sessions_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."interaction_sessions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "interaction_sessions" ADD CONSTRAINT "interaction_sessions_owner_id_users_id_fk" FOREIGN KEY ("owner_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "interaction_handoffs_session_status_idx" ON "interaction_handoffs" USING btree ("session_id","status");--> statement-breakpoint
CREATE UNIQUE INDEX "interaction_inbox_session_idempotency_idx" ON "interaction_inbox" USING btree ("session_id","idempotency_key");--> statement-breakpoint
CREATE INDEX "interaction_inbox_session_status_created_idx" ON "interaction_inbox" USING btree ("session_id","status","created_at");--> statement-breakpoint
CREATE UNIQUE INDEX "interaction_outbox_session_idempotency_idx" ON "interaction_outbox" USING btree ("session_id","idempotency_key");--> statement-breakpoint
CREATE INDEX "interaction_outbox_session_status_created_idx" ON "interaction_outbox" USING btree ("session_id","status","created_at");

View File

@@ -0,0 +1,5 @@
ALTER TABLE "interaction_checkpoints" DROP CONSTRAINT "interaction_checkpoints_checkpoint_id_unique";--> statement-breakpoint
ALTER TABLE "interaction_checkpoints" DROP CONSTRAINT "interaction_checkpoints_pkey";--> statement-breakpoint
ALTER TABLE "interaction_checkpoints" ADD COLUMN "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL;--> statement-breakpoint
CREATE UNIQUE INDEX "interaction_checkpoints_session_idempotency_idx" ON "interaction_checkpoints" USING btree ("session_id","checkpoint_id");--> statement-breakpoint
CREATE INDEX "interaction_checkpoints_session_epoch_idx" ON "interaction_checkpoints" USING btree ("session_id","compaction_epoch");

View File

@@ -0,0 +1,5 @@
ALTER TABLE "interaction_outbox" ADD COLUMN "channel_id" text;
--> statement-breakpoint
UPDATE "interaction_outbox" SET "channel_id" = 'legacy:unknown' WHERE "channel_id" IS NULL;
--> statement-breakpoint
ALTER TABLE "interaction_outbox" ALTER COLUMN "channel_id" SET NOT NULL;

View File

@@ -0,0 +1,3 @@
ALTER TABLE "interaction_checkpoints" ADD COLUMN "content_digest" text;--> statement-breakpoint
UPDATE "interaction_checkpoints" SET "content_digest" = 'legacy' WHERE "content_digest" IS NULL;--> statement-breakpoint
ALTER TABLE "interaction_checkpoints" ALTER COLUMN "content_digest" SET NOT NULL;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -85,6 +85,34 @@
"when": 1782310438919,
"tag": "0011_bitter_gateway",
"breakpoints": true
},
{
"idx": 12,
"version": "7",
"when": 1783911983447,
"tag": "0012_interaction_durable_state",
"breakpoints": true
},
{
"idx": 13,
"version": "7",
"when": 1783913232578,
"tag": "0013_interaction_checkpoint_history",
"breakpoints": true
},
{
"idx": 14,
"version": "7",
"when": 1783913398006,
"tag": "0014_interaction_outbox_channel_scope",
"breakpoints": true
},
{
"idx": 15,
"version": "7",
"when": 1783942610000,
"tag": "0015_interaction_checkpoint_payload_digest",
"breakpoints": true
}
]
}