Class: AgUi::Server::Triage

Inherits:
Object
  • Object
show all
Defined in:
lib/ag_ui/server/triage.rb

Overview

Resolves the incoming request to an AG-UI operation, mirroring the Node runtime's suffix-matching fetch-router (doc 09 §2):

GET  …/info                        → "info"
POST …/agent/:agentId/run          → "run"     (body = RunAgentInput)
POST …/agent/:agentId/connect      → "connect" (body tolerated, not required)
POST …/agent/:agentId/stop/:tid    → "stop"
POST <mount root>                  → "run"     (bare AG-UI endpoint —
                                   what @ag-ui/client's HttpAgent
                                   POSTs when given a plain URL)
OPTIONS *                          → 204 (permissive CORS preflight)

Sets env, env and, for runs, env (parsed RunInput). Short-circuits 400 on a bad run body and 404 on unknown routes — downstream only ever sees a resolved operation.

Works both mounted (Rails/Rack map set SCRIPT_NAME, PATH_INFO is relative) and standalone: matching is on trailing path segments.

Constant Summary collapse

AGENT_ROUTE =
%r{/agent/(?<agent_id>[^/]+)/(?<action>run|connect)\z}
STOP_ROUTE =
%r{/agent/(?<agent_id>[^/]+)/stop/(?<thread_id>[^/]+)\z}
INFO_ROUTE =
%r{(\A|/)info\z}

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ Triage

Returns a new instance of Triage.



32
33
34
# File 'lib/ag_ui/server/triage.rb', line 32

def initialize(app)
  @app = app
end

Instance Method Details

#call(env) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/ag_ui/server/triage.rb', line 36

def call(env)
  method = env["REQUEST_METHOD"]
  path   = env["PATH_INFO"].to_s.chomp("/")

  if method == "OPTIONS"
    preflight
  elsif method == "GET" && path.match?(INFO_ROUTE)
    @app.call(env.merge("ag_ui.operation" => "info"))
  elsif method == "POST" && (m = path.match(STOP_ROUTE))
    @app.call(
      env.merge(
        "ag_ui.operation" => "stop",
        "ag_ui.agent_id" => m[:agent_id],
        "ag_ui.thread_id" => m[:thread_id],
      ),
    )
  elsif method == "POST" && (m = path.match(AGENT_ROUTE))
    dispatch_agent(env, m)
  elsif method == "POST" && path.empty?
    dispatch_bare_run(env)
  else
    not_found
  end
end