Class: Clacky::Server::HistoryCollector

Inherits:
Object
  • Object
show all
Defined in:
lib/clacky/server/http_server.rb

Overview

Lightweight UI collector used by api_session_messages to capture events emitted by Agent#replay_history without broadcasting over WebSocket. Implements the same show_* interface as WebUIController.

Instance Method Summary collapse

Constructor Details

#initialize(session_id, events) ⇒ HistoryCollector

Returns a new instance of HistoryCollector.



31
32
33
34
# File 'lib/clacky/server/http_server.rb', line 31

def initialize(session_id, events)
  @session_id = session_id
  @events     = events
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, **kwargs) ⇒ Object

Ignore all other UI methods (progress, errors, etc.) during history replay



103
# File 'lib/clacky/server/http_server.rb', line 103

def method_missing(name, *args, **kwargs); end

Instance Method Details

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


104
# File 'lib/clacky/server/http_server.rb', line 104

def respond_to_missing?(name, include_private = false); true; end

#show_assistant_message(content, files:) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/clacky/server/http_server.rb', line 62

def show_assistant_message(content, files:)
  return if content.nil? || content.to_s.strip.empty?

  # Rewrite local image paths to /api/local-image proxy URLs for browser rendering
  rewritten = Utils::FileProcessor.rewrite_local_image_urls(content.to_s)
  @events << { type: "assistant_message", session_id: @session_id, content: rewritten }
end

#show_feedback_request(question, context, options) ⇒ Object



97
98
99
100
# File 'lib/clacky/server/http_server.rb', line 97

def show_feedback_request(question, context, options)
  @events << { type: "request_feedback", session_id: @session_id,
               question: question, context: context, options: options }
end

#show_token_usage(token_data) ⇒ Object



91
92
93
94
95
# File 'lib/clacky/server/http_server.rb', line 91

def show_token_usage(token_data)
  return unless token_data.is_a?(Hash)

  @events << { type: "token_usage", session_id: @session_id }.merge(token_data)
end

#show_tool_call(name, args) ⇒ Object



70
71
72
73
74
# File 'lib/clacky/server/http_server.rb', line 70

def show_tool_call(name, args)
  args_data = args.is_a?(String) ? (JSON.parse(args) rescue args) : args
  summary   = tool_call_summary(name, args_data)
  @events << { type: "tool_call", session_id: @session_id, name: name, args: args_data, summary: summary }
end

#show_tool_result(result) ⇒ Object



87
88
89
# File 'lib/clacky/server/http_server.rb', line 87

def show_tool_result(result)
  @events << { type: "tool_result", session_id: @session_id, result: result }
end

#show_user_message(content, created_at: nil, files: []) ⇒ 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
60
# File 'lib/clacky/server/http_server.rb', line 36

def show_user_message(content, created_at: nil, files: [])
  ev = { type: "history_user_message", session_id: @session_id, content: content }
  ev[:created_at] = created_at if created_at
  rendered = Array(files).filter_map do |f|
    url  = f[:data_url] || f["data_url"]
    name = f[:name]     || f["name"]
    path = f[:path]     || f["path"]
    type = f[:type]     || f["type"] || ""

    if url
      url
    elsif type.to_s == "image" && path && File.exist?(path.to_s)
      # Serve via the /api/local-image proxy instead of inlining a base64
      # data URL. Inlining forced a synchronous disk-read + full base64
      # encode + downscale on every history replay (2-3s lag for sessions
      # with downgraded text-model images). The proxy lets the browser
      # lazy-load + cache the image, keeping the replay response tiny.
      "/api/local-image?path=#{CGI.escape(path.to_s)}"
    elsif name
      type.to_s == "image" ? "expired:#{name}" : "pdf:#{name}"
    end
  end
  ev[:images] = rendered unless rendered.empty?
  @events << ev
end