Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions framework/configstore/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ func triggerMigrations(ctx context.Context, db *gorm.DB) error {
if err := migrationAddRoutingChainMaxDepthColumn(ctx, db); err != nil {
return err
}
if err := migrationAddPromptVariablesColumns(ctx, db); err != nil {
return err
}
if err := migrationAddModelCapabilityColumns(ctx, db); err != nil {
return err
}
Expand Down Expand Up @@ -5466,6 +5469,50 @@ func migrationAddOpenAIConfigJSONColumn(ctx context.Context, db *gorm.DB) error
return nil
}

// migrationAddPromptVariablesColumns adds variables_json column to prompt_sessions and prompt_versions
func migrationAddPromptVariablesColumns(ctx context.Context, db *gorm.DB) error {
m := migrator.New(db, migrator.DefaultOptions, []*migrator.Migration{{
ID: "add_prompt_variables_columns",
Migrate: func(tx *gorm.DB) error {
tx = tx.WithContext(ctx)
migrator := tx.Migrator()

if !migrator.HasColumn(&tables.TablePromptSession{}, "variables_json") {
if err := migrator.AddColumn(&tables.TablePromptSession{}, "VariablesJSON"); err != nil {
return fmt.Errorf("failed to add variables_json column to prompt_sessions: %w", err)
}
}

if !migrator.HasColumn(&tables.TablePromptVersion{}, "variables_json") {
if err := migrator.AddColumn(&tables.TablePromptVersion{}, "VariablesJSON"); err != nil {
return fmt.Errorf("failed to add variables_json column to prompt_versions: %w", err)
}
}

return nil
},
Rollback: func(tx *gorm.DB) error {
tx = tx.WithContext(ctx)
migrator := tx.Migrator()
if migrator.HasColumn(&tables.TablePromptSession{}, "variables_json") {
if err := migrator.DropColumn(&tables.TablePromptSession{}, "variables_json"); err != nil {
return err
}
}
if migrator.HasColumn(&tables.TablePromptVersion{}, "variables_json") {
if err := migrator.DropColumn(&tables.TablePromptVersion{}, "variables_json"); err != nil {
return err
}
}
return nil
},
}})
if err := m.Migrate(); err != nil {
return fmt.Errorf("error while running add_prompt_variables_columns migration: %s", err.Error())
}
return nil
}

// migrationAddKeyBlacklistedModelsJSONColumn adds blacklisted_models_json to config_keys
// for per-key model deny lists (JSON array of model ids, default []).
func migrationAddKeyBlacklistedModelsJSONColumn(ctx context.Context, db *gorm.DB) error {
Expand Down
22 changes: 22 additions & 0 deletions framework/configstore/tables/promptSessions.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type TablePromptSession struct {
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
CreatedAt time.Time `gorm:"not null" json:"created_at"`
UpdatedAt time.Time `gorm:"not null" json:"updated_at"`

Expand All @@ -40,6 +42,17 @@ func (s *TablePromptSession) BeforeSave(tx *gorm.DB) error {
}
paramsStr := string(data)
s.ModelParamsJSON = &paramsStr

if s.Variables != nil {
varsData, err := json.Marshal(s.Variables)
if err != nil {
return err
}
varsStr := string(varsData)
s.VariablesJSON = &varsStr
} else {
s.VariablesJSON = nil
}
return nil
}

Expand All @@ -52,6 +65,15 @@ func (s *TablePromptSession) AfterFind(tx *gorm.DB) error {
return err
}
}
if s.VariablesJSON != nil && *s.VariablesJSON != "" {
var vars PromptVariables
if err := json.Unmarshal([]byte(*s.VariablesJSON), &vars); err != nil {
return err
}
s.Variables = vars
} else {
s.Variables = nil
}
return nil
}

Expand Down
41 changes: 30 additions & 11 deletions framework/configstore/tables/promptVersions.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ import (
// 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"`
IsLatest bool `gorm:"not null;default:false" json:"is_latest"`
CreatedAt time.Time `gorm:"not null" json:"created_at"`
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
Expand All @@ -36,6 +38,10 @@ func (TablePromptVersion) TableName() string { return "prompt_versions" }
// 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 {
Expand All @@ -46,6 +52,14 @@ func (v *TablePromptVersion) BeforeSave(tx *gorm.DB) error {
paramsStr := string(data)
v.ModelParamsJSON = &paramsStr
}
if v.Variables != nil {
varsData, err := json.Marshal(v.Variables)
if err != nil {
return err
}
varsStr := string(varsData)
v.VariablesJSON = &varsStr
}
return nil
}

