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, 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, provider: nil) ⇒ Chat
Returns a new instance of Chat.
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/ask/agent/chat.rb', line 42 def initialize(model:, tools: [], temperature: nil, schema: nil, provider: nil, **) @model_id = model.respond_to?(:id) ? model.id : model.to_s @model_info = Ask::ModelCatalog.find(@model_id) @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.
112 113 114 115 116 117 118 119 |
# File 'lib/ask/agent/chat.rb', line 112 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.
58 59 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 |
# File 'lib/ask/agent/chat.rb', line 58 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.
153 154 155 |
# File 'lib/ask/agent/chat.rb', line 153 def @messages.clear end |
#with_instructions(prompt) ⇒ self
Set or replace the system prompt.
125 126 127 128 129 |
# File 'lib/ask/agent/chat.rb', line 125 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.
139 140 141 142 |
# File 'lib/ask/agent/chat.rb', line 139 def with_params(**params) @extra_params = (@extra_params || {}).merge(params) self end |
#with_schema(schema) ⇒ self
147 148 149 150 |
# File 'lib/ask/agent/chat.rb', line 147 def with_schema(schema) @schema = schema.respond_to?(:to_json_schema) ? schema.to_json_schema : schema self end |