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 ⇒ 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) ⇒ Chat
constructor
A new instance of Chat.
-
#reset_messages! ⇒ Object
Clear all messages from the conversation.
-
#with_instructions(prompt) ⇒ self
Set or replace the system prompt.
Constructor Details
#initialize(model:, tools: [], temperature: nil, schema: nil) ⇒ Chat
Returns a new instance of Chat.
38 39 40 41 42 43 44 45 46 |
# File 'lib/ask/agent/chat.rb', line 38 def initialize(model:, tools: [], temperature: nil, schema: nil, **) @model_id = model.respond_to?(:id) ? model.id : model.to_s @model_info = resolve_model(@model_id) @tools = tools @temperature = temperature @schema = schema @messages = [] @provider = nil end |
Instance Attribute Details
#messages ⇒ Array<Ask::Message> (readonly)
Returns all messages in the conversation.
32 33 34 |
# File 'lib/ask/agent/chat.rb', line 32 def @messages end |
#model ⇒ String (readonly)
Returns model ID (e.g. “gpt-4o”).
29 30 31 |
# File 'lib/ask/agent/chat.rb', line 29 def model @model end |
Instance Method Details
#add_message(role:, content: nil, tool_call_id: nil, tool_calls: nil) ⇒ Object
Add a message to the conversation history.
107 108 109 110 111 112 113 114 |
# File 'lib/ask/agent/chat.rb', line 107 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.
53 54 55 56 57 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 |
# File 'lib/ask/agent/chat.rb', line 53 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 ) 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 |
#reset_messages! ⇒ Object
Clear all messages from the conversation.
127 128 129 |
# File 'lib/ask/agent/chat.rb', line 127 def @messages.clear end |
#with_instructions(prompt) ⇒ self
Set or replace the system prompt.
120 121 122 123 124 |
# File 'lib/ask/agent/chat.rb', line 120 def with_instructions(prompt) @messages.reject! { |m| m.role == :system } @messages.unshift(Ask::Message.new(role: :system, content: prompt)) self end |