Class: PromptEngine::Prompt

Inherits:
ApplicationRecord show all
Defined in:
app/models/prompt_engine/prompt.rb

Constant Summary collapse

VERSIONED_ATTRIBUTES =
%w[content system_message model temperature max_tokens metadata].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#change_summaryObject

Returns the value of attribute change_summary.



15
16
17
# File 'app/models/prompt_engine/prompt.rb', line 15

def change_summary
  @change_summary
end

Instance Method Details

#current_versionObject



39
40
41
# File 'app/models/prompt_engine/prompt.rb', line 39

def current_version
  versions.first
end

#detect_variablesObject

Parameter management methods



62
63
64
65
# File 'app/models/prompt_engine/prompt.rb', line 62

def detect_variables
  # Don't cache the detector as content can change
  PromptEngine::VariableDetector.new(content).variable_names
end

#render_with_params(provided_params = {}) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'app/models/prompt_engine/prompt.rb', line 100

def render_with_params(provided_params = {})
          detector = PromptEngine::VariableDetector.new(content)

  # Validate all required parameters are provided
  validation = validate_parameters(provided_params)
  return { error: validation[:errors].join(", ") } unless validation[:valid]

  # Cast parameters to their correct types, including defaults
  casted_params = {}
  parameters.each do |param|
    value = provided_params[param.name] || provided_params[param.name.to_sym]
    # Let cast_value handle the default value logic
    casted_params[param.name] = param.cast_value(value)
  end

  # Also include any parameters not defined in the database but present in the template
  detected_vars = detect_variables
  detected_vars.each do |var_name|
    unless casted_params.key?(var_name)
      value = provided_params[var_name] || provided_params[var_name.to_sym]
      casted_params[var_name] = value.to_s if value.present?
    end
  end

  {
    content: detector.render(casted_params),
    system_message: system_message,
    model: model,
    temperature: temperature,
    max_tokens: max_tokens,
    parameters_used: casted_params
  }
end

#restore_version!(version_number) ⇒ Object



47
48
49
50
# File 'app/models/prompt_engine/prompt.rb', line 47

def restore_version!(version_number)
  version = versions.find_by!(version_number: version_number)
  version.restore!
end

#sync_parameters!Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/models/prompt_engine/prompt.rb', line 67

def sync_parameters!
  detected_vars = detect_variables
  existing_names = parameters.pluck(:name)

  # Add new parameters
  new_vars = detected_vars - existing_names
  if new_vars.any?
    # Get max position once, before the loop
    max_position = parameters.maximum(:position) || 0
    detector = PromptEngine::VariableDetector.new(content)

    new_vars.each_with_index do |var_name, index|
      var_info = detector.extract_variables.find { |v| v[:name] == var_name }

      # Skip if parameter already exists (race condition protection)
      next if parameters.exists?(name: var_name)

      parameters.create!(
        name: var_name,
        parameter_type: var_info[:type],
        required: var_info[:required],
        position: max_position + index + 1
      )
    end
  end

  # Remove parameters that no longer exist
  removed_vars = existing_names - detected_vars
  parameters.where(name: removed_vars).destroy_all if removed_vars.any?

  true
end

#validate_parameters(provided_params = {}) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'app/models/prompt_engine/prompt.rb', line 134

def validate_parameters(provided_params = {})
  errors = []

  parameters.each do |param|
    value = provided_params[param.name] || provided_params[param.name.to_sym]
    # Use default value if not provided and parameter is optional
    if value.blank? && !param.required? && param.default_value.present?
      value = param.default_value
    end
    param_errors = param.validate_value(value)
    errors.concat(param_errors)
  end

  {
    valid: errors.empty?,
    errors: errors
  }
end

#version_at(version_number) ⇒ Object



52
53
54
# File 'app/models/prompt_engine/prompt.rb', line 52

def version_at(version_number)
  versions.find_by(version_number: version_number)
end

#version_countObject



43
44
45
# File 'app/models/prompt_engine/prompt.rb', line 43

def version_count
  versions_count
end

#versioned_attributes_changed?Boolean

Returns:

  • (Boolean)


56
57
58
59
# File 'app/models/prompt_engine/prompt.rb', line 56

def versioned_attributes_changed?
  # This method is for checking if versioned attributes have changed before save
  (changed & VERSIONED_ATTRIBUTES).any?
end