Class: AiSupportController

Inherits:
ApplicationController
  • Object
show all
Includes:
ActionController::Live
Defined in:
lib/generators/active_harness/install/templates/controllers/ai_controller.rb

Instance Method Summary collapse

Instance Method Details

#agentObject


POST /ai/agent body: { input: “What is your return policy?” }




10
11
12
13
14
15
16
17
18
# File 'lib/generators/active_harness/install/templates/controllers/ai_controller.rb', line 10

def agent
  result = SupportAgent.call(input: params.require(:input))

  render json: {
    output: result.output,
    model:  result.model,
    time:   result.execution_time
  }
end

#agent_memoryObject


POST /ai/agent_memory body: { input: “Does that apply to accessories?”, session_id: “user_42” }

Uses AppMemory so the same session keeps conversational context across multiple requests.




27
28
29
30
31
32
33
34
35
36
37
# File 'lib/generators/active_harness/install/templates/controllers/ai_controller.rb', line 27

def agent_memory
  memory = AppMemory.new(session_id: params.require(:session_id))
  result = SupportAgent.call(input: params.require(:input), memory: memory)

  render json: {
    output: result.output,
    model:  result.model,
    time:   result.execution_time,
    turns:  memory.size
  }
end

#agent_streamObject


GET /ai/agent_stream?input=What+is+your+return+policy%3F

Streams the response token by token using Server-Sent Events. Each token arrives as: data: “token”:“…” End of stream is marked: data: “done”:true

JavaScript client example:

const es = new EventSource('/ai/agent_stream?input=Hello');
es.onmessage = ({ data }) => {
  const { token, done } = JSON.parse(data);
  if (done) { es.close(); return; }
  document.querySelector('#output').insertAdjacentText('beforeend', token);
};



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/generators/active_harness/install/templates/controllers/ai_controller.rb', line 87

def agent_stream
  input = params.require(:input)

  response.headers["Content-Type"]  = "text/event-stream"
  response.headers["Cache-Control"] = "no-cache"
  response.headers["X-Accel-Buffering"] = "no"  # disable nginx buffering

  sse = ActionController::Live::SSE.new(response.stream, event: "message")

  SupportAgent.call(
    input:  input,
    stream: ->(token) { sse.write({ token: token }.to_json) }
  )

  sse.write({ done: true }.to_json)
rescue ActionController::Live::ClientDisconnected
  # client closed the connection — normal, nothing to do
ensure
  sse.close
end

#pipelineObject


POST /ai/pipeline body: { input: “What is your return policy?” }

Runs the full TestSupportPipeline. If a guard step stops the pipeline early, stopped: true is returned.




61
62
63
64
65
66
67
68
69
70
# File 'lib/generators/active_harness/install/templates/controllers/ai_controller.rb', line 61

def pipeline
  pipe = SupportPipeline.new(input: params.require(:input))
  pipe.call

  if pipe.stopped?
    render json: { stopped: true, stopped_at: pipe.stopped_at }
  else
    render json: { stopped: false, output: pipe.output }
  end
end

#tribunalObject


POST /ai/tribunal body: { input: “Buy cheap pills now!!!” }

Returns verdict: true (safe) or false (rejected).




45
46
47
48
49
50
51
52
# File 'lib/generators/active_harness/install/templates/controllers/ai_controller.rb', line 45

def tribunal
  result = SupportGuardTribunal.call(input: params.require(:input))

  render json: {
    verdict: result.verdict,
    time:    result.execution_time
  }
end