Class: ActiveAgent::Base

Inherits:
AbstractController::Base
  • Object
show all
Includes:
AbstractController::AssetPaths, AbstractController::Caching, AbstractController::Callbacks, AbstractController::Helpers, AbstractController::Logger, AbstractController::Rendering, AbstractController::Translation, ActionView::Layouts, Callbacks, GenerationMethods, GenerationProvider, Parameterized, Previews, QueuedGeneration, Rescuable
Defined in:
lib/active_agent/base.rb

Defined Under Namespace

Classes: LateAttachmentsProxy, NullPrompt

Constant Summary collapse

PROTECTED_IVARS =
AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [:@_action_has_layout]

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Rescuable

#handle_exceptions

Methods included from GenerationProvider

#generation_provider

Methods included from GenerationMethods

#wrap_generation_behavior!

Constructor Details

#initializeBase



232
233
234
235
236
# File 'lib/active_agent/base.rb', line 232

def initialize
  super
  @_prompt_was_called = false
  @_context = ActiveAgent::ActionPrompt::Prompt.new(instructions: options[:instructions])
end

Class Attribute Details

.agent_nameObject

Returns the name of the current agent. This method is also being used as a path for a view lookup. If this is an anonymous agent, this method will return anonymous instead.



141
142
143
# File 'lib/active_agent/base.rb', line 141

def agent_name
  @agent_name ||= anonymous? ? "anonymous" : name.underscore
end

Class Method Details

.controller_pathObject

Returns the name of the current agent. This method is also being used as a path for a view lookup. If this is an anonymous agent, this method will return anonymous instead.



146
147
148
# File 'lib/active_agent/base.rb', line 146

def agent_name
  @agent_name ||= anonymous? ? "anonymous" : name.underscore
end

.default(value = nil) ⇒ Object Also known as: default_options=

Sets the defaults through app configuration:

config.action_agent.default(from: "[email protected]")

Aliased by ::default_options=



153
154
155
156
# File 'lib/active_agent/base.rb', line 153

def default(value = nil)
  self.default_params = default_params.merge(value).freeze if value
  default_params
end

.generate_prompt(prompt) ⇒ Object

Wraps a prompt generation inside of ActiveSupport::Notifications instrumentation.

This method is actually called by the ActionPrompt::Prompt object itself through a callback when you call :generate_prompt on the ActionPrompt::Prompt, calling generate_prompt directly and passing an ActionPrompt::Prompt will do nothing except tell the logger you generated the prompt.



168
169
170
171
172
173
# File 'lib/active_agent/base.rb', line 168

def generate_prompt(prompt) # :nodoc:
  ActiveSupport::Notifications.instrument("deliver.active_agent") do |payload|
    set_payload_for_prompt(payload, prompt)
    yield # Let Prompt do the generation actions
  end
end

.generate_with(provider, **options) ⇒ Object

Define how the agent should generate content



129
130
131
132
133
# File 'lib/active_agent/base.rb', line 129

def generate_with(provider, **options)
  self.generation_provider = provider
  self.options = (options || {}).merge(options)
  generation_provider.config.merge!(options)
end

.observer_class_for(value) ⇒ Object

:nodoc:



118
119
120
121
122
123
124
125
# File 'lib/active_agent/base.rb', line 118

def observer_class_for(value) # :nodoc:
  case value
  when String, Symbol
    value.to_s.camelize.constantize
  else
    value
  end
end

.register_interceptor(interceptor) ⇒ Object

Register an Interceptor which will be called before prompt is sent. Either a class, string, or symbol can be passed in as the Interceptor. If a string or symbol is passed in it will be camelized and constantized.



107
108
109
# File 'lib/active_agent/base.rb', line 107

def register_interceptor(interceptor)
  Prompt.register_interceptor(observer_class_for(interceptor))
end

.register_interceptors(*interceptors) ⇒ Object

Register one or more Interceptors which will be called before prompt is sent.



81
82
83
# File 'lib/active_agent/base.rb', line 81

def register_interceptors(*interceptors)
  interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
end

.register_observer(observer) ⇒ Object

Register an Observer which will be notified when prompt is generated. Either a class, string, or symbol can be passed in as the Observer. If a string or symbol is passed in it will be camelized and constantized.



93
94
95
# File 'lib/active_agent/base.rb', line 93

def register_observer(observer)
  Prompt.register_observer(observer_class_for(observer))
end

.register_observers(*observers) ⇒ Object

Register one or more Observers which will be notified when prompt is generated.



71
72
73
# File 'lib/active_agent/base.rb', line 71

