first commit
This commit is contained in:
120
framework/configstore/tables/promptVersions.go
Normal file
120
framework/configstore/tables/promptVersions.go
Normal file
@@ -0,0 +1,120 @@
|
||||
// Package tables provides tables for the configstore
|
||||
package tables
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// TablePromptVersion represents an immutable version of a prompt
|
||||
// Once created, a version cannot be modified - to make changes, create a new version
|
||||
type TablePromptVersion struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
PromptID string `gorm:"type:varchar(36);not null;index;uniqueIndex:idx_prompt_version" json:"prompt_id"`
|
||||
Prompt *TablePrompt `gorm:"foreignKey:PromptID" json:"prompt,omitempty"`
|
||||
VersionNumber int `gorm:"not null;uniqueIndex:idx_prompt_version" json:"version_number"`
|
||||
CommitMessage string `gorm:"type:text" json:"commit_message"`
|
||||
ModelParamsJSON *string `gorm:"type:text;column:model_params_json" json:"-"`
|
||||
ModelParams ModelParams `gorm:"-" json:"model_params"`
|
||||
Provider string `gorm:"type:varchar(100)" json:"provider"`
|
||||
Model string `gorm:"type:varchar(100)" json:"model"`
|
||||
VariablesJSON *string `gorm:"type:text;column:variables_json" json:"-"`
|
||||
Variables PromptVariables `gorm:"-" json:"variables,omitempty"` // {key: value} map for Jinja2 variables
|
||||
IsLatest bool `gorm:"not null;default:false" json:"is_latest"`
|
||||
CreatedAt time.Time `gorm:"not null" json:"created_at"`
|
||||
// No UpdatedAt - versions are immutable
|
||||
|
||||
// Relationships
|
||||
Messages []TablePromptVersionMessage `gorm:"foreignKey:VersionID;constraint:OnDelete:CASCADE" json:"messages,omitempty"`
|
||||
}
|
||||
|
||||
// TableName for TablePromptVersion
|
||||
func (TablePromptVersion) TableName() string { return "prompt_versions" }
|
||||
|
||||
// ModelParams represents model configuration parameters as a flexible map
|
||||
// so that any provider-specific params (response_format, seed, logprobs, etc.) are preserved.
|
||||
type ModelParams map[string]interface{}
|
||||
|
||||
// PromptVariables represents a map of Jinja2 variable names to their values.
|
||||
// Sessions store full {key: value} pairs; versions store {key: ""} (keys only).
|
||||
type PromptVariables map[string]string
|
||||
|
||||
// BeforeSave GORM hook to serialize JSON fields
|
||||
func (v *TablePromptVersion) BeforeSave(tx *gorm.DB) error {
|
||||
if v.ModelParams != nil {
|
||||
data, err := json.Marshal(v.ModelParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
paramsStr := string(data)
|
||||
v.ModelParamsJSON = ¶msStr
|
||||
}
|
||||
if v.Variables != nil {
|
||||
varsData, err := json.Marshal(v.Variables)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
varsStr := string(varsData)
|
||||
v.VariablesJSON = &varsStr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AfterFind GORM hook to deserialize JSON fields
|
||||
func (v *TablePromptVersion) AfterFind(tx *gorm.DB) error {
|
||||
if v.ModelParamsJSON != nil && *v.ModelParamsJSON != "" {
|
||||
dec := json.NewDecoder(strings.NewReader(*v.ModelParamsJSON))
|
||||
dec.UseNumber()
|
||||
if err := dec.Decode(&v.ModelParams); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if v.VariablesJSON != nil && *v.VariablesJSON != "" {
|
||||
if err := json.Unmarshal([]byte(*v.VariablesJSON), &v.Variables); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TablePromptVersionMessage represents a message in an immutable prompt version
|
||||
type TablePromptVersionMessage struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
||||
PromptID string `gorm:"type:varchar(36);not null;index" json:"prompt_id"`
|
||||
VersionID uint `gorm:"not null;index;uniqueIndex:idx_version_order" json:"version_id"`
|
||||
Version *TablePromptVersion `gorm:"foreignKey:VersionID" json:"-"`
|
||||
OrderIndex int `gorm:"not null;uniqueIndex:idx_version_order" json:"order_index"`
|
||||
MessageJSON string `gorm:"type:text;not null;column:message_json" json:"-"`
|
||||
Message PromptMessage `gorm:"-" json:"message"`
|
||||
}
|
||||
|
||||
// TableName for TablePromptVersionMessage
|
||||
func (TablePromptVersionMessage) TableName() string { return "prompt_version_messages" }
|
||||
|
||||
// PromptMessage is a raw JSON message stored in the database.
|
||||
// The frontend handles serialization/deserialization of the message format.
|
||||
// The backend treats it as opaque JSON to remain format-agnostic and backward-compatible.
|
||||
type PromptMessage = json.RawMessage
|
||||
|
||||
// BeforeSave GORM hook to serialize JSON fields
|
||||
func (m *TablePromptVersionMessage) BeforeSave(tx *gorm.DB) error {
|
||||
data, err := json.Marshal(m.Message)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.MessageJSON = string(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AfterFind GORM hook to deserialize JSON fields
|
||||
func (m *TablePromptVersionMessage) AfterFind(tx *gorm.DB) error {
|
||||
if m.MessageJSON != "" {
|
||||
if err := json.Unmarshal([]byte(m.MessageJSON), &m.Message); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user