postgres

package module
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

postgres

Package postgres is a history Store backed by PostgreSQL via pgx. Each conversation's messages live in a single table; messages are serialized to JSONB through the shared tagged core/chat wire codec, so ordered parts, tool results, media, and metadata round-trip with full fidelity. Historical wire must be migrated before upgrading; this package reads and writes only the current tagged format. Example: pool, _ := pgxpool.New(ctx, "postgres://...") store, _ := postgres.NewStore(ctx, postgres.StoreConfig{ Pool: pool, InitializeSchema: true, // create the table+index on first use }) defer pool.Close()

Install

go get github.com/Tangerg/scope/historystores/postgres

Constructors

Every constructor validates its config and returns a value implementing the store capabilities in core/history:

  • NewStore

Testing

This module integrates a third-party service, so its tests cover what runs without live credentials: config validation, request and response mapping, and error classification. The shared conformance contract is core/history/storetest — this module runs it rather than copying it.

An integration probe skips unless its credential environment variable is set, so go test ./... is always runnable offline.

Boundaries

This is an independent leaf module: it carries only its own SDK dependency and never imports a sibling provider. The shared contract every module in this family obeys is in ../ARCHITECTURE.md.

See ARCHITECTURE.md for what this module owns.

Documentation

Overview

Package postgres is a history Store backed by PostgreSQL via pgx.

Each conversation's messages live in a single table; messages are serialized to JSONB through the shared tagged core/chat wire codec, so ordered parts, tool results, media, and metadata round-trip with full fidelity. Historical wire must be migrated before upgrading; this package reads and writes only the current tagged format.

Example:

pool, _ := pgxpool.New(ctx, "postgres://...")
store, _ := postgres.NewStore(ctx, postgres.StoreConfig{
    Pool:             pool,
    InitializeSchema: true, // create the table+index on first use
})
defer pool.Close()

Index

Constants

View Source
const (
	DefaultSchemaName      = "public"
	DefaultTableName       = "chat_history"
	DefaultIndexNameSuffix = "_conversation_idx"
)

Default identifiers used when StoreConfig leaves them blank.

Variables

This section is empty.

Functions

This section is empty.

Types

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store persists canonical chat messages through a caller-owned pgx pool. It never closes the pool; schema initialization is optional and idempotent.

Schema (created when StoreConfig.InitializeSchema is true):

CREATE TABLE <schema>.<table> (
    seq             BIGSERIAL    PRIMARY KEY,
    conversation_id TEXT         NOT NULL,
    message         JSONB        NOT NULL,
    created_at      TIMESTAMPTZ  NOT NULL DEFAULT now()
);
CREATE INDEX <index>
    ON <schema>.<table> (conversation_id, seq);

`seq` is global (BIGSERIAL) so concurrent writers in different conversations don't contend on a per-conversation counter; ordering inside a single conversation is recovered by ORDER BY seq.

func NewStore

func NewStore(ctx context.Context, config StoreConfig) (*Store, error)

func (*Store) Clear

func (s *Store) Clear(ctx context.Context, conversationID history.ConversationID) (err error)

Clear drops every message stored under conversationID. Unknown ids are silently ignored.

func (*Store) Conversations

func (s *Store) Conversations(ctx context.Context) (ids []history.ConversationID, err error)

Conversations returns every stored conversation ID in lexical order.

func (*Store) Read

func (s *Store) Read(ctx context.Context, conversationID history.ConversationID) (storedMessages []chat.Message, err error)

Read returns every message stored under conversationID in insertion order. An empty slice is returned for unknown ids.

func (*Store) Write

func (s *Store) Write(ctx context.Context, conversationID history.ConversationID, messages ...chat.Message) (err error)

Write appends every message under conversationID. Messages within one call are queued in order; concurrent calls may interleave. Empty writes are a no-op.

type StoreConfig

type StoreConfig struct {
	// Pool is the pgx connection pool. Required. The store does not
	// take ownership — callers close the pool themselves.
	Pool *pgxpool.Pool

	// SchemaName is the PostgreSQL schema that holds the chat history
	// table. Optional: defaults to [DefaultSchemaName] ("public").
	SchemaName string

	// TableName is the table that stores serialized messages.
	// Optional: defaults to [DefaultTableName] ("chat_history").
	TableName string

	// IndexName overrides the conversation-id index name generated
	// when InitializeSchema is true. Optional: defaults to
	// "<TableName><DefaultIndexNameSuffix>".
	IndexName string

	// InitializeSchema, when true, creates the table and index if
	// they don't already exist. When false the store assumes the
	// schema is already provisioned.
	InitializeSchema bool
}

func (StoreConfig) Validate

func (s StoreConfig) Validate() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL