ask-agent 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb3f240855fe04ef37b3d474cd4f9ddae5db28256673aa1d1804bdfbc1a8836c
4
- data.tar.gz: 84684f83697510a261de607ede4a6aafd2a396a2151d169290769148214bc4a0
3
+ metadata.gz: f9b59871c0216de559acd011a9553c650ca4f3714150c7e71811b375a92f2a48
4
+ data.tar.gz: edb6f7137010f1c448da22ca99a7cf2c90dda29f70d210db4c2e18d5f4079568
5
5
  SHA512:
6
- metadata.gz: 41ac967bf49f11bea0d4a65d9984ddfc0838007096b153c2294691abd8ce3bdd60aae0890e10f7bfed39ce2ed0b7f71f577e33d10a029f1660c6b779b4117f13
7
- data.tar.gz: e097d8c0bbd5bf5f78cccc49fd167d951119d91ee473915803c92dfbbae245167b95050ad321ba2ccfbed71fc3c224effe30252c2badeff8c6fbb07f624c801e
6
+ metadata.gz: c3c7ddc41ed53e2978b9860814ed802b9bae305f81fe442dc3b123b8f34786f4bd16a1f9fa90ff6069cae4570aba8033f135a4187e39806745b16f33fef976b4
7
+ data.tar.gz: dafe52d28098ac72a45557547818bcea55c609d1db0856d6c67ea7fd330a837ed80ded9145cc6d0d3cc3f45818f268db5c4faca7cb38b9220a63ccc3a84457b9
@@ -66,7 +66,7 @@ module Ask
66
66
  # Accumulator for tool calls during streaming (keyed by index)
67
67
  calls_acc = {}
68
68
 
