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_schema(schema) ⇒ self
Set the structured output schema and return 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 ) 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.
143 144 145 |
# File 'lib/ask/agent/chat.rb', line 143 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_schema(schema) ⇒ self
Set the structured output schema and return self.
137 138 139 140 |
# File 'lib/ask/agent/chat.rb', line 137 def with_schema(schema) @schema = schema.respond_to?(:to_json_schema) ? schema.to_json_schema : schema self end |