Class: Raif::Task

Direct Known Subclasses

Evals::LlmJudge

Constant Summary

Constants included from Concerns::LlmResponseParsing

Concerns::LlmResponseParsing::ASCII_CONTROL_CHARS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Concerns::JsonSchemaDefinition

#schema_for_instance

Methods included from Concerns::LlmResponseParsing

#parse_html_response, #parse_json_response, #parsed_response

Methods included from Concerns::HasAvailableModelTools

#available_model_tools_map

Methods included from Concerns::HasRequestedLanguage

#requested_language_name, #system_prompt_language_preference

Methods included from Concerns::HasLlm

#default_llm_model_key, #llm

Methods inherited from ApplicationRecord

table_name_prefix, where_json_not_blank

Instance Attribute Details

#filesObject

Returns the value of attribute files.



71
72
73
# File 'app/models/raif/task.rb', line 71

def files
  @files
end

#imagesObject

Returns the value of attribute images.



71
72
73
# File 'app/models/raif/task.rb', line 71

def images
  @images
end

Class Method Details

.json_response_schema(&block) ⇒ Object



179
180
181
182
183
184
185
# File 'app/models/raif/task.rb', line 179

def self.json_response_schema(&block)
  if block_given?
    json_schema_definition(:json_response, &block)
  elsif schema_defined?(:json_response)
    schema_for(:json_response)
  end
end

.prompt(creator: nil, **args) ⇒ String

Returns the LLM prompt for the task.

Parameters:

  • creator (Object, nil) (defaults to: nil)

    The creator of the task (polymorphic association), optional

  • args (Hash)

    Additional arguments to pass to the instance of the task that is created.

Returns:

  • (String)

    The LLM prompt for the task.



166
167
168
# File 'app/models/raif/task.rb', line 166

def self.prompt(creator: nil, **args)
  new(creator:, **args).build_prompt
end

.run(creator: nil, available_model_tools: [], llm_model_key: nil, images: [], files: [], **args) ⇒ Raif::Task?

The primary interface for running a task. It will hit the LLM with the task’s prompt and system prompt and return a Raif::Task object. It will also create a new Raif::ModelCompletion record.

Parameters:

  • creator (Object, nil) (defaults to: nil)

    The creator of the task (polymorphic association), optional

  • available_model_tools (Array<Class>) (defaults to: [])

    Optional array of model tool classes that will be provided to the LLM for it to invoke.

  • llm_model_key (Symbol, String) (defaults to: nil)

    Optional key for the LLM model to use. If blank, Raif.config.default_llm_model_key will be used.

  • images (Array) (defaults to: [])

    Optional array of Raif::ModelImageInput objects to include with the prompt.

  • files (Array) (defaults to: [])

    Optional array of Raif::ModelFileInput objects to include with the prompt.

  • args (Hash)

    Additional arguments to pass to the instance of the task that is created.

Returns:

  • (Raif::Task, nil)

    The task instance that was created and run.



98
99
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
# File 'app/models/raif/task.rb', line 98

def self.run(creator: nil, available_model_tools: [], llm_model_key: nil, images: [], files: [], **args)
  task = new(
    creator: creator,
    llm_model_key: llm_model_key,
    available_model_tools: available_model_tools,
    started_at: Time.current,
    images: images,
    files: files,
    **args
  )

  task.save!
  task.run
  task
rescue StandardError => e
  task&.failed!

  logger.error e.message
  logger.error e.backtrace.join("\n")

  if defined?(Airbrake)
    notice = Airbrake.build_notice(e)
    notice[:context][:component] = "raif_task"
    notice[:context][:action] = name

    Airbrake.notify(notice)
  end

  task
end

.system_prompt(creator: nil, **args) ⇒ String

Returns the LLM system prompt for the task.

Parameters:

  • creator (Object, nil) (defaults to: nil)

    The creator of the task (polymorphic association), optional

  • args (Hash)

    Additional arguments to pass to the instance of the task that is created.

Returns:

  • (String)

    The LLM system prompt for the task.



175
176
177
# File 'app/models/raif/task.rb', line 175

def self.system_prompt(creator: nil, **args)
  new(creator:, **args).build_system_prompt
end

Instance Method Details

#build_promptObject

Raises:

  • (NotImplementedError)


194
195
196
# File 'app/models/raif/task.rb', line 194

def build_prompt
  raise NotImplementedError, "Raif::Task subclasses must implement #build_prompt"
end

#build_system_promptObject



198
199
200
201
202
203
# File 'app/models/raif/task.rb', line 198

def build_system_prompt
  sp = Raif.config.task_system_prompt_intro
  sp = sp.call(self) if sp.respond_to?(:call)
  sp += system_prompt_language_preference if requested_language_key.present?
  sp
end

#json_response_schemaObject

Instance method to get the JSON response schema For instance-dependent schemas, builds the schema with this instance as context For class-level schemas, returns the class-level schema



190
191
192
# File 'app/models/raif/task.rb', line 190

def json_response_schema
  schema_for_instance(:json_response)
end

#messagesObject



157
158
159
# File 'app/models/raif/task.rb', line 157

def messages
  [{ "role" => "user", "content" => message_content }]
end

#re_runObject



152
153
154
155
# File 'app/models/raif/task.rb', line 152

def re_run
  update_columns(started_at: Time.current)
  run(skip_prompt_population: true)
end

#run(skip_prompt_population: false) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'app/models/raif/task.rb', line 129

def run(skip_prompt_population: false)
  update_columns(started_at: Time.current) if started_at.nil?

  populate_prompts unless skip_prompt_population

  mc = llm.chat(
    messages: messages,
    source: self,
    system_prompt: system_prompt,
    response_format: response_format.to_sym,
    available_model_tools: available_model_tools,
    temperature: self.class.temperature
  )

  self.raif_model_completion = mc.becomes(Raif::ModelCompletion)

  update(raw_response: raif_model_completion.raw_response)

  process_model_tool_invocations
  completed!
  self
end

#statusObject



76
77
78
79
80
81
82
83
84
85
86
# File 'app/models/raif/task.rb', line 76

def status
  if completed_at?
    :completed
  elsif failed_at?
    :failed
  elsif started_at?
    :in_progress
  else
    :pending
  end
end