Class: Clacky::JsonUIController
- Inherits:
-
Object
- Object
- Clacky::JsonUIController
show all
- Includes:
- UIInterface
- Defined in:
- lib/clacky/json_ui_controller.rb
Overview
JsonUIController implements UIInterface for JSON (NDJSON) output mode. All output is written as one-JSON-per-line to stdout. Confirmation requests read responses from stdin.
Instance Method Summary
collapse
-
#append_output(content) ⇒ Object
append_output is a no-op in JSON mode (content is already emitted via semantic methods).
-
#clear_input ⇒ Object
-
#emit(type, **data) ⇒ Object
-
#initialize(output: $stdout, input: $stdin) ⇒ JsonUIController
constructor
A new instance of JsonUIController.
-
#log(message, level: :info) ⇒ Object
-
#request_confirmation(message, default: true) ⇒ Object
Blocking interaction ===.
-
#set_idle_status ⇒ Object
-
#set_input_tips(message, type: :info) ⇒ Object
-
#set_working_status ⇒ Object
-
#show_assistant_message(content, files:) ⇒ Object
Output display ===.
-
#show_complete(iterations:, cost:, duration: nil, cache_stats: nil, awaiting_user_feedback: false) ⇒ Object
-
#show_diff(old_content, new_content, max_lines: 50) ⇒ Object
-
#show_error(message) ⇒ Object
-
#show_file_edit_preview(path) ⇒ Object
-
#show_file_error(error_message) ⇒ Object
-
#show_file_write_preview(path, is_new_file:) ⇒ Object
-
#show_info(message, prefix_newline: true) ⇒ Object
Status messages ===.
-
#show_progress(message = nil, prefix_newline: true, progress_type: "thinking", phase: "active", metadata: {}) ⇒ Object
Progress ===.
-
#show_shell_preview(command) ⇒ Object
-
#show_success(message) ⇒ Object
-
#show_token_usage(token_data) ⇒ Object
-
#show_tool_args(formatted_args) ⇒ Object
-
#show_tool_call(name, args) ⇒ Object
-
#show_tool_error(error) ⇒ Object
-
#show_tool_result(result) ⇒ Object
-
#show_warning(message) ⇒ Object
-
#stop ⇒ Object
Lifecycle ===.
-
#update_sessionbar(tasks: nil, cost: nil, cost_source: nil, status: nil) ⇒ Object
State updates ===.
-
#update_todos(todos) ⇒ Object
#show_tool_stdout, #start_progress, #with_progress
Constructor Details
#initialize(output: $stdout, input: $stdin) ⇒ JsonUIController
Returns a new instance of JsonUIController.
14
15
16
17
18
|
# File 'lib/clacky/json_ui_controller.rb', line 14
def initialize(output: $stdout, input: $stdin)
@output = output
@input = input
@mutex = Mutex.new
end
|
Instance Method Details
#append_output(content) ⇒ Object
append_output is a no-op in JSON mode (content is already emitted via semantic methods)
90
91
92
|
# File 'lib/clacky/json_ui_controller.rb', line 90
def append_output(content)
end
|
186
187
188
|
# File 'lib/clacky/json_ui_controller.rb', line 186
def clear_input
end
|
#emit(type, **data) ⇒ Object
21
22
23
24
25
26
27
|
# File 'lib/clacky/json_ui_controller.rb', line 21
def emit(type, **data)
event = { type: type }.merge(data)
@mutex.synchronize do
@output.puts(JSON.generate(event))
@output.flush
end
end
|
#log(message, level: :info) ⇒ Object
112
113
114
|
# File 'lib/clacky/json_ui_controller.rb', line 112
def log(message, level: :info)
emit("log", level: level.to_s, message: message)
end
|
#request_confirmation(message, default: true) ⇒ Object
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
# File 'lib/clacky/json_ui_controller.rb', line 160
def request_confirmation(message, default: true)
conf_id = "conf_#{SecureRandom.hex(4)}"
emit("request_confirmation", id: conf_id, message: message, default: default)
line = @input.gets
return default if line.nil?
begin
response = JSON.parse(line.strip)
result = response["result"] || response[:result]
case result.to_s.downcase
when "yes", "y" then true
when "no", "n" then false
else
result.to_s
end
rescue JSON::ParserError
default
end
end
|
#set_idle_status ⇒ Object
154
155
156
|
# File 'lib/clacky/json_ui_controller.rb', line 154
def set_idle_status
emit("session_update", status: "idle")
end
|
190
191
192
|
# File 'lib/clacky/json_ui_controller.rb', line 190
def set_input_tips(message, type: :info)
end
|
#set_working_status ⇒ Object
150
151
152
|
# File 'lib/clacky/json_ui_controller.rb', line 150
def set_working_status
emit("session_update", status: "working")
end
|
#show_assistant_message(content, files:) ⇒ Object
31
32
33
34
35
36
37
|
# File 'lib/clacky/json_ui_controller.rb', line 31
def show_assistant_message(content, files:)
return if (content.nil? || content.strip.empty?) && files.empty?
data = { content: content.to_s }
data[:files] = files if files.any?
emit("assistant_message", **data)
end
|
#show_complete(iterations:, cost:, duration: nil, cache_stats: nil, awaiting_user_feedback: false) ⇒ Object
81
82
83
84
85
86
87
|
# File 'lib/clacky/json_ui_controller.rb', line 81
def show_complete(iterations:, cost:, duration: nil, cache_stats: nil, awaiting_user_feedback: false)
data = { iterations: iterations, cost: cost }
data[:duration] = duration if duration
data[:cache_stats] = cache_stats if cache_stats
data[:awaiting_user_feedback] = awaiting_user_feedback if awaiting_user_feedback
emit("complete", **data)
end
|
#show_diff(old_content, new_content, max_lines: 50) ⇒ Object
73
74
75
|
# File 'lib/clacky/json_ui_controller.rb', line 73
def show_diff(old_content, new_content, max_lines: 50)
emit("diff", old_size: old_content.bytesize, new_size: new_content.bytesize)
end
|
#show_error(message) ⇒ Object
104
105
106
|
# File 'lib/clacky/json_ui_controller.rb', line 104
def show_error(message)
emit("error", message: message)
end
|
#show_file_edit_preview(path) ⇒ Object
61
62
63
|
# File 'lib/clacky/json_ui_controller.rb', line 61
def show_file_edit_preview(path)
emit("file_preview", path: path, operation: "edit")
end
|
#show_file_error(error_message) ⇒ Object
65
66
67
|
# File 'lib/clacky/json_ui_controller.rb', line 65
def show_file_error(error_message)
emit("file_error", error: error_message)
end
|
#show_file_write_preview(path, is_new_file:) ⇒ Object
57
58
59
|
# File 'lib/clacky/json_ui_controller.rb', line 57
def show_file_write_preview(path, is_new_file:)
emit("file_preview", path: path, operation: "write", is_new_file: is_new_file)
end
|
#show_info(message, prefix_newline: true) ⇒ Object
96
97
98
|
# File 'lib/clacky/json_ui_controller.rb', line 96
def show_info(message, prefix_newline: true)
emit("info", message: message)
end
|
#show_progress(message = nil, prefix_newline: true, progress_type: "thinking", phase: "active", metadata: {}) ⇒ Object
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# File 'lib/clacky/json_ui_controller.rb', line 118
def show_progress(message = nil, prefix_newline: true, progress_type: "thinking", phase: "active", metadata: {})
@progress_start_time = Time.now if phase == "active"
data = {
message: message,
progress_type: progress_type,
phase: phase,
status: phase == "active" ? "start" : "stop" }
data[:metadata] = metadata unless metadata.empty?
data[:elapsed] = (Time.now - @progress_start_time).round(1) if phase == "done" && @progress_start_time
emit("progress", **data)
@progress_start_time = nil if phase == "done"
end
|
#show_shell_preview(command) ⇒ Object
69
70
71
|
# File 'lib/clacky/json_ui_controller.rb', line 69
def show_shell_preview(command)
emit("shell_preview", command: command)
end
|
#show_success(message) ⇒ Object
108
109
110
|
# File 'lib/clacky/json_ui_controller.rb', line 108
def show_success(message)
emit("success", message: message)
end
|
#show_token_usage(token_data) ⇒ Object
77
78
79
|
# File 'lib/clacky/json_ui_controller.rb', line 77
def show_token_usage(token_data)
emit("token_usage", **token_data)
end
|
53
54
55
|
# File 'lib/clacky/json_ui_controller.rb', line 53
def show_tool_args(formatted_args)
emit("tool_args", args: formatted_args)
end
|
39
40
41
42
|
# File 'lib/clacky/json_ui_controller.rb', line 39
def show_tool_call(name, args)
args_data = args.is_a?(String) ? (JSON.parse(args) rescue args) : args
emit("tool_call", name: name, args: args_data)
end
|
48
49
50
51
|
# File 'lib/clacky/json_ui_controller.rb', line 48
def show_tool_error(error)
error_msg = error.is_a?(Exception) ? error.message : error.to_s
emit("tool_error", error: error_msg)
end
|
44
45
46
|
# File 'lib/clacky/json_ui_controller.rb', line 44
def show_tool_result(result)
emit("tool_result", result: result)
end
|
#show_warning(message) ⇒ Object
100
101
102
|
# File 'lib/clacky/json_ui_controller.rb', line 100
def show_warning(message)
emit("warning", message: message)
end
|
#stop ⇒ Object
196
197
198
|
# File 'lib/clacky/json_ui_controller.rb', line 196
def stop
end
|
#update_sessionbar(tasks: nil, cost: nil, cost_source: nil, status: nil) ⇒ Object
137
138
139
140
141
142
143
144
|
# File 'lib/clacky/json_ui_controller.rb', line 137
def update_sessionbar(tasks: nil, cost: nil, cost_source: nil, status: nil)
data = {}
data[:tasks] = tasks if tasks
data[:cost] = cost if cost
data[:cost_source] = cost_source if cost_source
data[:status] = status if status
emit("session_update", **data) unless data.empty?
end
|
#update_todos(todos) ⇒ Object
146
147
148
|
# File 'lib/clacky/json_ui_controller.rb', line 146
def update_todos(todos)
emit("todo_update", todos: todos)
end
|