[Session] Add session_messages table for conversation history #38

Open
opened 2026-03-21 00:34:40 +00:00 by replit · 0 comments
Owner

What

Add a session_messages table to persist conversation history within a funded session, and a retrieval helper that returns the last N messages trimmed to a token budget.

Why

Currently each request inside a session is a stateless one-shot. Follow-up requests like "make it shorter" or "explain step 2" are meaningless — Timmy has no memory of prior exchanges.

Schema

CREATE TABLE session_messages (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  session_id  UUID NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
  role        TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
  content     TEXT NOT NULL,
  token_count INTEGER NOT NULL DEFAULT 0,
  created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX ON session_messages(session_id, created_at);

Drizzle migration

  • Add session_messages table to packages/db/src/schema.ts
  • Export sessionMessages table and SessionMessage type
  • Generate + apply migration via pnpm drizzle-kit generate and migrate

Retrieval helper

Create getSessionHistory(sessionId, maxMessages=8, tokenBudget=4000) in packages/db/src/index.ts:

  • Query session_messages WHERE session_id=$1 ORDER BY created_at DESC LIMIT $maxMessages
  • Reverse to chronological order
  • Trim leading rows until sum(token_count) <= tokenBudget
  • Return Array<{ role: string; content: string }>

Token counting

Use heuristic Math.ceil(content.length / 4) at insert time, stored in token_count.

Relevant files

  • packages/db/src/schema.ts
  • packages/db/src/index.ts
  • artifacts/api-server/src/routes/sessions.ts

Acceptance

  • Migration applies cleanly on fresh DB
  • getSessionHistory returns messages chronologically, trimmed to budget
  • Manual insert + retrieval round-trip verified
## What Add a `session_messages` table to persist conversation history within a funded session, and a retrieval helper that returns the last N messages trimmed to a token budget. ## Why Currently each request inside a session is a stateless one-shot. Follow-up requests like "make it shorter" or "explain step 2" are meaningless — Timmy has no memory of prior exchanges. ## Schema ```sql CREATE TABLE session_messages ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), session_id UUID NOT NULL REFERENCES sessions(id) ON DELETE CASCADE, role TEXT NOT NULL CHECK (role IN ('user', 'assistant')), content TEXT NOT NULL, token_count INTEGER NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX ON session_messages(session_id, created_at); ``` ## Drizzle migration - Add `session_messages` table to `packages/db/src/schema.ts` - Export `sessionMessages` table and `SessionMessage` type - Generate + apply migration via `pnpm drizzle-kit generate` and `migrate` ## Retrieval helper Create `getSessionHistory(sessionId, maxMessages=8, tokenBudget=4000)` in `packages/db/src/index.ts`: - Query `session_messages WHERE session_id=$1 ORDER BY created_at DESC LIMIT $maxMessages` - Reverse to chronological order - Trim leading rows until `sum(token_count) <= tokenBudget` - Return `Array<{ role: string; content: string }>` ## Token counting Use heuristic `Math.ceil(content.length / 4)` at insert time, stored in `token_count`. ## Relevant files - `packages/db/src/schema.ts` - `packages/db/src/index.ts` - `artifacts/api-server/src/routes/sessions.ts` ## Acceptance - Migration applies cleanly on fresh DB - `getSessionHistory` returns messages chronologically, trimmed to budget - Manual insert + retrieval round-trip verified
replit added the aibackend labels 2026-03-21 00:34:40 +00:00
gemini was assigned by Rockachopa 2026-03-22 23:37:30 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: replit/timmy-tower#38