Expand All @@ -58,6 +72,11 @@ func (v *TablePromptVersion) AfterFind(tx *gorm.DB) error {
return err
}
}
if v.VariablesJSON != nil && *v.VariablesJSON != "" {
if err := json.Unmarshal([]byte(*v.VariablesJSON), &v.Variables); err != nil {
return err
}
}
return nil
}

Expand Down
47 changes: 36 additions & 11 deletions transports/bifrost-http/handlers/prompts.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,25 +137,28 @@ type CreateVersionRequest struct {
ModelParams tables.ModelParams `json:"model_params"`
Provider string `json:"provider"`
Model string `json:"model"`
Variables tables.PromptVariables `json:"variables,omitempty"`
}

// CreateSessionRequest represents the request body for creating a session
type CreateSessionRequest struct {
Name string `json:"name"`
VersionID *uint `json:"version_id,omitempty"`
Messages []tables.PromptMessage `json:"messages,omitempty"`
ModelParams tables.ModelParams `json:"model_params"`
Provider string `json:"provider"`
Model string `json:"model"`
Name string `json:"name"`
VersionID *uint `json:"version_id,omitempty"`
Messages []tables.PromptMessage `json:"messages,omitempty"`
ModelParams tables.ModelParams `json:"model_params"`
Provider string `json:"provider"`
Model string `json:"model"`
Variables tables.PromptVariables `json:"variables,omitempty"`
}

// UpdateSessionRequest represents the request body for updating a session
type UpdateSessionRequest struct {
Name string `json:"name"`
Messages []tables.PromptMessage `json:"messages"`
ModelParams tables.ModelParams `json:"model_params"`
Provider string `json:"provider"`
Model string `json:"model"`
Name string `json:"name"`
Messages []tables.PromptMessage `json:"messages"`
ModelParams tables.ModelParams `json:"model_params"`
Provider string `json:"provider"`
Model string `json:"model"`
Variables tables.PromptVariables `json:"variables,omitempty"`
}

// RenameSessionRequest represents the request body for renaming a session
Expand Down Expand Up @@ -631,12 +634,22 @@ func (h *PromptsHandler) createVersion(ctx *fasthttp.RequestCtx) {
})
}

// Strip variable values — versions store keys only; values live in sessions
var versionVars tables.PromptVariables
if len(req.Variables) > 0 {
versionVars = make(tables.PromptVariables, len(req.Variables))
for key := range req.Variables {
versionVars[key] = ""
}
}

version := &tables.TablePromptVersion{
PromptID: promptID,
CommitMessage: req.CommitMessage,
ModelParams: req.ModelParams,
Provider: req.Provider,
Model: req.Model,
Variables: versionVars,
Messages: messages,
}

Expand Down Expand Up @@ -835,6 +848,7 @@ func (h *PromptsHandler) createSession(ctx *fasthttp.RequestCtx) {
ModelParams: req.ModelParams,
Provider: req.Provider,
Model: req.Model,
Variables: req.Variables,
Messages: messages,
}

Expand Down Expand Up @@ -890,6 +904,7 @@ func (h *PromptsHandler) updateSession(ctx *fasthttp.RequestCtx) {
session.ModelParams = req.ModelParams
session.Provider = req.Provider
session.Model = req.Model
session.Variables = req.Variables

// Update messages
var messages []tables.TablePromptSessionMessage
Expand Down Expand Up @@ -1066,12 +1081,22 @@ func (h *PromptsHandler) commitSession(ctx *fasthttp.RequestCtx) {
return
}

// Copy variable keys from session with empty values for the version
var versionVars tables.PromptVariables
if len(session.Variables) > 0 {
versionVars = make(tables.PromptVariables, len(session.Variables))
for key := range session.Variables {
versionVars[key] = ""
}
}

version := &tables.TablePromptVersion{
PromptID: session.PromptID,
CommitMessage: req.CommitMessage,
ModelParams: session.ModelParams,
Provider: session.Provider,
Model: session.Model,
Variables: versionVars,
Messages: messages,
}

Expand Down
11 changes: 11 additions & 0 deletions ui/app/workspace/mcp-logs/views/bifrost.code-workspace
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"folders": [
{
"path": "../../../../.."
},
{
"path": "../../../../../../bifrost-enterprise"
}
],
"settings": {}
}
Loading
Loading