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 +4 -4
- data/lib/ask/agent/chat.rb +10 -1
- data/lib/ask/agent/version.rb +1 -1
- metadata +1 -2
- data/lib/ask/agent/session_backup.rb +0 -237
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f9b59871c0216de559acd011a9553c650ca4f3714150c7e71811b375a92f2a48
|
|
4
|
+
data.tar.gz: edb6f7137010f1c448da22ca99a7cf2c90dda29f70d210db4c2e18d5f4079568
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c3c7ddc41ed53e2978b9860814ed802b9bae305f81fe442dc3b123b8f34786f4bd16a1f9fa90ff6069cae4570aba8033f135a4187e39806745b16f33fef976b4
|
|
7
|
+
data.tar.gz: dafe52d28098ac72a45557547818bcea55c609d1db0856d6c67ea7fd330a837ed80ded9145cc6d0d3cc3f45818f268db5c4faca7cb38b9220a63ccc3a84457b9
|
data/lib/ask/agent/chat.rb
CHANGED
|
@@ -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
|
data/lib/ask/agent/version.rb
CHANGED
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.
|
|
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
|
-
|