Class: Ask::AppServer::AgentAdapter
- Inherits:
-
Object
- Object
- Ask::AppServer::AgentAdapter
- Defined in:
- lib/ask/app_server/agent_adapter.rb
Overview
Wraps an Ask::Agent::Session and translates its events into the app-server protocol event format via EventTranslator.
Each wrapper is associated with one session and maintains an EventTranslator that app-server clients poll or subscribe to.
Instance Attribute Summary collapse
-
#created_at ⇒ Object
readonly
When the session was created.
-
#running ⇒ Object
readonly
Whether a turn is currently in progress.
-
#session ⇒ Object
readonly
The underlying ask-agent session.
-
#session_id ⇒ Object
readonly
The session ID (same as ask-agent session id).
-
#translator ⇒ Object
readonly
The event translator that accumulates protocol events.
Instance Method Summary collapse
-
#abort_turn! ⇒ Object
Request abort of the current turn.
-
#drain_events ⇒ Object
Drain and return pending events.
-
#events_after(after_seq) ⇒ Object
Events after a given sequence number.
-
#idle? ⇒ Boolean
Whether this session is idle (no turn running).
-
#initialize(model:, tools: nil, system_prompt: nil, agent_dir: nil, **session_opts) ⇒ AgentAdapter
constructor
A new instance of AgentAdapter.
-
#inject_message(content) ⇒ Object
Inject a message into a running session (mid-execution).
-
#last_seq ⇒ Object
Last sequence number.
-
#pending_events ⇒ Object
All events since last drain.
-
#resume(session) ⇒ Object
Resume an existing session (re-attach event handler).
-
#send_message(content) ⇒ Object
Send a message and start processing.
-
#start_session ⇒ Object
Start a new ask-agent session.
-
#streaming_text ⇒ Object
The accumulated streaming text from the current/ last turn.
-
#wait_for_turn(timeout: 600) ⇒ Object
Wait for the current turn to complete (with timeout).
Constructor Details
#initialize(model:, tools: nil, system_prompt: nil, agent_dir: nil, **session_opts) ⇒ AgentAdapter
Returns a new instance of AgentAdapter.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/ask/app_server/agent_adapter.rb', line 26 def initialize(model:, tools: nil, system_prompt: nil, agent_dir: nil, **session_opts) @model = model @system_prompt = system_prompt @tools = resolve_tools(tools) @session_opts = session_opts @agent_dir = agent_dir @session = nil @translator = nil @session_id = nil @running = false @running_mutex = Mutex.new @run_thread = nil @abort_requested = false @created_at = Time.now @logger = Logger.new($stdout, level: ENV["DEBUG"] ? Logger::DEBUG : Logger::WARN) end |
Instance Attribute Details
#created_at ⇒ Object (readonly)
When the session was created.
24 25 26 |
# File 'lib/ask/app_server/agent_adapter.rb', line 24 def created_at @created_at end |
#running ⇒ Object (readonly)
Whether a turn is currently in progress.
21 22 23 |
# File 'lib/ask/app_server/agent_adapter.rb', line 21 def running @running end |
#session ⇒ Object (readonly)
The underlying ask-agent session.
12 13 14 |
# File 'lib/ask/app_server/agent_adapter.rb', line 12 def session @session end |
#session_id ⇒ Object (readonly)
The session ID (same as ask-agent session id).
18 19 20 |
# File 'lib/ask/app_server/agent_adapter.rb', line 18 def session_id @session_id end |
#translator ⇒ Object (readonly)
The event translator that accumulates protocol events.
15 16 17 |
# File 'lib/ask/app_server/agent_adapter.rb', line 15 def translator @translator end |
Instance Method Details
#abort_turn! ⇒ Object
Request abort of the current turn.
100 101 102 103 |
# File 'lib/ask/app_server/agent_adapter.rb', line 100 def abort_turn! @abort_requested = true @session&.abort if @session end |
#drain_events ⇒ Object
Drain and return pending events.
147 148 149 |
# File 'lib/ask/app_server/agent_adapter.rb', line 147 def drain_events @translator&.drain_events || [] end |
#events_after(after_seq) ⇒ Object
Events after a given sequence number.
157 158 159 |
# File 'lib/ask/app_server/agent_adapter.rb', line 157 def events_after(after_seq) pending_events.select { |e| e[:seq] > after_seq } end |
#idle? ⇒ Boolean
Whether this session is idle (no turn running).
116 117 118 |
# File 'lib/ask/app_server/agent_adapter.rb', line 116 def idle? !@running end |
#inject_message(content) ⇒ Object
Inject a message into a running session (mid-execution). Aborts the current turn; the message will be processed when the next turn starts. Note: ask-agent doesn't natively support mid-execution injection. We abort and queue the message for the next run.
125 126 127 128 129 130 131 132 133 134 |
# File 'lib/ask/app_server/agent_adapter.rb', line 125 def (content) if @running abort_turn! # The caller should wait for idle, then call send_message again false else (content) true end end |
#last_seq ⇒ Object
Last sequence number.
152 153 154 |
# File 'lib/ask/app_server/agent_adapter.rb', line 152 def last_seq @translator&.last_seq || 0 end |
#pending_events ⇒ Object
All events since last drain.
142 143 144 |
# File 'lib/ask/app_server/agent_adapter.rb', line 142 def pending_events @translator&.pending_events || [] end |
#resume(session) ⇒ Object
Resume an existing session (re-attach event handler).
66 67 68 69 70 71 72 |
# File 'lib/ask/app_server/agent_adapter.rb', line 66 def resume(session) @session = session @session_id = session.id @translator = EventTranslator.new(@session_id) @session.on_event { |event| handle_agent_event(event) } @session_id end |
#send_message(content) ⇒ Object
Send a message and start processing. Runs in a background thread. The caller should poll or subscribe to receive events.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/ask/app_server/agent_adapter.rb', line 76 def (content) raise "Session not started" unless @session raise "Session already busy" if @running @running_mutex.synchronize do @abort_requested = false @running = true end @run_thread = Thread.new do begin @session.run(content) rescue => e # Agent may have been aborted — that's fine @logger.debug("Agent run error: #{e.}") if ENV["DEBUG"] ensure @running_mutex.synchronize { @running = false } end end true end |
#start_session ⇒ Object
Start a new ask-agent session. Returns the session ID.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/ask/app_server/agent_adapter.rb', line 45 def start_session opts = @session_opts.dup # Extract hooks from session opts and pass them to Session hooks = opts.delete(:hooks) || {} @session = Ask::Agent::Session.new( model: @model, tools: @tools, system_prompt: @system_prompt, agent_dir: @agent_dir, hooks: hooks, **opts ) @session_id = @session.id @translator = EventTranslator.new(@session_id) @session.on_event { |event| handle_agent_event(event) } @session_id end |
#streaming_text ⇒ Object
The accumulated streaming text from the current/ last turn.
137 138 139 |
# File 'lib/ask/app_server/agent_adapter.rb', line 137 def streaming_text @translator&.instance_variable_get(:@streaming_text).to_s end |
#wait_for_turn(timeout: 600) ⇒ Object
Wait for the current turn to complete (with timeout). Returns true if completed, false if timed out.
107 108 109 110 111 112 113 |
# File 'lib/ask/app_server/agent_adapter.rb', line 107 def wait_for_turn(timeout: 600) thread = @run_thread return true unless thread thread.join(timeout) !thread.alive? end |