Class: NitroIntelligence::AgentServer

Inherits:
Object
  • Object
show all
Defined in:
lib/nitro_intelligence/agent_server.rb

Defined Under Namespace

Classes: ConfigurationError, RunError, ThreadInitializationError, ThreadResumptionError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_url:, api_key:, user_id: "default-user") ⇒ AgentServer

Returns a new instance of AgentServer.

Raises:



12
13
14
15
16
17
18
19
20
21
# File 'lib/nitro_intelligence/agent_server.rb', line 12

def initialize(base_url:, api_key:, user_id: "default-user")
  raise ConfigurationError, "base_url is required" if base_url.blank?
  raise ConfigurationError, "api_key is required" if api_key.blank?
  raise ConfigurationError, "user_id is required" if user_id.blank?

  @base_url = base_url
  @api_key = api_key
  @user_id = user_id
  @tool_call_review_validator = ToolCallReviewValidator.new
end

Instance Attribute Details

#base_urlObject (readonly)

Returns the value of attribute base_url.



10
11
12
# File 'lib/nitro_intelligence/agent_server.rb', line 10

def base_url
  @base_url
end

#user_idObject (readonly)

Returns the value of attribute user_id.



10
11
12
# File 'lib/nitro_intelligence/agent_server.rb', line 10

def user_id
  @user_id
end

Instance Method Details

#await_run(thread_id:, assistant_id:, messages:, context: {}) ⇒ Object

Raises:



23
24
25
26
27
28
29
30
31
# File 'lib/nitro_intelligence/agent_server.rb', line 23

def await_run(thread_id:, assistant_id:, messages:, context: {})
  raise RunError, "messages cannot be empty" if messages.blank?

  initial_state = messages[0..-2]
  last_message = messages.last

  initialize_thread_if_needed(thread_id:, initial_state:)
  trigger_run(thread_id:, assistant_id:, context:, last_message:)
end

#review_tool_calls(thread_id:, assistant_id:, reviewer_id:, tool_calls:, reviewed_at: DateTime.current.iso8601) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/nitro_intelligence/agent_server.rb', line 52

def review_tool_calls(thread_id:, assistant_id:, reviewer_id:, tool_calls:, reviewed_at: DateTime.current.iso8601)
  resume = { reviewer_id:, reviewed_at:, tool_calls: }.with_indifferent_access
  thread = get_thread(thread_id:)
  raise ThreadResumptionError, "Thread #{thread_id} is not in the interrupted state" unless interrupted?(thread)

  thread_state = get_thread_state(thread_id:)

  @tool_call_review_validator.validate!(
    thread_state:,
    tool_calls: resume[:tool_calls],
    pending_tool_calls: tool_calls_pending_review(thread_id:)
  )

  resume_run(
    thread_id:,
    assistant_id:,
    resume:,
    context: interrupt_context(thread_state)
  )

  nil
end

#tool_calls_pending_review(thread_id:) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/nitro_intelligence/agent_server.rb', line 33

def tool_calls_pending_review(thread_id:)
  thread_state = get_thread_state(thread_id:)
  messages = thread_messages(thread_state)
  reviewed_tool_call_ids = tool_messages(messages).map { |message| message["tool_call_id"] }

  messages.each_with_index.flat_map do |message, index|
    next [] unless message["type"] == "ai"

    pending_tool_calls(message, reviewed_tool_call_ids).map do |tool_call|
      {
        "previous_message_id" => index.zero? ? nil : messages[index - 1]&.dig("id"),
        "id" => tool_call["id"],
        "name" => tool_call["name"],
        "args" => tool_call["args"] || {},
      }
    end
  end
end