Skip to content

feat(ai): add persistent conversation store backends - #1540

Open
beatenevo wants to merge 8 commits into
apache:aifrom
beatenevo:feat/ai-gorm-store
Open

feat(ai): add persistent conversation store backends#1540
beatenevo wants to merge 8 commits into
apache:aifrom
beatenevo:feat/ai-gorm-store

Conversation

@beatenevo

@beatenevo beatenevo commented Aug 22, 2026

Copy link
Copy Markdown

Please provide a description of this PR:

This PR adds pluggable persistence for AI conversation data.

Related to #1502.

Changes

  • Define SessionStore, MessageStore, and the combined Store interfaces.
  • Migrate in-memory Session, Turn, and Genkit ai.Message handling to MemoryStore.
  • Inject one shared Store instance into the Session Manager, Agent, and Memory Tool.
  • Add GORM models for Sessions, Turns, and Messages.
  • Implement GormStore for persistent conversation history.
  • Add Memory/GORM backend configuration and database connection initialization.
  • Add schema migration support.
  • Use max_turns as the single Turn-limit configuration for both backends.
  • Return ErrTurnLimitReached when a Session attempts to create a Turn beyond the configured limit.
  • Add transactional writes, Turn finalization, and Session-associated data deletion.
  • Enforce message ordering with a unique (turn_id, sequence) constraint.
  • Delete Messages and Turns explicitly without database foreign keys.
  • Prevent expiration cleanup from deleting a Session refreshed by another instance.
  • Use a cancellation-independent persistence context for generated message writes and final Turn finalization, so client disconnects do not interrupt already-generated data persistence.
  • Keep HistoryMemory only as a lazily initialized compatibility layer; production Agent, Memory Tool, and Session Manager paths use Store interfaces exclusively.
  • Add contract, rollback, restart recovery, multi-instance sharing, JSON codec, max-turn, persistence-context, and component regression tests.

Testing

The following checks pass in the ai/ Go module:

  • go test ./...
  • go vet ./...
  • go test -race ./store/... ./component/agent/react ./component/tools/test ./component/server/engine ./component/server/engine/sse

SQLite is used for local persistence and behavioral tests. MySQL and PostgreSQL drivers are included and compile successfully. Service-backed MySQL/PostgreSQL integration tests are outside the current PR because CI database services are not configured.

To help us figure out who should review this PR, please put an X in all the areas that this PR affects.

  • Docs
  • Installation
  • User Experience
  • Dubboctl
  • Console
  • Core Component

Please check any characteristics that apply to this pull request.

@robocanic

Copy link
Copy Markdown
Contributor

@larry-zy

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds pluggable, persistent AI conversation storage shared across agents, tools, sessions, and server components.

Changes:

  • Introduces memory and GORM store backends with migrations and limits.
  • Injects one shared store throughout AI runtime components.
  • Adds configuration schemas and comprehensive backend tests.

Reviewed changes

Copilot reviewed 39 out of 40 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
ai/store/types.go Defines persisted session and turn types.
ai/store/store.go Defines conversation store interfaces.
ai/store/errors.go Adds store sentinel errors.
ai/store/memory/store.go Implements in-memory storage.
ai/store/gorm/store.go Implements relational storage.
ai/store/gorm/models.go Defines GORM database models.
ai/store/gorm/dialector.go Opens supported databases.
ai/store/gorm/codec.go Serializes Genkit messages.
ai/store/gorm/codec_test.go Tests message serialization.
ai/store/gorm/store_test.go Tests persistence and transactions.
ai/store/test/contract.go Defines shared backend contract tests.
ai/store/test/memory_store_test.go Tests memory-store behavior.
ai/component/memory/config.go Adds backend/database configuration.
ai/component/memory/factory.go Applies configuration defaults.
ai/component/memory/component.go Owns and initializes the shared store.
ai/component/memory/config_test.go Tests configuration and lifecycle.
ai/component/agent/agent.go Adds request context to agent interactions.
ai/component/agent/react/react.go Persists interaction history and turns.
ai/component/agent/react/steps.go Reads and writes through MessageStore.
ai/component/agent/react/orchestrator.go Carries persistence context.
ai/component/agent/react/component.go Injects the shared store.
ai/component/agent/react/component_store_test.go Verifies store injection.
ai/component/agent/react/persistence_context_test.go Tests detached persistence contexts.
ai/component/agent/react/page_context_test.go Updates page-context tests.
ai/component/agent/react/step_test.go Updates step tests for stores.
ai/component/tools/engine/tools.go Injects MessageStore into tools.
ai/component/tools/engine/memory_tools.go Reads persisted conversation history.
ai/component/tools/test/engine_tools_test.go Tests shared-store tool access.
ai/component/server/component.go Injects stores and manages router cleanup.
ai/component/server/engine/router.go Constructs store-backed session routing.
ai/component/server/engine/handlers.go Uses persistent session operations.
ai/component/server/engine/handlers_test.go Updates handler tests.
ai/component/server/engine/session/session.go Replaces session maps with SessionStore.
ai/component/server/engine/session/session_test.go Tests shared session storage.
ai/component/server/engine/sse/sse_test.go Adds SSE behavior tests.
ai/config/test/loader_test.go Tests GORM configuration loading.
ai/schema/json/memory.schema.json Defines backend configuration schema.
ai/schema/json/REQUIRED_FIELDS.md Documents new configuration fields.
ai/go.mod Adds GORM database dependencies.
ai/go.sum Records dependency checksums.
Suppressed comments (2)

ai/component/server/engine/handlers.go:212

  • SessionStore.Get can now return arbitrary GORM/database failures, but this maps every error to 404 and labels it "Session not found". Return 404 only for ErrSessionNotFound/ErrSessionExpired; operational failures should produce a sanitized 5xx response.
	sessionObj, err := h.sessionMgr.GetSession(c.Request.Context(), sessionID)
	if err != nil {
		c.JSON(http.StatusNotFound, NewErrorResponse("Session not found: "+err.Error()))
		return

ai/component/server/engine/handlers.go:245

  • A failed database transaction is also mapped to 404 here, even when the session exists. Check specifically for ErrSessionNotFound; return a sanitized 5xx response for other persistence errors so clients do not treat an outage as a missing resource.
	if err := h.sessionMgr.DeleteSession(c.Request.Context(), sessionID); err != nil {
		c.JSON(http.StatusNotFound, NewErrorResponse("Session not found: "+err.Error()))
		return

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread ai/store/store.go Outdated
Comment thread ai/store/gorm/store.go Outdated
Comment thread ai/store/memory/store.go Outdated
Comment thread ai/component/agent/react/react.go Outdated
Comment thread ai/store/gorm/store.go Outdated
Comment thread ai/component/server/engine/handlers.go Outdated
Comment thread ai/component/server/engine/handlers.go Outdated
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants