Class: Prescient::Agent::Runtime

Inherits:
Object
  • Object
show all
Defined in:
lib/prescient/agent/runtime.rb

Overview

Runs a bounded single-agent tool-calling loop through Prescient::Client.

Instance Method Summary collapse

Constructor Details

#initialize(provider: nil, client: nil, tools: nil, tool_names: [], configuration: Configuration.new, system_prompt: "You are a helpful assistant.", provider_options: {}, generation_options: {}, authorization: nil, telemetry: nil, enable_fallback: true, request_context: {}, audit_log: nil) ⇒ Runtime

Returns a new instance of Runtime.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/prescient/agent/runtime.rb', line 7

def initialize(provider: nil, client: nil, tools: nil, tool_names: [], configuration: Configuration.new,
               system_prompt: "You are a helpful assistant.", provider_options: {}, generation_options: {},
               authorization: nil, telemetry: nil, enable_fallback: true,
               request_context: {}, audit_log: nil)
  @configuration = configuration
  @telemetry = telemetry || configuration.telemetry
  @audit_log = audit_log
  @authorization = authorization || configuration.authorization
  @request_context = request_context
  @system_prompt = system_prompt
  @generation_options = generation_options

  begin
    @client = client || Prescient.client(provider, enable_fallback:, provider_options:)
    configured_tools = tools || tool_names.to_h { |name| [name, Prescient.tool(name)] }
    @registry = ToolRegistry.new(configured_tools.compact)
  rescue StandardError => e
    emit_failure(e, phase: :initialization, loops_run: 0, actions: [])
    raise
  end
end

Instance Method Details

#run(task) ⇒ Result

Execute one bounded agent task.

Parameters:

  • task (String)

    Task instruction

Returns:

  • (Result)

    Completed agent result



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/prescient/agent/runtime.rb', line 32

def run(task)
  actions = []
  loops_run = 0
  validate_task(task)
  context = build_context(task)

  @configuration.max_loops.times do |index|
    loops_run = index + 1
    emit(:iteration, loop: index + 1)
    response = @client.generate_response(task, context.to_a, **@generation_options)
    validate_response!(response)
    unless action_appended?(context, response, actions)
      emit(:completed, loops_run: index + 1, actions: actions.dup, success: true)
      return result(response, index + 1, actions)
    end
  end

  emit(:max_loops_exceeded, loops_run: @configuration.max_loops, actions: actions.dup, success: false)
  raise MaxLoopsExceededError, "agent exceeded maximum loops: #{@configuration.max_loops}"
rescue StandardError => e
  emit_failure(e, phase: :execution, loops_run:, actions: actions.dup)
  raise
end