Octopus
SQL Tables
All SQL-backed Octopus memory is stored in tables created by the SqlServerPlugin migrations. This page documents the complete schema for every table — episodes, episode messages, procedures, agent config, and memory config.
Octopus_Episodes
Stores one row per completed conversation session (episodic memory):
CREATE TABLE Octopus_Episodes (
EpisodeId UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID(),
TenantId UNIQUEIDENTIFIER NOT NULL,
AgentId UNIQUEIDENTIFIER NOT NULL,
UserId NVARCHAR(256) NOT NULL,
StartedAt DATETIME2 NOT NULL,
EndedAt DATETIME2 NULL,
Summary NVARCHAR(MAX) NULL,
KeyFactsJson NVARCHAR(MAX) NULL, -- JSON array of strings
Embedding VARBINARY(MAX) NULL, -- float[] serialized as bytes
IsDeleted BIT NOT NULL DEFAULT 0,
DeletedAt DATETIME2 NULL,
CreatedAt DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
CONSTRAINT PK_Octopus_Episodes PRIMARY KEY (EpisodeId)
);
CREATE INDEX IX_Episodes_AgentUser ON Octopus_Episodes (AgentId, UserId, TenantId) WHERE IsDeleted = 0;
CREATE INDEX IX_Episodes_EndedAt ON Octopus_Episodes (EndedAt DESC) WHERE IsDeleted = 0;
CREATE INDEX IX_Episodes_TenantDelete ON Octopus_Episodes (TenantId, IsDeleted, DeletedAt);
Octopus_EpisodeMessages
Stores individual messages within an episode (for full episode recall):
CREATE TABLE Octopus_EpisodeMessages (
MessageId UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID(),
EpisodeId UNIQUEIDENTIFIER NOT NULL,
TenantId UNIQUEIDENTIFIER NOT NULL,
Role NVARCHAR(20) NOT NULL, -- 'user' | 'assistant' | 'tool'
Content NVARCHAR(MAX) NOT NULL,
TokenCount INT NULL,
CreatedAt DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
CONSTRAINT PK_Octopus_EpisodeMessages PRIMARY KEY (MessageId),
CONSTRAINT FK_EpisodicMessages_Episode FOREIGN KEY (EpisodeId)
REFERENCES Octopus_Episodes (EpisodeId) ON DELETE CASCADE
);
CREATE INDEX IX_EpisodeMessages_Episode ON Octopus_EpisodeMessages (EpisodeId, CreatedAt);
Octopus_Procedures
Stores procedural memory — admin-defined and agent-learned step sequences:
CREATE TABLE Octopus_Procedures (
ProcedureId UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID(),
TenantId UNIQUEIDENTIFIER NOT NULL,
AgentId UNIQUEIDENTIFIER NULL, -- NULL = shared across tenant agents
Name NVARCHAR(200) NOT NULL,
Description NVARCHAR(MAX) NULL,
TriggerPattern NVARCHAR(500) NULL, -- Regex trigger pattern
StepsJson NVARCHAR(MAX) NOT NULL, -- JSON array of ProcedureStep
Embedding VARBINARY(MAX) NULL, -- float[] for semantic matching
IsActive BIT NOT NULL DEFAULT 1,
IsApproved BIT NOT NULL DEFAULT 0,
Version INT NOT NULL DEFAULT 1,
CreatedAt DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
UpdatedAt DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
CreatedBy NVARCHAR(256) NULL,
CONSTRAINT PK_Octopus_Procedures PRIMARY KEY (ProcedureId)
);
CREATE INDEX IX_Procedures_Agent ON Octopus_Procedures (AgentId, TenantId) WHERE IsActive = 1 AND IsApproved = 1;
CREATE INDEX IX_Procedures_Shared ON Octopus_Procedures (TenantId) WHERE AgentId IS NULL AND IsActive = 1;
Octopus_Agents
Stores agent configuration (the AgentComposite data):
CREATE TABLE Octopus_Agents (
AgentId UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID(),
TenantId UNIQUEIDENTIFIER NOT NULL,
Name NVARCHAR(200) NOT NULL,
SystemPrompt NVARCHAR(MAX) NOT NULL,
LLMProvider NVARCHAR(50) NOT NULL, -- 'Anthropic' | 'OpenAI' | 'AzureOpenAI' | 'Ollama'
Model NVARCHAR(100) NOT NULL,
LLMConfigJson NVARCHAR(MAX) NULL, -- Temperature, MaxTokens etc.
MemoryConfigJson NVARCHAR(MAX) NULL, -- AgentMemoryConfig as JSON
IsActive BIT NOT NULL DEFAULT 1,
CreatedAt DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
UpdatedAt DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
CONSTRAINT PK_Octopus_Agents PRIMARY KEY (AgentId)
);
CREATE UNIQUE INDEX UX_Agents_TenantName ON Octopus_Agents (TenantId, Name) WHERE IsActive = 1;
CREATE INDEX IX_Agents_Tenant ON Octopus_Agents (TenantId) WHERE IsActive = 1;
Column Summary
| Column Pattern | Purpose | Present In |
|---|---|---|
TenantId | Multi-tenant isolation — all queries filter by this | All tables |
IsDeleted + DeletedAt | Soft delete — records hidden from queries before hard purge | Episodes |
IsActive | Logical enable/disable without deletion | Procedures, Agents |
Embedding | Serialized float[] for semantic similarity matching | Episodes, Procedures |
*Json columns | Schemaless extension data stored as JSON | Procedures (Steps), Agents (Config) |
CreatedAt / UpdatedAt | Audit trail timestamps (UTC) | All tables |
Migrations Are Automatic
All tables are created and updated by EF Core migrations included in the SqlServerPlugin assembly. You do not need to run DDL scripts manually — the plugin applies all pending migrations on startup via db.Database.MigrateAsync().