69
- result = provider.chat(
69
+ result = provider.chat(@extra_params || {},
70
70
  @messages.map(&:to_h),
71
71
  model: @model_id,
72
72
  tools: tool_defs,
@@ -134,6 +134,15 @@ module Ask
134
134
  #
135
135
  # @param schema [Ask::Schema, Hash] structured output schema
136
136
  # @return [self]
137
+ # Set additional parameters for the provider call and return self.
138
+ #
139
+ # @param params [Hash] extra parameters passed to the provider
140
+ # @return [self]
141
+ def with_params(**params)
142
+ @extra_params = (@extra_params || {}).merge(params)
143
+ self
144
+ end
145
+
137
146
  def with_schema(schema)
138
147
  @schema = schema.respond_to?(:to_json_schema) ? schema.to_json_schema : schema
139
148
  self
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ask
4
4
  module Agent
5
- VERSION = "0.1.3"
5
+ VERSION = "0.1.4"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto
@@ -147,7 +147,6 @@ files:
147
147
  - lib/ask/agent/persistence/in_memory.rb
148
148
  - lib/ask/agent/reflector.rb
149
149
  - lib/ask/agent/session.rb
150
- - lib/ask/agent/session_backup.rb
151
150
  - lib/ask/agent/telemetry.rb
152
151
  - lib/ask/agent/tool_abort_controller.rb
153
152
  - lib/ask/agent/tool_executor.rb
@@ -1,237 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "securerandom"
4
- require "time"
5
-
6
- module Ask
7
- module Agent
8
- class Session
9
- attr_reader :id, :chat, :tools, :turn_count, :created_at, :messages
10
- attr_reader :tool_calls_made
11
-
12
- def reflection_count
13
- @reflector&.reflection_count || 0
14
- end
15
-
16
-
17
- # @return [Ask::Skills::Registry, nil] auto-discovered skills registry
18
- attr_reader :skills_registry
19
- attr_reader :meta_agent_results
20
- # @return [Ask::Skills::Registry, nil] auto-discovered skills registry
21
- attr_reader :skills_registry
22
-
23
- def initialize(model:, tools: [], max_turns: 25, max_tool_retries: 3,
24
- compactor: nil, hooks: {}, persistence: nil,
25
- id: nil, system_prompt: nil, parallel_tools: true,
26
- reflector: nil, telemetry: true, meta_agent: nil, **chat_options)
27
- @id = id || SecureRandom.uuid
28
- @max_turns = max_turns
29
- @max_tool_retries = max_tool_retries
30
- @parallel_tools = parallel_tools
31
- @event_handlers = { all: [] }
32
- @running = false
33
- @deleted = false
34
- @abort_requested = false
35
- @turn_count = 0
36
- @created_at = Time.now
37
- @_no_tools_instructed = false
38
-
39
- @telemetry = telemetry.is_a?(Telemetry) ? telemetry : Telemetry.new(enabled: !!telemetry)
40
-
41
- @chat = build_chat(model, system_prompt, tools, **chat_options)
42
- @tools = resolve_tools(tools)
43
- @loop = Loop.new(max_turns: max_turns)
44
- @tool_executor = ToolExecutor.new(max_retries: max_tool_retries, parallel: parallel_tools)
45
-
46
- # Auto-discover skills and inject into system prompt
47
- @skills_registry = Ask::Skills.discover rescue nil
48
- if @skills_registry && !@skills_registry.names.empty?
49
- skill_text = @skills_registry.format_for_prompt
50
- if !skill_text.empty? && @chat.messages.any? { |m| m.role == :system }
51
- current = @chat.messages.find { |m| m.role == :system }.content.to_s
52
- @chat.with_instructions(current + skill_text)
53
- end
54
- end
55
- @compactor = compactor ? build_compactor(compactor) : nil
56
- @hooks = Hooks.new(hooks)
57
-
58
- # Auto-discover skills and inject into system prompt
59
- @skills_registry = Ask::Skills.discover rescue nil
60
- if @skills_registry && !@skills_registry.names.empty?
61
- skill_text = @skills_registry.format_for_prompt
62
- if !skill_text.empty? && @chat.messages.any? { |m| m.role == :system }
63
- current = @chat.messages.find { |m| m.role == :system }.content.to_s
64
- @chat.with_instructions(current + skill_text)
65
- end
66
- end
67
- @persistence = persistence
68
-
69
- reflector_opts = reflector.is_a?(Hash) ? reflector : {}
70
- @reflector = if reflector
71
- Reflector.new(
72
- model: @chat,
73
- max_reflections: reflector_opts[:max_reflections] || 1
74
- )
75
- end
76
-
77
- @meta_agent_config = meta_agent
78
- @meta_agent_results = nil
79
-
80
-
81
- # Auto-discover skills and inject into system prompt
82
- @skills_registry = Ask::Skills.discover rescue nil
83
- if @skills_registry && !@skills_registry.names.empty?
84
- skill_text = @skills_registry.format_for_prompt
85
- if !skill_text.empty? && @chat.messages.any? { |m| m.role == :system }
86
- current = @chat.messages.find { |m| m.role == :system }.content.to_s
87
- @chat.with_instructions(current + skill_text)
88
- end
89
- end
90
- @compactor&.chat = @chat
91
- end
92
-
93
- def run(message, tools: nil)
94
- raise "Session deleted" if @deleted
95
- raise "Session already running" if @running
96
-
97
- @running = true
98
- @abort_requested = false
99
- @turn_count = 0
100
- @loop.reset!
101
-
102
- emit(Events::SessionStart.new)
103
-
104
- active_tools = resolve_tools(tools || [])
105
- active_tools = @tools if active_tools.empty?
106
-
107
- if active_tools.empty? && !@_no_tools_instructed
108
- @chat.add_message(role: :system, content: "You have no tools available. Do not claim you can look up information or use tools of any kind. Just respond based on your existing knowledge.")
109
- @_no_tools_instructed = true
110
- end
111
-
112
- begin
113
- @tool_executor.telemetry = @telemetry
114
-
115
- response = @loop.run_turn(
116
- chat: @chat,
117
- message: message,
118
- tools: active_tools,
119
- tool_executor: @tool_executor,
120
- compactor: @compactor,
121
- hooks: @hooks,
122
- event_emitter: self,
123
- session_id: @id
124
- )
125
- rescue MaxTurnsExceeded => e
126
- emit(Events::MaxTurnsExceeded.new(max_turns: @max_turns))
127
- @telemetry.log(:max_turns_exceeded, session_id: @id, max_turns: @max_turns)
128
- response = last_content
129
- rescue LoopDetected => e
130
- emit(Events::LoopDetected.new(tool_name: e.message, repeated_count: 3))
131
- @telemetry.log(:loop_detected, session_id: @id, tool_name: e.message, repeated_count: 3)
132
- response = last_content
133
- rescue Ask::ContextLengthExceeded
134
- if @compactor && !@compactor.overflow_recovered?
135
- @compactor.recover_from_overflow
136
- retry
137
- end
138
- response = "I'm sorry, the conversation has grown too long. Please start a new session."
139
- rescue StandardError => e
140
- emit(Events::Error.new(error: e.message, recoverable: true))
141
- raise
142
- ensure
143
- @running = false
144
- persist! if @persistence
145
- end
146
-
147
- @tool_calls_made = @tool_executor.total_executions
148
-
149
- if @reflector && @reflector.reflect?(@tool_calls_made) && !@abort_requested
150
- eval_result = @reflector.evaluate(response: response, event_emitter: self)
151
- @telemetry.log(:reflection_end, session_id: @id, decision: eval_result[:decision], feedback: eval_result[:feedback])
152
-
153
- if eval_result[:decision] == :improve && !@abort_requested
154
- @chat.add_message(
155
- role: :system,
156
- content: "Improve your last response: #{eval_result[:feedback]}"
157
- )
158
-
159
- response = @loop.run_turn(
160
- chat: @chat,
161
- message: "",
162
- tools: active_tools,
163
- tool_executor: @tool_executor,
164
- compactor: @compactor,
165
- hooks: @hooks,
166
- event_emitter: self,
167
- session_id: @id
168
- )
169
- end
170
- end
171
-
172
- if @meta_agent_config
173
- @telemetry.increment_session_count!
174
- try_auto_meta_agent
175
- end
176
-
177
- emit(Events::SessionEnd.new(result: response, turn_count: @turn_count, tool_calls_made: @tool_calls_made))
178
- @messages = @chat.messages.dup
179
-
180
- response
181
- end
182
-
183
- def on_event(&block)
184
- @event_handlers[:all] << block
185
- self
186
- end
187
-
188
- def on(type, &block)
189
- @event_handlers[type] ||= []
190
- @event_handlers[type] << block
191
- self
192
- end
193
-
194
- def emit(event)
195
- @event_handlers[:all].each { |h| h.call(event) }
196
- handlers = @event_handlers[event.class]
197
- handlers&.each { |h| h.call(event) }
198
- end
199
-
200
- def running? = @running
201
- def deleted? = @deleted
202
-
203
- def save
204
- persist! if @persistence
205
- end
206
-
207
- def self.load(id, adapter:)
208
- data = adapter.load(id)
209
- return nil unless data
210
-
211
- session = new(
212
- id: data[:id],
213
- model: data.dig(:metadata, :model),
214
- tools: data.dig(:metadata, :tools)&.map(&:constantize) || [],
215
- persistence: adapter
216
- )
217
-
218
- data[:messages].each do |msg|
219
- session.chat.add_message(
220
- role: msg[:role].to_sym,
221
- content: msg[:content],
222
- tool_call_id: msg[:tool_call_id]
223
- )
224
- end
225
-
226
- session
227
- end
228
-
229
- def delete
230
- @deleted = true
231
- @persistence&.delete(@id)
232
- end
233
-
234
- def abort
235
- @abort_requested = true
236
- end
237
-