Class: AiTestSupportController

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?” }




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

def agent
  result = TestSupportAgent.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.




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

def agent_memory
  memory = TestSupportMemory.new(session_id: params.require(:session_id))
  result = TestSupportAgent.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);
};



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

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")

  TestSupportAgent.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.




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

def pipeline
  pipe = TestSupportPipeline.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).




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

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

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