def register_observers(*observers)
  observers.flatten.compact.each { |observer| register_observer(observer) }
end

.stream_with(&stream) ⇒ Object



135
136
137
# File 'lib/active_agent/base.rb', line 135

def stream_with(&stream)
  self.options = (options || {}).merge(stream: stream)
end

.unregister_interceptor(interceptor) ⇒ Object

Unregister a previously registered Interceptor. Either a class, string, or symbol can be passed in as the Interceptor. If a string or symbol is passed in it will be camelized and constantized.



114
115
116
# File 'lib/active_agent/base.rb', line 114

def unregister_interceptor(interceptor)
  Prompt.unregister_interceptor(observer_class_for(interceptor))
end

.unregister_interceptors(*interceptors) ⇒ Object

Unregister one or more previously registered Interceptors.



86
87
88
# File 'lib/active_agent/base.rb', line 86

def unregister_interceptors(*interceptors)
  interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) }
end

.unregister_observer(observer) ⇒ Object

Unregister a previously registered Observer. Either a class, string, or symbol can be passed in as the Observer. If a string or symbol is passed in it will be camelized and constantized.



100
101
102
# File 'lib/active_agent/base.rb', line 100

def unregister_observer(observer)
  Prompt.unregister_observer(observer_class_for(observer))
end

.unregister_observers(*observers) ⇒ Object

Unregister one or more previously registered Observers.



76
77
78
# File 'lib/active_agent/base.rb', line 76

def unregister_observers(*observers)
  observers.flatten.compact.each { |observer| unregister_observer(observer) }
end

Instance Method Details

#action_schemasObject



333
334
335
336
337
338
339
# File 'lib/active_agent/base.rb', line 333

def action_schemas
  action_methods.map do |action|
    if action != "prompt"
      JSON.parse render_to_string(locals: {action_name: action}, action: action, formats: :json)
    end
  end.compact
end

#agent_nameObject

Returns the name of the agent object.



271
272
273
# File 'lib/active_agent/base.rb', line 271

def agent_name
  self.class.agent_name
end

#handle_response(response) ⇒ Object



212
213
214
215
# File 'lib/active_agent/base.rb', line 212

def handle_response(response)
  perform_actions(requested_actions: response.message.requested_actions) if response.message.requested_actions.present?
  update_context(response)
end

#headers(args = nil) ⇒ Object



275
276
277
278
279
280
281
# File 'lib/active_agent/base.rb', line 275

def headers(args = nil)
  if args
    @_context.headers(args)
  else
    @_context
  end
end

#perform_action(action) ⇒ Object



228
229
230
# File 'lib/active_agent/base.rb', line 228

def perform_action(action)
  process(action.name, *action.params)
end

#perform_actions(requested_actions:) ⇒ Object



222
223
224
225
226
# File 'lib/active_agent/base.rb', line 222

def perform_actions(requested_actions:)
  requested_actions.each do |action|
    perform_action(action)
  end
end

#perform_generationObject



205
206
207
208
209
210
# File 'lib/active_agent/base.rb', line 205

def perform_generation
  context.options.merge(options)      
  generation_provider.generate(context) if context && generation_provider
  handle_response(generation_provider.response)      
  generation_provider.response
end

#process(method_name, *args) ⇒ Object

:nodoc:



238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/active_agent/base.rb', line 238

def process(method_name, *args) # :nodoc:
  payload = {
    agent: self.class.name,
    action: method_name,
    args: args
  }

  ActiveSupport::Notifications.instrument("process.active_agent", payload) do
    super
    @_context = ActiveAgent::ActionPrompt::Prompt.new unless @_prompt_was_called
  end
end

#prompt(headers = {}, &block) ⇒ Object



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/active_agent/base.rb', line 312

def prompt(headers = {}, &block)
  return context if @_prompt_was_called && headers.blank? && !block

  content_type = headers[:content_type]

  headers = apply_defaults(headers)

  context.charset = charset = headers[:charset]

  responses = collect_responses(headers, &block)

  @_prompt_was_called = true

  create_parts_from_responses(context, responses)

  context.content_type = set_content_type(context, content_type, headers[:content_type])
  context.charset = charset
  context.actions = headers[:actions] || action_schemas
  context
end

#prompt_withObject



308
309
310
# File 'lib/active_agent/base.rb', line 308

def prompt_with(*)
  context.update_context(*)
end

#update_context(response) ⇒ Object



217
218
219
220
# File 'lib/active_agent/base.rb', line 217

def update_context(response)
  context.message = response.message
  context.messages << response.message
end