ask-agent 0.40.20 → 0.40.21
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 +64 -0
- data/README.md +29 -0
- data/lib/ask/agent/session.rb +4 -1
- data/lib/ask/agent/session_adapter.rb +250 -0
- data/lib/ask/agent/version.rb +1 -1
- data/lib/ask/agent.rb +1 -0
- metadata +16 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8119f78526cac8f96b7f6506c1d40e046127dccad46015252e9ea0805e15c677
|
|
4
|
+
data.tar.gz: be381f8d8fbb4b104ba79ab0a1cece93918c8ef028bfdb4fc24dd6ae49399726
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aee841408cd187f95b2d54f6bbb0820fac09865bf58f1af38680b1847088a8aca7c1a187008e93a98a6cf39941fd65e0690dd78a16b6d07491c6d0ec0573bcf2
|
|
7
|
+
data.tar.gz: c6b6c736800ae14baa95355f692294da8f428af180c404852a5aa9141905d5bfb776994f59aab21e772f3263e40c3c542b32009cee779f1263ade62c8d095cb5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,67 @@
|
|
|
1
|
+
## [Unreleased]
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## [0.40.21] — 2026-09-22
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- **`Ask::Agent::SessionAdapter` — bridges an agent session to
|
|
9
|
+
`Ask::Session::Host`.** Records user input and per-run snapshots as
|
|
10
|
+
event-sourced ask-session events, maps agent events (turn, streaming,
|
|
11
|
+
tool, todo, plan, error) onto session event types with `trace_id` /
|
|
12
|
+
`causation_id` propagation, and resumes from the latest snapshot
|
|
13
|
+
(`SessionAdapter.resume`). Resume survives process restarts when the host
|
|
14
|
+
store is durable (e.g. `Ask::Session::ProviderStore` over
|
|
15
|
+
`ask-state-providers`). Requires the new runtime dependency
|
|
16
|
+
`ask-session >= 0.1.0` (the single session store; no second store added).
|
|
17
|
+
Resume validates the snapshot before restoring, so a malformed snapshot
|
|
18
|
+
raises `SessionAdapter::Error` instead of leaving the agent half-restored.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **`Session#turn_count` is now maintained during runs.** The counter was
|
|
23
|
+
only ever reset at run start (or restored from a checkpoint), never
|
|
24
|
+
incremented — so `SessionEnd`, audit-log entries, persisted
|
|
25
|
+
`metadata.turn_count`, and `SessionAdapter` snapshots all recorded `0` for
|
|
26
|
+
live runs. Turns are now counted on `TurnStart`, matching the loop's own
|
|
27
|
+
count (`reset: true` scopes it to the run; `reset: false` accumulates).
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## [0.40.20] — 2026-09-21
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- **Agent tool execution unified with ask-runtime.** `ToolExecutor` runs
|
|
35
|
+
tool calls through the runtime's execution contract, exposing the current
|
|
36
|
+
runtime call and execution context (`Ask.current_runtime_call` /
|
|
37
|
+
`Ask.current_runtime_context`) while a tool executes, and conforming to
|
|
38
|
+
the runtime executor contract.
|
|
39
|
+
- Requires `ask-runtime >= 0.1.0`.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
## [0.40.19] — 2026-09-20
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- **Bundled `agent.build_agents` skill** — teaches building agents with
|
|
47
|
+
ask-rb (definitions, sessions, tools, configuration, common patterns).
|
|
48
|
+
Auto-discovered via `Gem.find_files` when ask-skills is present.
|
|
49
|
+
- **`askr skills install` / `askr skills uninstall`** with
|
|
50
|
+
`--global|--local|--dir`, plus auto-sync of managed skill copies on
|
|
51
|
+
every CLI invocation.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## [0.40.18] — 2026-09-19
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
|
|
58
|
+
- **`Agent.new` and `Session.new` unified.** The shared implementation
|
|
59
|
+
lives in `Session.build_from_definition`; `Agent.new` delegates to it,
|
|
60
|
+
`Session.new` supports definition lookup, and `Ask.chat` accepts `name:`
|
|
61
|
+
for definition lookup. The duplicate `build_session_from_definition` and
|
|
62
|
+
`resolve_definition_tools` helpers were removed from the `Agent` module.
|
|
63
|
+
|
|
64
|
+
|
|
1
65
|
## [0.40.17] — 2026-09-18
|
|
2
66
|
|
|
3
67
|
### Added
|
data/README.md
CHANGED
|
@@ -102,6 +102,35 @@ under multiple OpenAI-compatible providers). A `provider:` passed to
|
|
|
102
102
|
`Session.new` or declared in an agent `Definition` always wins over the global
|
|
103
103
|
default.
|
|
104
104
|
|
|
105
|
+
## Durable sessions (ask-session)
|
|
106
|
+
|
|
107
|
+
`Ask::Agent::SessionAdapter` bridges a session to an event-sourced
|
|
108
|
+
`Ask::Session::Host`. Every run records the user input, the mapped agent
|
|
109
|
+
events, and an `agent.snapshot`; `SessionAdapter.resume` restores the latest
|
|
110
|
+
snapshot — including after a process restart, as long as the host store is
|
|
111
|
+
durable (for example `Ask::Session::ProviderStore` over
|
|
112
|
+
`ask-state-providers`' SQLite adapter).
|
|
113
|
+
|
|
114
|
+
```ruby
|
|
115
|
+
require "ask-agent"
|
|
116
|
+
require "ask/session"
|
|
117
|
+
|
|
118
|
+
host = Ask::Session::Host.new(store: Ask::Session::Store.new)
|
|
119
|
+
|
|
120
|
+
session = Ask::Agent::Session.new(model: "gpt-4o", id: "chat-1")
|
|
121
|
+
adapter = Ask::Agent::SessionAdapter.create(agent: session, host: host)
|
|
122
|
+
adapter.run("Hello")
|
|
123
|
+
|
|
124
|
+
# Later (even in a new process, with the same durable store):
|
|
125
|
+
resumed = Ask::Agent::Session.new(model: "gpt-4o", id: "chat-1")
|
|
126
|
+
adapter = Ask::Agent::SessionAdapter.resume(agent: resumed, host: host, session_id: "chat-1")
|
|
127
|
+
adapter.run("Continue where we left off")
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`SessionAdapter::Error` is raised when the session record or its latest
|
|
131
|
+
snapshot cannot be found. This requires the `ask-session` gem (a runtime
|
|
132
|
+
dependency of ask-agent).
|
|
133
|
+
|
|
105
134
|
## Full documentation
|
|
106
135
|
|
|
107
136
|
The full ask-rb documentation lives at https://ask-rb.github.io/ask-docs.
|
data/lib/ask/agent/session.rb
CHANGED
|
@@ -107,7 +107,10 @@ module Ask
|
|
|
107
107
|
@turn_id = 0
|
|
108
108
|
@queued_steers = []
|
|
109
109
|
@steer_mutex = Mutex.new
|
|
110
|
-
on(Events::TurnStart)
|
|
110
|
+
on(Events::TurnStart) do
|
|
111
|
+
@turn_id += 1
|
|
112
|
+
@turn_count += 1
|
|
113
|
+
end
|
|
111
114
|
@created_at = Time.now
|
|
112
115
|
@_no_tools_instructed = false
|
|
113
116
|
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "securerandom"
|
|
4
|
+
require "ask/session"
|
|
5
|
+
|
|
6
|
+
module Ask
|
|
7
|
+
module Agent
|
|
8
|
+
# Adapter that bridges an Ask::Agent::Session to an Ask::Session::Host.
|
|
9
|
+
#
|
|
10
|
+
# Maps agent events to event-sourced ask-session events, persists a
|
|
11
|
+
# snapshot at the end of each run, and supports resume from the latest
|
|
12
|
+
# durable snapshot.
|
|
13
|
+
#
|
|
14
|
+
# adapter = SessionAdapter.create(agent: session, host: host)
|
|
15
|
+
# result = adapter.run("Hello")
|
|
16
|
+
#
|
|
17
|
+
# restored = SessionAdapter.resume(agent: session, host: host, session_id: id)
|
|
18
|
+
# restored.run("Follow up")
|
|
19
|
+
#
|
|
20
|
+
class SessionAdapter
|
|
21
|
+
SNAPSHOT_TYPE = "agent.snapshot"
|
|
22
|
+
|
|
23
|
+
# Raised when resume cannot find the ask-session record or its
|
|
24
|
+
# latest snapshot.
|
|
25
|
+
class Error < Ask::Agent::Error; end
|
|
26
|
+
|
|
27
|
+
attr_reader :agent, :host, :session_id
|
|
28
|
+
|
|
29
|
+
def initialize(agent:, host:, session_id: agent.id, metadata: {}, create: false)
|
|
30
|
+
@agent = agent
|
|
31
|
+
@host = host
|
|
32
|
+
@session_id = session_id
|
|
33
|
+
@current_trace_id = nil
|
|
34
|
+
@current_turn_id = nil
|
|
35
|
+
@current_causation_id = nil
|
|
36
|
+
|
|
37
|
+
@host.create(id: @session_id, metadata: metadata) if create
|
|
38
|
+
|
|
39
|
+
attach_event_handler
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Create a new ask-session record and return the adapter.
|
|
43
|
+
#
|
|
44
|
+
# @param agent [Ask::Agent::Session] the agent session
|
|
45
|
+
# @param host [Ask::Session::Host] the session host
|
|
46
|
+
# @param metadata [Hash] session metadata
|
|
47
|
+
# @return [SessionAdapter]
|
|
48
|
+
def self.create(agent:, host:, metadata: {})
|
|
49
|
+
record = host.create(id: agent.id, metadata: metadata)
|
|
50
|
+
new(agent: agent, host: host, session_id: record.id, metadata: metadata, create: false)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Attach to an existing ask-session and restore the latest snapshot.
|
|
54
|
+
#
|
|
55
|
+
# Contract: Ask::Session::Host#session raises
|
|
56
|
+
# Ask::Session::NotFoundError for a missing record (it never returns
|
|
57
|
+
# nil); both missing-session and missing-snapshot failures surface as
|
|
58
|
+
# SessionAdapter::Error.
|
|
59
|
+
#
|
|
60
|
+
# @param agent [Ask::Agent::Session] the agent session (will be populated from snapshot)
|
|
61
|
+
# @param host [Ask::Session::Host] the session host
|
|
62
|
+
# @param session_id [String] the ask-session record id
|
|
63
|
+
# @return [SessionAdapter]
|
|
64
|
+
# @raise [SessionAdapter::Error] if the session or snapshot is not found
|
|
65
|
+
def self.resume(agent:, host:, session_id:)
|
|
66
|
+
begin
|
|
67
|
+
host.session(session_id)
|
|
68
|
+
rescue Ask::Session::NotFoundError
|
|
69
|
+
raise Error, "Session not found: #{session_id.inspect}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
events = host.events(session_id)
|
|
73
|
+
snapshot_event = events.reverse_each.find { |e| e.type == SNAPSHOT_TYPE }
|
|
74
|
+
raise Error, "No snapshot found for session #{session_id.inspect}" unless snapshot_event
|
|
75
|
+
|
|
76
|
+
payload = snapshot_event.payload
|
|
77
|
+
messages = payload[:messages] || payload["messages"] || []
|
|
78
|
+
|
|
79
|
+
# Validate before mutating the agent so a malformed snapshot cannot
|
|
80
|
+
# leave it half-restored.
|
|
81
|
+
messages.each do |msg|
|
|
82
|
+
role = msg.is_a?(Hash) ? (msg[:role] || msg["role"]) : nil
|
|
83
|
+
raise Error, "Snapshot for session #{session_id.inspect} contains a message without a role" unless role
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
agent.instance_variable_set(:@turn_count, payload[:turn_count] || payload["turn_count"] || 0)
|
|
87
|
+
agent.chat.reset_messages!
|
|
88
|
+
messages.each do |msg|
|
|
89
|
+
agent.chat.add_message(
|
|
90
|
+
role: (msg[:role] || msg["role"]).to_sym,
|
|
91
|
+
content: deserialize_content(msg[:content] || msg["content"]),
|
|
92
|
+
tool_call_id: msg[:tool_call_id] || msg["tool_call_id"],
|
|
93
|
+
tool_calls: msg[:tool_calls] || msg["tool_calls"]
|
|
94
|
+
)
|
|
95
|
+
end
|
|
96
|
+
agent.instance_variable_set(:@messages, agent.chat.messages.dup)
|
|
97
|
+
|
|
98
|
+
new(agent: agent, host: host, session_id: session_id, create: false)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Current trace id for the running trace.
|
|
102
|
+
# @return [String, nil]
|
|
103
|
+
def current_trace_id
|
|
104
|
+
@current_trace_id
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Current turn identifier (stable per TurnStart).
|
|
108
|
+
# @return [Integer, nil]
|
|
109
|
+
def current_turn_id
|
|
110
|
+
@current_turn_id
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Run the agent and record events in the ask-session.
|
|
114
|
+
#
|
|
115
|
+
# @param message [String] the user message
|
|
116
|
+
# @param trace_id [String, nil] optional trace id (auto-generated if nil)
|
|
117
|
+
# @param causation_id [String, nil] optional causation id linking to the
|
|
118
|
+
# event that caused this run
|
|
119
|
+
# @param options [Hash] forwarded to agent.run
|
|
120
|
+
# @return [String] the agent response
|
|
121
|
+
def run(message, trace_id: nil, causation_id: nil, **options)
|
|
122
|
+
@current_trace_id = trace_id || "trace_#{SecureRandom.hex(8)}"
|
|
123
|
+
@current_causation_id = causation_id
|
|
124
|
+
|
|
125
|
+
# Record user input as a message event.
|
|
126
|
+
input_event = @host.send_message(
|
|
127
|
+
@session_id,
|
|
128
|
+
content: message.to_s,
|
|
129
|
+
trace_id: @current_trace_id,
|
|
130
|
+
causation_id: @current_causation_id
|
|
131
|
+
)
|
|
132
|
+
@current_causation_id ||= input_event.trace_id
|
|
133
|
+
|
|
134
|
+
begin
|
|
135
|
+
result = @agent.run(message, **options)
|
|
136
|
+
|
|
137
|
+
# Append snapshot for resume.
|
|
138
|
+
snapshot = build_snapshot
|
|
139
|
+
@host.append(
|
|
140
|
+
@session_id,
|
|
141
|
+
type: SNAPSHOT_TYPE,
|
|
142
|
+
payload: snapshot,
|
|
143
|
+
trace_id: @current_trace_id,
|
|
144
|
+
causation_id: @current_causation_id
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
result
|
|
148
|
+
rescue Ask::Agent::Aborted
|
|
149
|
+
@host.append(
|
|
150
|
+
@session_id,
|
|
151
|
+
type: "turn.aborted",
|
|
152
|
+
payload: { turn_id: @current_turn_id },
|
|
153
|
+
trace_id: @current_trace_id,
|
|
154
|
+
causation_id: @current_causation_id
|
|
155
|
+
)
|
|
156
|
+
raise
|
|
157
|
+
rescue => e
|
|
158
|
+
@host.append(
|
|
159
|
+
@session_id,
|
|
160
|
+
type: "turn.failed",
|
|
161
|
+
payload: { error: e.message, error_class: e.class.name },
|
|
162
|
+
trace_id: @current_trace_id,
|
|
163
|
+
causation_id: @current_causation_id
|
|
164
|
+
)
|
|
165
|
+
raise
|
|
166
|
+
ensure
|
|
167
|
+
@current_turn_id = nil
|
|
168
|
+
@current_causation_id = nil
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Request agent abort without writing a terminal session event.
|
|
173
|
+
def abort
|
|
174
|
+
@agent.abort
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Close the ask-session (terminal: :closed).
|
|
178
|
+
def close
|
|
179
|
+
@host.close(@session_id)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Abort the ask-session (terminal: :aborted).
|
|
183
|
+
def abort_session
|
|
184
|
+
@host.abort(@session_id)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
private
|
|
188
|
+
|
|
189
|
+
def attach_event_handler
|
|
190
|
+
@agent.on_event do |event|
|
|
191
|
+
handle_event(event)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def handle_event(event)
|
|
196
|
+
trace_id = @current_trace_id
|
|
197
|
+
causation_id = @current_causation_id
|
|
198
|
+
turn_id = @current_turn_id
|
|
199
|
+
|
|
200
|
+
case event
|
|
201
|
+
when Events::TurnStart
|
|
202
|
+
@current_turn_id = (@current_turn_id || 0) + 1
|
|
203
|
+
turn_id = @current_turn_id
|
|
204
|
+
@host.append(@session_id, type: "turn.started", payload: { turn_id: turn_id }, trace_id: trace_id, causation_id: causation_id)
|
|
205
|
+
|
|
206
|
+
when Events::TextDelta
|
|
207
|
+
@host.append(@session_id, type: "model.streaming", payload: { content: event.content, turn_id: turn_id }, trace_id: trace_id, causation_id: causation_id)
|
|
208
|
+
|
|
209
|
+
when Events::ThinkingDelta
|
|
210
|
+
@host.append(@session_id, type: "model.thinking", payload: { content: event.content, turn_id: turn_id }, trace_id: trace_id, causation_id: causation_id)
|
|
211
|
+
|
|
212
|
+
when Events::ToolExecutionStart
|
|
213
|
+
@host.append(@session_id, type: "tool.use", payload: { tool_name: event.name, arguments: event.arguments, tool_call_id: event.id, turn_id: turn_id }, trace_id: trace_id, causation_id: causation_id)
|
|
214
|
+
|
|
215
|
+
when Events::ToolExecutionUpdate
|
|
216
|
+
@host.append(@session_id, type: "tool.delta", payload: { tool_name: event.name, tool_call_id: event.id, partial_result: event.partial_result, turn_id: turn_id }, trace_id: trace_id, causation_id: causation_id)
|
|
217
|
+
|
|
218
|
+
when Events::ToolExecutionEnd
|
|
219
|
+
@host.append(@session_id, type: "tool.result", payload: { tool_name: event.name, tool_call_id: event.id, result: event.result, is_error: event.is_error, duration_ms: event.duration_ms, turn_id: turn_id }, trace_id: trace_id, causation_id: causation_id)
|
|
220
|
+
|
|
221
|
+
when Events::TodoUpdated
|
|
222
|
+
@host.append(@session_id, type: "todos.updated", payload: { todos: event.todos }, trace_id: trace_id, causation_id: causation_id)
|
|
223
|
+
|
|
224
|
+
when Events::PlanProposed
|
|
225
|
+
@host.append(@session_id, type: "plan.proposed", payload: { plan: event.plan }, trace_id: trace_id, causation_id: causation_id)
|
|
226
|
+
|
|
227
|
+
when Events::PlanApproved
|
|
228
|
+
@host.append(@session_id, type: "plan.approved", payload: { plan: event.plan }, trace_id: trace_id, causation_id: causation_id)
|
|
229
|
+
|
|
230
|
+
when Events::PlanRejected
|
|
231
|
+
@host.append(@session_id, type: "plan.rejected", payload: { plan: event.plan }, trace_id: trace_id, causation_id: causation_id)
|
|
232
|
+
|
|
233
|
+
when Events::Error
|
|
234
|
+
@host.append(@session_id, type: "error", payload: { message: event.error, recoverable: event.recoverable }, trace_id: trace_id, causation_id: causation_id)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def build_snapshot
|
|
239
|
+
{
|
|
240
|
+
messages: (@agent.messages || []).map(&:to_h),
|
|
241
|
+
turn_count: @agent.turn_count || 0
|
|
242
|
+
}
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def self.deserialize_content(content)
|
|
246
|
+
content.is_a?(Array) ? content.map { |block| Ask::Content.from_h(block) } : content
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
data/lib/ask/agent/version.rb
CHANGED
data/lib/ask/agent.rb
CHANGED
|
@@ -216,6 +216,7 @@ require_relative "agent/chat"
|
|
|
216
216
|
require_relative "agent/telemetry"
|
|
217
217
|
require_relative "agent/tool_abort_controller"
|
|
218
218
|
require_relative "agent/session"
|
|
219
|
+
require_relative "agent/session_adapter"
|
|
219
220
|
require_relative "agent/loop"
|
|
220
221
|
require_relative "agent/reflector"
|
|
221
222
|
require_relative "agent/evaluator"
|
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.40.
|
|
4
|
+
version: 0.40.21
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kaka Ruto
|
|
@@ -121,6 +121,20 @@ dependencies:
|
|
|
121
121
|
- - "~>"
|
|
122
122
|
- !ruby/object:Gem::Version
|
|
123
123
|
version: '3.9'
|
|
124
|
+
- !ruby/object:Gem::Dependency
|
|
125
|
+
name: ask-session
|
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - ">="
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: 0.1.0
|
|
131
|
+
type: :runtime
|
|
132
|
+
prerelease: false
|
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - ">="
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: 0.1.0
|
|
124
138
|
- !ruby/object:Gem::Dependency
|
|
125
139
|
name: minitest
|
|
126
140
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -216,6 +230,7 @@ files:
|
|
|
216
230
|
- lib/ask/agent/reflector.rb
|
|
217
231
|
- lib/ask/agent/scheduler.rb
|
|
218
232
|
- lib/ask/agent/session.rb
|
|
233
|
+
- lib/ask/agent/session_adapter.rb
|
|
219
234
|
- lib/ask/agent/stream_transforms/base.rb
|
|
220
235
|
- lib/ask/agent/stream_transforms/extract_json.rb
|
|
221
236
|
- lib/ask/agent/stream_transforms/pipeline.rb
|