Class: Ask::Agent::Chat
- Inherits:
-
Object
- Object
- Ask::Agent::Chat
- Defined in:
- lib/ask/agent/chat.rb
Overview
Thin wrapper around Provider + an internal message array that presents a Chat-like API for ask-agent internal use.
Manages conversation history, resolves the correct provider/model, handles streaming chunk accumulation, and normalises tool call formats between Ask::Provider (Array of Hashes) and ask-agent internal usage (Hash of { id => ToolCallInfo }).
Instance Attribute Summary collapse
-
#messages ⇒ Array<Ask::Message>
readonly
All messages in the conversation.
-
#model_id ⇒ String
readonly
Model ID (e.g. “gpt-4o”).
Instance Method Summary collapse
-
#add_message(role:, content: nil, tool_call_id: nil, tool_calls: nil) ⇒ Object
Add a message to the conversation history.
-
#ask(message = nil) {|ChatChunk| ... } ⇒ ResponseMessage
Send a user message and get a completion response.
-
#initialize(model:, tools: [], temperature: nil, schema: nil, assume_model_exists: false, provider: nil) ⇒ Chat
constructor
A new instance of Chat.
-
#model ⇒ String
Model ID (e.g. “gpt-4o”).
-
#reset_messages! ⇒ Object
Clear all messages from the conversation.
-
#with_instructions(prompt) ⇒ self
Set or replace the system prompt.
-
#with_params(**params) ⇒ self
Set additional parameters for the provider call and return self.
- #with_schema(schema) ⇒ self
Constructor Details
#initialize(model:, tools: [], temperature: nil, schema: nil, assume_model_exists: false, provider: nil) ⇒ Chat
Returns a new instance of Chat.
43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/ask/agent/chat.rb', line 43 def initialize(model:, tools: [], temperature: nil, schema: nil, assume_model_exists: false, provider: nil, **) @model_id = model.respond_to?(:id) ? model.id : model.to_s @model_info = resolve_model(@model_id) unless assume_model_exists @tools = tools @temperature = temperature @schema = schema @messages = [] @provider_override = provider @provider = nil end |
Instance Attribute Details
#messages ⇒ Array<Ask::Message> (readonly)
Returns all messages in the conversation.
35 36 37 |
# File 'lib/ask/agent/chat.rb', line 35 def @messages end |
#model_id ⇒ String (readonly)
Returns model ID (e.g. “gpt-4o”).
29 30 31 |
# File 'lib/ask/agent/chat.rb', line 29 def model_id @model_id end |
Instance Method Details
#add_message(role:, content: nil, tool_call_id: nil, tool_calls: nil) ⇒ Object
Add a message to the conversation history.
114 115 116 117 118 119 120 121 |
# File 'lib/ask/agent/chat.rb', line 114 def (role:, content: nil, tool_call_id: nil, tool_calls: nil) @messages << Ask::Message.new( role: role, content: content, tool_call_id: tool_call_id, tool_calls: tool_calls ) end |
#ask(message = nil) {|ChatChunk| ... } ⇒ ResponseMessage
Send a user message and get a completion response.
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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/ask/agent/chat.rb', line 60 def ask( = nil, &block) @messages << Ask::Message.new(role: :user, content: .to_s) if stream = block_given? tool_defs = @tools.map { |t| Ask::ToolDef.from_tool(t) } # Accumulator for tool calls during streaming (keyed by index) calls_acc = {} result = provider.chat( @messages.map(&:to_h), model: @model_id, tools: tool_defs, temperature: @temperature, stream: stream, schema: @schema&.respond_to?(:to_json_schema) ? @schema.to_json_schema : @schema, **(@extra_params || {}) ) do |raw_chunk| next unless block_given? # Accumulate tool calls by index during streaming accumulate_tool_calls(raw_chunk, calls_acc) # Yield adapted chunk with current tool call state yield ChatChunk.new( content: raw_chunk.content, tool_calls: build_current_tool_calls(calls_acc), thinking: raw_chunk.respond_to?(:thinking) ? raw_chunk.thinking : nil ) end response_msg = if stream build_stream_response(result, calls_acc) else build_response(result) end # Store assistant response in conversation history @messages << Ask::Message.new( role: :assistant, content: response_msg.content, tool_calls: response_msg.tool_calls&.values&.map { |tc| { id: tc.id, type: "function", name: tc.name, arguments: tc.arguments } } ) response_msg end |
#model ⇒ String
Returns model ID (e.g. “gpt-4o”).
31 32 33 |
# File 'lib/ask/agent/chat.rb', line 31 def model @model_id end |
#reset_messages! ⇒ Object
Clear all messages from the conversation.
155 156 157 |
# File 'lib/ask/agent/chat.rb', line 155 def @messages.clear end |
#with_instructions(prompt) ⇒ self
Set or replace the system prompt.
127 128 129 130 131 |
# File 'lib/ask/agent/chat.rb', line 127 def with_instructions(prompt) @messages.reject! { |m| m.role == :system } @messages.unshift(Ask::Message.new(role: :system, content: prompt)) self end |
#with_params(**params) ⇒ self
Set additional parameters for the provider call and return self.
141 142 143 144 |
# File 'lib/ask/agent/chat.rb', line 141 def with_params(**params) @extra_params = (@extra_params || {}).merge(params) self end |
#with_schema(schema) ⇒ self
149 150 151 152 |
# File 'lib/ask/agent/chat.rb', line 149 def with_schema(schema) @schema = schema.respond_to?(:to_json_schema) ? schema.to_json_schema : schema self end |