Class: Insika::Wiring::GraphChat
- Inherits:
-
Object
- Object
- Insika::Wiring::GraphChat
- Defined in:
- lib/insika/wiring/graph_chat.rb
Overview
A synchronous, in-process "chat" seam over an assembled Graph::Result:
dispatch a Command, drain the event stream to its terminal event, hand
back the outcome. Extracted from DSL::Runtime#chat/#run_workflow
(C3.1) so a graph built OUTSIDE the DSL — config/deployment.rb, the
actual production/round1 composition root config.ru boots — can hand a
#chat-capable object to anything that needs one (today:
run_persona_eval's Evals::GraphTransport seam), without a second copy
of this dispatch+drain plumbing. DSL::Runtime now delegates here too —
one implementation, exercised by both roots.
Constant Summary collapse
- TERMINAL =
%i[task_completed task_failed task_cancelled].freeze
Instance Method Summary collapse
-
#chat(message, agent:, session_id: nil, timeout: nil) ⇒ Object
One turn, in-process -> the assistant's text.
-
#initialize(graph:) ⇒ GraphChat
constructor
A new instance of GraphChat.
-
#run_command(command, session_id:, timeout:) ⇒ Object
Dispatch + drain, generic over any Command — the seam a workflow run also needs (a :trigger_workflow Command carries :output, not :text).
Constructor Details
#initialize(graph:) ⇒ GraphChat
Returns a new instance of GraphChat.
17 18 19 |
# File 'lib/insika/wiring/graph_chat.rb', line 17 def initialize(graph:) @graph = graph end |
Instance Method Details
#chat(message, agent:, session_id: nil, timeout: nil) ⇒ Object
One turn, in-process -> the assistant's text. agent: is REQUIRED —
this seam has no notion of "the default agent" (that is a DSL::Runtime
concept, filled in by its own caller before delegating here). Raises
Insika::Error on a failed/cancelled turn, or the command's own
rejection (unknown agent, bad schema) verbatim.
26 27 28 29 30 31 32 |
# File 'lib/insika/wiring/graph_chat.rb', line 26 def chat(, agent:, session_id: nil, timeout: nil) command = Insika::Command.build( :send_message, { agent: agent.to_s, message: , session_id: session_id }, transport: :cli ) run_command(command, session_id: session_id, timeout: timeout)[:text] end |
#run_command(command, session_id:, timeout:) ⇒ Object
Dispatch + drain, generic over any Command — the seam a workflow run also needs (a :trigger_workflow Command carries :output, not :text). Subscribes BEFORE dispatching (the fiber may emit eagerly) and binds to the dispatched task. A synchronous handler error (unknown agent/ workflow, bad input against the schema) propagates untouched — the caller sees the real ValidationError/NotFoundError, not a turn failure.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/insika/wiring/graph_chat.rb', line 40 def run_command(command, session_id:, timeout:) require "async" outcome = {} rejected = nil Async do |task| serving = !session_id.nil? @graph.executor.supervised = true if serving ensure_session(session_id) if session_id sub = @graph.event_stream.subscribe res = begin @graph.bus.dispatch(command) rescue StandardError => e # CAPTURED, not re-raised inside the reactor: letting it escape the # Async block logs "Task may have ended with unhandled exception" — # alarming noise for a DOCUMENTED rejection (a schema violation, an # unknown agent). Re-raised verbatim below, outside the reactor. sub.close rejected = e next end sub.bind(task_id: res[:task_id]) drain(sub, outcome, task, timeout) teardown_serving if serving end.wait raise rejected if rejected raise Insika::Error, "turn #{outcome[:error]}" if outcome[:error] outcome end |