Class: AgentC::Agent::Chat

Inherits:
Object
  • Object
show all
Defined in:
lib/agent_c/agent/chat.rb

Constant Summary collapse

NONE =
Object.new

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tools: Tools.all, cached_prompts: [], workspace_dir: nil, record:, session: nil) ⇒ Chat

Returns a new instance of Chat.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/agent_c/agent/chat.rb', line 11

def initialize(
  tools: Tools.all,
  cached_prompts: [],
  workspace_dir: nil,
  record:, # Can be used for testing or continuing existing chats
  session: nil
)
  @session = session
  @logger = session&.config&.logger
  @tools = tools.map do
    if _1.is_a?(Symbol)
      Tools.resolve(
        value: _1,
        available_tools: Tools::NAMES.merge(session&.config&.extra_tools || {}),
        args: {},
        workspace_dir: workspace_dir || session&.config&.workspace_dir
      )
    else
      _1
    end
  end
  @cached_prompts = cached_prompts
  @record_param = record
end

Instance Attribute Details

#cached_promptsObject (readonly)

Returns the value of attribute cached_prompts.



9
10
11
# File 'lib/agent_c/agent/chat.rb', line 9

def cached_prompts
  @cached_prompts
end

#idObject (readonly)

Returns the value of attribute id.



9
10
11
# File 'lib/agent_c/agent/chat.rb', line 9

def id
  @id
end

#loggerObject (readonly)

Returns the value of attribute logger.



9
10
11
# File 'lib/agent_c/agent/chat.rb', line 9

def logger
  @logger
end

#sessionObject (readonly)

Returns the value of attribute session.



9
10
11
# File 'lib/agent_c/agent/chat.rb', line 9

def session
  @session
end

#toolsObject (readonly)

Returns the value of attribute tools.



9
10
11
# File 'lib/agent_c/agent/chat.rb', line 9

def tools
  @tools
end

Instance Method Details

#ask(msg) ⇒ Object



36
37
38
# File 'lib/agent_c/agent/chat.rb', line 36

def ask(msg)
  record.ask(msg)
end

#get(msg, schema: nil, confirm: 1, out_of: 1) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/agent_c/agent/chat.rb', line 86

def get(msg, schema: nil, confirm: 1, out_of: 1)
  requests = 0
  answers = []

  confirmed_answer = NONE

  while(requests < out_of && confirmed_answer == NONE)
    requests += 1
    answers << get_result(msg, schema:)

    current_result = answers.group_by { _1 }.find { _2.count >= confirm }

    if current_result
      confirmed_answer = current_result.first
    end
  end

  if confirmed_answer == NONE
    raise "Unable to confirm an answer:\n#{JSON.pretty_generate(answers)}"
  end

  confirmed_answer
end

#messagesObject



110
111
112
# File 'lib/agent_c/agent/chat.rb', line 110

def messages(...)
  record.messages(...)
end

#recordObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/agent_c/agent/chat.rb', line 114

def record
  @record ||= begin
    # If a record was injected (for continuing existing chat), use it
    # Otherwise create a new chat

    # Set up callbacks and tools
    @record_param
      .with_tools(*tools.flatten)
      .on_new_message { log("message start") }
      .on_end_message do |message|
        log("message end: #{serialize_for_log(message).to_json}")
      end
      .on_tool_call { log("tool_call: #{serialize_for_log(_1).to_json}") }
      .on_tool_result { log("tool_result: #{_1}") }
  end
end

#refine(msg, schema:, times: 2) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/agent_c/agent/chat.rb', line 60

def refine(msg, schema:, times: 2)
  schema = normalize_schema(schema)

  requests = 0
  last_answer = NONE

  while(requests < times)
    requests += 1
    full_msg = (
      if last_answer == NONE
        msg
      else
        I18n.t(
          "agent.chat.refine.system_message",
          prior_answer: last_answer,
          original_message: msg
        )
      end
    )

    last_answer = get_result(full_msg, schema:)
  end

  last_answer
end

#to_hObject



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/agent_c/agent/chat.rb', line 44

def to_h
  record
    .messages
    .map {
      hash = _1.to_llm.to_h

      if hash.key?(:tool_calls)
        hash[:tool_calls] = hash.fetch(:tool_calls).values.map(&:to_h)
      end

      hash
    }
end