ask-agent 0.25.2 → 0.25.3
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/CHANGELOG.md +20 -0
- data/lib/ask/agent/context_source.rb +1 -0
- data/lib/ask/agent/context_sources.rb +1 -0
- data/lib/ask/agent/extensions/audit_log/active_record_writer.rb +1 -0
- data/lib/ask/agent/extensions/audit_log.rb +1 -0
- data/lib/ask/agent/loop.rb +11 -6
- data/lib/ask/agent/meta_agent.rb +1 -0
- data/lib/ask/agent/telemetry.rb +1 -0
- data/lib/ask/agent/tool_executor.rb +14 -4
- data/lib/ask/agent/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ec5991dad0128d2383500176d9872d4fda5ac504f81826eeac343a1b8435616b
|
|
4
|
+
data.tar.gz: f62dd7104119cd637c2ca590bc8c3e7c7c6c32e8f85d2d0e7e2cc2cbd2e8b019
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0ea8e0cf1e8750265f971b7379db7fddbc8c425d7f765835bc1d2b23e0fdf79001b2ceb93cc70e5647999e4327f6aa0ae3e56ed6708cdd8c66ea8e0006ddb039
|
|
7
|
+
data.tar.gz: bd758b33c296cd20fd90429d269fb079b5a1501b074c854d1dcfe27c007c2234b509693e7a136abf801738c775ed7c64894e2e2bc7c7414499f14ec2bbd6b416
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## [0.25.3] - 2026-08-04
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
|
|
5
|
+
- **Tools now respect the session's `parallel_tools` setting.** The agent
|
|
6
|
+
loop dispatched tool calls straight to `execute_parallel`, so tools always
|
|
7
|
+
ran in worker threads — even with `parallel_tools: false`. Sequential
|
|
8
|
+
sessions now run tools in the caller thread, which is what frameworks
|
|
9
|
+
like Rails rely on for per-request context (`CurrentAttributes` are
|
|
10
|
+
thread-local). The loop calls `ToolExecutor#execute`, which honors the
|
|
11
|
+
executor's `parallel` flag.
|
|
12
|
+
- **Parallel tool threads inherit the caller's thread-local state.** When
|
|
13
|
+
tools do run in threads (parallel mode), `execute_parallel` copies the
|
|
14
|
+
caller's `Thread.current` locals into each worker thread first, so
|
|
15
|
+
per-request context (Rails `CurrentAttributes`, log tags, etc.) reaches
|
|
16
|
+
the tools instead of being nil.
|
|
17
|
+
- `ToolExecutor#execute` accepts a `result_callback:` kwarg (invoked per
|
|
18
|
+
completed tool in both sequential and parallel modes); sequential
|
|
19
|
+
execution reports results through it too, matching parallel behavior.
|
|
20
|
+
|
|
1
21
|
## [0.25.2] - 2026-08-03
|
|
2
22
|
|
|
3
23
|
### Fixed
|
data/lib/ask/agent/loop.rb
CHANGED
|
@@ -79,12 +79,17 @@ module Ask
|
|
|
79
79
|
|
|
80
80
|
if user_tool_calls.any?
|
|
81
81
|
# Execute user tool calls locally
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
# Respect the session's parallel_tools setting: parallel tools run
|
|
83
|
+
# in threads (with the caller's thread-local context inherited);
|
|
84
|
+
# sequential tools run in the caller thread so per-request context
|
|
85
|
+
# (e.g. Rails CurrentAttributes) is visible without any copying.
|
|
86
|
+
user_results = tool_executor.execute(
|
|
87
|
+
user_tool_calls, tools, hooks: hooks, event_emitter: event_emitter,
|
|
88
|
+
result_callback: lambda do |tool_call_id, result|
|
|
89
|
+
tc = user_tool_calls[tool_call_id]
|
|
90
|
+
chat.add_message(role: :tool, content: result[:message].to_s, tool_call_id: tool_call_id) if tc
|
|
91
|
+
end
|
|
92
|
+
)
|
|
88
93
|
all_tool_results.concat(user_results)
|
|
89
94
|
end
|
|
90
95
|
|
data/lib/ask/agent/meta_agent.rb
CHANGED
data/lib/ask/agent/telemetry.rb
CHANGED
|
@@ -19,7 +19,7 @@ module Ask
|
|
|
19
19
|
|
|
20
20
|
attr_writer :telemetry
|
|
21
21
|
|
|
22
|
-
def execute(tool_calls, tools, hooks:, event_emitter:, session_id: nil)
|
|
22
|
+
def execute(tool_calls, tools, hooks:, event_emitter:, session_id: nil, result_callback: nil)
|
|
23
23
|
return [] if tool_calls.empty?
|
|
24
24
|
|
|
25
25
|
@total_executions = 0
|
|
@@ -27,9 +27,11 @@ module Ask
|
|
|
27
27
|
sibling_abort = ToolAbortController.new
|
|
28
28
|
|
|
29
29
|
if @parallel
|
|
30
|
-
execute_parallel(tool_calls, tools, hooks, event_emitter, sibling_abort)
|
|
30
|
+
execute_parallel(tool_calls, tools, hooks, event_emitter, sibling_abort, &result_callback)
|
|
31
31
|
else
|
|
32
|
-
execute_sequential(tool_calls, tools, hooks, event_emitter, sibling_abort)
|
|
32
|
+
execute_sequential(tool_calls, tools, hooks, event_emitter, sibling_abort) do |id, result|
|
|
33
|
+
result_callback&.call(id, result)
|
|
34
|
+
end
|
|
33
35
|
end
|
|
34
36
|
end
|
|
35
37
|
|
|
@@ -38,8 +40,15 @@ module Ask
|
|
|
38
40
|
mutex = Mutex.new
|
|
39
41
|
results = {}
|
|
40
42
|
|
|
43
|
+
# Inherit the caller's thread-local state (Rails CurrentAttributes
|
|
44
|
+
# and similar frameworks store per-request context in Thread.current)
|
|
45
|
+
# so tools see the same context they would in a sequential run.
|
|
46
|
+
inherited_locals = {}
|
|
47
|
+
Thread.current.keys.each { |key| inherited_locals[key] = Thread.current[key] }
|
|
48
|
+
|
|
41
49
|
tool_calls.each do |id, tool_call|
|
|
42
50
|
threads << Thread.new do
|
|
51
|
+
inherited_locals.each { |key, value| Thread.current[key] = value }
|
|
43
52
|
begin
|
|
44
53
|
if sibling_abort.aborted?
|
|
45
54
|
mutex.synchronize { results[id] = aborted_result(tool_call) }
|
|
@@ -75,13 +84,14 @@ module Ask
|
|
|
75
84
|
tool_calls.keys.map { |id| results[id] }.compact
|
|
76
85
|
end
|
|
77
86
|
|
|
78
|
-
def execute_sequential(tool_calls, tools, hooks, event_emitter, sibling_abort)
|
|
87
|
+
def execute_sequential(tool_calls, tools, hooks, event_emitter, sibling_abort, &result_callback)
|
|
79
88
|
results = []
|
|
80
89
|
tool_calls.each do |id, tool_call|
|
|
81
90
|
break if sibling_abort.aborted?
|
|
82
91
|
|
|
83
92
|
result = execute_single_tool(tool_call, tools, hooks, event_emitter, sibling_abort)
|
|
84
93
|
results << result
|
|
94
|
+
result_callback&.call(id, result)
|
|
85
95
|
break if result[:critical_failure]
|
|
86
96
|
break if result[:halted]
|
|
87
97
|
end
|
data/lib/ask/agent/version.rb
CHANGED