kward 0.74.0 → 0.75.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/Gemfile.lock +2 -2
- data/README.md +4 -2
- data/Rakefile +18 -0
- data/doc/configuration.md +56 -3
- data/doc/extensibility.md +6 -19
- data/doc/getting-started.md +1 -1
- data/doc/lifecycle-hooks.md +424 -0
- data/doc/memory.md +1 -1
- data/doc/personas.md +2 -2
- data/doc/plugins.md +1 -1
- data/doc/releasing.md +7 -15
- data/doc/rpc.md +108 -16
- data/doc/session-management.md +9 -9
- data/doc/skills.md +199 -0
- data/doc/usage.md +7 -7
- data/lib/kward/agent.rb +72 -22
- data/lib/kward/auth/anthropic_oauth.rb +5 -87
- data/lib/kward/auth/oauth_helpers.rb +105 -0
- data/lib/kward/auth/openai_oauth.rb +4 -86
- data/lib/kward/cli/commands.rb +9 -2
- data/lib/kward/cli/compaction.rb +7 -0
- data/lib/kward/cli/git.rb +30 -3
- data/lib/kward/cli/hook_commands.rb +258 -0
- data/lib/kward/cli/memory_commands.rb +1 -5
- data/lib/kward/cli/plugins.rb +41 -1
- data/lib/kward/cli/prompt_interface.rb +32 -3
- data/lib/kward/cli/rendering.rb +1 -1
- data/lib/kward/cli/runtime_helpers.rb +44 -5
- data/lib/kward/cli/sessions.rb +13 -0
- data/lib/kward/cli/settings.rb +226 -152
- data/lib/kward/cli/slash_commands.rb +81 -42
- data/lib/kward/cli/tabs.rb +26 -6
- data/lib/kward/cli.rb +26 -3
- data/lib/kward/cli_transcript_formatter.rb +0 -7
- data/lib/kward/compaction/token_estimator.rb +112 -0
- data/lib/kward/compactor.rb +42 -116
- data/lib/kward/config_files.rb +117 -25
- data/lib/kward/deep_copy.rb +42 -0
- data/lib/kward/diff_view_mode.rb +36 -0
- data/lib/kward/events.rb +1 -0
- data/lib/kward/export_path.rb +2 -6
- data/lib/kward/frontmatter.rb +43 -0
- data/lib/kward/hooks/audit_log.rb +121 -0
- data/lib/kward/hooks/catalog.rb +110 -0
- data/lib/kward/hooks/command_handler.rb +66 -0
- data/lib/kward/hooks/config_loader.rb +104 -0
- data/lib/kward/hooks/decision.rb +102 -0
- data/lib/kward/hooks/event.rb +60 -0
- data/lib/kward/hooks/http_handler.rb +72 -0
- data/lib/kward/hooks/manager.rb +158 -0
- data/lib/kward/hooks/matcher.rb +75 -0
- data/lib/kward/hooks.rb +16 -0
- data/lib/kward/markdown_transcript.rb +4 -3
- data/lib/kward/mcp/client.rb +1 -1
- data/lib/kward/mcp/server_config.rb +7 -3
- data/lib/kward/mcp/stdio_transport.rb +7 -1
- data/lib/kward/memory/turn_context.rb +19 -0
- data/lib/kward/message_access.rb +2 -2
- data/lib/kward/message_text.rb +19 -0
- data/lib/kward/model/client.rb +13 -45
- data/lib/kward/model/context_usage.rb +10 -4
- data/lib/kward/model/copilot_models.rb +44 -0
- data/lib/kward/model/model_info.rb +24 -0
- data/lib/kward/model/payloads.rb +15 -17
- data/lib/kward/model/stream_parser.rb +178 -13
- data/lib/kward/pan/server.rb +51 -2
- data/lib/kward/path_guard.rb +13 -0
- data/lib/kward/plugin_registry.rb +86 -25
- data/lib/kward/prompt_interface/editor/controller.rb +60 -1
- data/lib/kward/prompt_interface/editor/renderer.rb +11 -0
- data/lib/kward/prompt_interface/editor/state.rb +5 -1
- data/lib/kward/prompt_interface/selection_prompt.rb +26 -6
- data/lib/kward/prompt_interface.rb +4 -1
- data/lib/kward/prompts/commands.rb +3 -3
- data/lib/kward/prompts.rb +7 -7
- data/lib/kward/rpc/mcp_status.rb +50 -0
- data/lib/kward/rpc/prompt_bridge.rb +38 -4
- data/lib/kward/rpc/runtime_payloads.rb +1 -1
- data/lib/kward/rpc/server.rb +94 -14
- data/lib/kward/rpc/session_manager.rb +258 -33
- data/lib/kward/rpc/session_metrics.rb +1 -1
- data/lib/kward/rpc/session_tree_rows.rb +13 -64
- data/lib/kward/rpc/tool_event_normalizer.rb +16 -2
- data/lib/kward/rpc/transcript_normalizer.rb +9 -10
- data/lib/kward/rpc/turn_context.rb +109 -0
- data/lib/kward/session_store.rb +6 -20
- data/lib/kward/session_tree_nodes.rb +98 -18
- data/lib/kward/session_tree_renderer.rb +6 -61
- data/lib/kward/skills/registry.rb +109 -17
- data/lib/kward/tools/mcp_tool.rb +4 -0
- data/lib/kward/tools/read_skill.rb +9 -4
- data/lib/kward/tools/registry.rb +266 -8
- data/lib/kward/tools/search/code.rb +4 -22
- data/lib/kward/tools/search/web.rb +28 -2
- data/lib/kward/update_check.rb +117 -0
- data/lib/kward/version.rb +1 -1
- data/lib/kward/workers/manager.rb +43 -3
- data/lib/kward/workspace.rb +3 -1
- data/templates/default/fulldoc/html/css/kward.css +22 -0
- data/templates/default/fulldoc/html/js/kward.js +2 -0
- data/templates/default/kward_navigation.rb +4 -2
- data/templates/default/layout/html/setup.rb +2 -0
- metadata +25 -1
data/lib/kward/cli/settings.rb
CHANGED
|
@@ -12,11 +12,14 @@ module Kward
|
|
|
12
12
|
return
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
initial_index = 0
|
|
15
16
|
loop do
|
|
16
|
-
|
|
17
|
+
choices = settings_category_choices
|
|
18
|
+
selected, selected_index = select_settings_menu_item("Settings category", choices, initial_index)
|
|
17
19
|
category = selected_settings_category(selected)
|
|
18
20
|
break unless category
|
|
19
21
|
|
|
22
|
+
initial_index = selected_index if selected_index
|
|
20
23
|
break if category == "done"
|
|
21
24
|
|
|
22
25
|
handle_settings_category(category, conversation)
|
|
@@ -83,14 +86,22 @@ module Kward
|
|
|
83
86
|
end
|
|
84
87
|
|
|
85
88
|
def configure_model_settings(conversation)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
initial_index = 0
|
|
90
|
+
loop do
|
|
91
|
+
selected, selected_index = select_settings_menu_item("Model & Reasoning", ["Provider", "Default model", "Reasoning effort", "Back"], initial_index)
|
|
92
|
+
break unless selected
|
|
93
|
+
|
|
94
|
+
initial_index = selected_index if selected_index
|
|
95
|
+
case selected.to_s.downcase
|
|
96
|
+
when /\Aprovider/
|
|
97
|
+
configure_provider(conversation)
|
|
98
|
+
when /\Adefault model/
|
|
99
|
+
configure_model(conversation)
|
|
100
|
+
when /\Areasoning effort/
|
|
101
|
+
configure_reasoning(conversation)
|
|
102
|
+
else
|
|
103
|
+
break
|
|
104
|
+
end
|
|
94
105
|
end
|
|
95
106
|
end
|
|
96
107
|
|
|
@@ -125,22 +136,30 @@ module Kward
|
|
|
125
136
|
end
|
|
126
137
|
|
|
127
138
|
def configure_account_settings
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
139
|
+
initial_index = 0
|
|
140
|
+
loop do
|
|
141
|
+
selected, selected_index = select_settings_menu_item("Accounts", account_setting_choices, initial_index)
|
|
142
|
+
break unless selected
|
|
143
|
+
|
|
144
|
+
initial_index = selected_index if selected_index
|
|
145
|
+
case selected.to_s.downcase
|
|
146
|
+
when /\Aopenai/
|
|
147
|
+
login(provider: "openai")
|
|
148
|
+
reload_client_config
|
|
149
|
+
when /\Aanthropic/, /\Aclaude/
|
|
150
|
+
login(provider: "anthropic")
|
|
151
|
+
reload_client_config
|
|
152
|
+
when /\Agithub/
|
|
153
|
+
login(provider: "github")
|
|
154
|
+
reload_client_config
|
|
155
|
+
when /\Aopenrouter/
|
|
156
|
+
login(provider: "openrouter")
|
|
157
|
+
reload_client_config
|
|
158
|
+
when /\Astatus/
|
|
159
|
+
print_auth_status
|
|
160
|
+
else
|
|
161
|
+
break
|
|
162
|
+
end
|
|
144
163
|
end
|
|
145
164
|
end
|
|
146
165
|
|
|
@@ -163,17 +182,25 @@ module Kward
|
|
|
163
182
|
end
|
|
164
183
|
|
|
165
184
|
def configure_memory_settings(conversation)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
185
|
+
initial_index = 0
|
|
186
|
+
loop do
|
|
187
|
+
selected, selected_index = select_settings_menu_item("Memory", memory_setting_choices, initial_index)
|
|
188
|
+
break unless selected
|
|
189
|
+
|
|
190
|
+
initial_index = selected_index if selected_index
|
|
191
|
+
case selected.to_s.downcase
|
|
192
|
+
when /\Aenable memory/, /\Adisable memory/
|
|
193
|
+
set_config_flag("memory", "enabled", !memory_enabled?)
|
|
194
|
+
conversation&.refresh_system_message!
|
|
195
|
+
runtime_output("Memory #{memory_enabled? ? "enabled" : "disabled"}.")
|
|
196
|
+
when /\Aenable auto-summary/, /\Adisable auto-summary/
|
|
197
|
+
set_config_flag("memory", "auto_summary", !memory_auto_summary_enabled?)
|
|
198
|
+
runtime_output("Memory auto-summary #{memory_auto_summary_enabled? ? "enabled" : "disabled"}.")
|
|
199
|
+
when /\Amanage/
|
|
200
|
+
runtime_output("Use /memory enable|disable|auto-summary enable|disable|core <text>|add <text>|list|forget <id>|promote <id>|relax <id>|inspect|why|summarize.")
|
|
201
|
+
else
|
|
202
|
+
break
|
|
203
|
+
end
|
|
177
204
|
end
|
|
178
205
|
end
|
|
179
206
|
|
|
@@ -196,50 +223,52 @@ module Kward
|
|
|
196
223
|
memory.is_a?(Hash) && memory["auto_summary"] == true
|
|
197
224
|
end
|
|
198
225
|
|
|
199
|
-
def set_memory_enabled(enabled)
|
|
200
|
-
update_nested_config("memory", "enabled" => enabled)
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def set_memory_auto_summary_enabled(enabled)
|
|
204
|
-
update_nested_config("memory", "auto_summary" => enabled)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
226
|
def configure_interface_settings
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
227
|
+
initial_index = 0
|
|
228
|
+
loop do
|
|
229
|
+
selected, selected_index = select_settings_menu_item("Interface", interface_setting_choices, initial_index)
|
|
230
|
+
break unless selected
|
|
231
|
+
|
|
232
|
+
initial_index = selected_index if selected_index
|
|
233
|
+
case selected.to_s.downcase
|
|
234
|
+
when /\Aoverlay alignment/
|
|
235
|
+
settings = ConfigFiles.overlay_settings
|
|
236
|
+
alignment = choose_overlay_setting("Overlay alignment", overlay_alignment_choices(settings), ConfigFiles::OVERLAY_ALIGNMENTS)
|
|
237
|
+
next unless alignment
|
|
238
|
+
|
|
239
|
+
update_overlay_settings("alignment" => alignment)
|
|
240
|
+
when /\Aoverlay width/
|
|
241
|
+
settings = ConfigFiles.overlay_settings
|
|
242
|
+
width = choose_overlay_setting("Overlay width", overlay_width_choices(settings), ConfigFiles::OVERLAY_WIDTHS)
|
|
243
|
+
next unless width
|
|
244
|
+
|
|
245
|
+
update_overlay_settings("width" => width)
|
|
246
|
+
when /\Ashow busy help/, /\Ahide busy help/
|
|
247
|
+
set_composer_busy_help(!composer_busy_help?)
|
|
248
|
+
runtime_output("Busy help #{composer_busy_help? ? "enabled" : "disabled"}. Restart the TUI to apply this setting.")
|
|
249
|
+
when /\Atab keybindings/
|
|
250
|
+
configure_tab_keybindings
|
|
251
|
+
when /\Aeditor mode/
|
|
252
|
+
configure_editor_mode
|
|
253
|
+
when /\Aeditor line numbers/
|
|
254
|
+
configure_editor_line_numbers
|
|
255
|
+
when /\Adiff view/
|
|
256
|
+
configure_diff_view
|
|
257
|
+
when /\Aenable auto-close pairs/, /\Adisable auto-close pairs/
|
|
258
|
+
set_config_flag("editor", "auto_close_pairs", !editor_auto_close_pairs_enabled?)
|
|
259
|
+
runtime_output("Editor auto-close pairs #{editor_auto_close_pairs_enabled? ? "enabled" : "disabled"}.")
|
|
260
|
+
when /\Aenable soft-wrap/, /\Adisable soft-wrap/
|
|
261
|
+
set_config_flag("editor", "soft_wrap", !editor_soft_wrap_enabled?)
|
|
262
|
+
runtime_output("Editor soft-wrap #{editor_soft_wrap_enabled? ? "enabled" : "disabled"}.")
|
|
263
|
+
when /\Aenable bar cursor/, /\Adisable bar cursor/
|
|
264
|
+
set_config_flag("editor", "bar_cursor", !editor_bar_cursor_enabled?)
|
|
265
|
+
runtime_output("Editor bar cursor #{editor_bar_cursor_enabled? ? "enabled" : "disabled"}.")
|
|
266
|
+
when /\Aenable session auto-resume/, /\Adisable session auto-resume/
|
|
267
|
+
set_config_flag("sessions", "auto_resume", !session_auto_resume_enabled?)
|
|
268
|
+
runtime_output("Session auto-resume #{session_auto_resume_enabled? ? "enabled" : "disabled"}.")
|
|
269
|
+
else
|
|
270
|
+
break
|
|
271
|
+
end
|
|
243
272
|
end
|
|
244
273
|
end
|
|
245
274
|
|
|
@@ -252,6 +281,7 @@ module Kward
|
|
|
252
281
|
"Tab keybindings (#{composer_tab_keybindings})",
|
|
253
282
|
"Editor mode (#{editor_mode})",
|
|
254
283
|
"Editor line numbers (#{editor_line_numbers})",
|
|
284
|
+
"Diff view (#{diff_view_label(diff_view)})",
|
|
255
285
|
"#{editor_auto_close_pairs_enabled? ? "Disable" : "Enable"} auto-close pairs (currently #{on_off(editor_auto_close_pairs_enabled?)})",
|
|
256
286
|
"#{editor_soft_wrap_enabled? ? "Disable" : "Enable"} soft-wrap (currently #{on_off(editor_soft_wrap_enabled?)})",
|
|
257
287
|
"#{editor_bar_cursor_enabled? ? "Disable" : "Enable"} bar cursor (currently #{on_off(editor_bar_cursor_enabled?)})",
|
|
@@ -318,28 +348,41 @@ module Kward
|
|
|
318
348
|
%w[absolute relative].map { |value| value == current ? "#{value} (current)" : value }
|
|
319
349
|
end
|
|
320
350
|
|
|
321
|
-
def
|
|
322
|
-
ConfigFiles.
|
|
351
|
+
def diff_view
|
|
352
|
+
ConfigFiles.diff_view(safely_read_config.to_h)
|
|
323
353
|
end
|
|
324
354
|
|
|
325
|
-
def
|
|
326
|
-
|
|
355
|
+
def configure_diff_view
|
|
356
|
+
selected = @prompt.select("Diff view", diff_view_choices, title: "Settings")
|
|
357
|
+
value = selected.to_s.split.first.to_s.downcase.tr("-", "_")
|
|
358
|
+
return unless Kward::DiffViewMode::MODES.include?(value)
|
|
359
|
+
|
|
360
|
+
update_nested_config("editor", "diff_view" => value)
|
|
361
|
+
runtime_output("Diff view set to #{diff_view_label(value)}.")
|
|
327
362
|
end
|
|
328
363
|
|
|
329
|
-
def
|
|
330
|
-
|
|
364
|
+
def diff_view_choices
|
|
365
|
+
current = diff_view
|
|
366
|
+
Kward::DiffViewMode::MODES.map do |value|
|
|
367
|
+
label = diff_view_label(value)
|
|
368
|
+
value == current ? "#{label} (current)" : label
|
|
369
|
+
end
|
|
331
370
|
end
|
|
332
371
|
|
|
333
|
-
def
|
|
334
|
-
|
|
372
|
+
def diff_view_label(value)
|
|
373
|
+
Kward::DiffViewMode.label(value)
|
|
335
374
|
end
|
|
336
375
|
|
|
337
|
-
def
|
|
338
|
-
ConfigFiles.
|
|
376
|
+
def editor_auto_close_pairs_enabled?
|
|
377
|
+
ConfigFiles.editor_auto_close_pairs?(safely_read_config.to_h)
|
|
339
378
|
end
|
|
340
379
|
|
|
341
|
-
def
|
|
342
|
-
|
|
380
|
+
def editor_soft_wrap_enabled?
|
|
381
|
+
ConfigFiles.editor_soft_wrap?(safely_read_config.to_h)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def editor_bar_cursor_enabled?
|
|
385
|
+
ConfigFiles.editor_bar_cursor?(safely_read_config.to_h)
|
|
343
386
|
end
|
|
344
387
|
|
|
345
388
|
def session_auto_resume_enabled?
|
|
@@ -347,27 +390,34 @@ module Kward
|
|
|
347
390
|
end
|
|
348
391
|
|
|
349
392
|
def set_composer_busy_help(enabled)
|
|
350
|
-
|
|
351
|
-
end
|
|
352
|
-
|
|
353
|
-
def set_session_auto_resume_enabled(enabled)
|
|
354
|
-
update_nested_config("sessions", "auto_resume" => enabled)
|
|
393
|
+
set_config_flag("composer", "busy_help", enabled)
|
|
355
394
|
end
|
|
356
395
|
|
|
357
396
|
def configure_tools_settings
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
397
|
+
initial_index = 0
|
|
398
|
+
loop do
|
|
399
|
+
selected, selected_index = select_settings_menu_item("Tools & Search", tools_setting_choices, initial_index)
|
|
400
|
+
break unless selected
|
|
401
|
+
|
|
402
|
+
initial_index = selected_index if selected_index
|
|
403
|
+
case selected.to_s.downcase
|
|
404
|
+
when /\Aenable web search/, /\Adisable web search/
|
|
405
|
+
set_config_flag("web_search", "enabled", !web_search_enabled?)
|
|
406
|
+
runtime_output("Web search #{web_search_enabled? ? "enabled" : "disabled"}.")
|
|
407
|
+
when /\Aweb search provider/
|
|
408
|
+
configure_web_search_provider
|
|
409
|
+
when /\Aallow model-provider/, /\Adisallow model-provider/
|
|
410
|
+
set_config_flag("web_search", "allow_model_providers", !web_search_allow_model_providers?)
|
|
411
|
+
runtime_output("Model-provider web search #{web_search_allow_model_providers? ? "enabled" : "disabled"}.")
|
|
412
|
+
when /\Atrust project skills/, /\Auntrust project skills/
|
|
413
|
+
set_config_flag("skills", "trust_project", !project_skills_trusted?)
|
|
414
|
+
runtime_output("Project skills #{project_skills_trusted? ? "trusted" : "untrusted"}.")
|
|
415
|
+
when /\Aenable workspace guardrails/, /\Adisable workspace guardrails/
|
|
416
|
+
set_config_flag("tools", "workspace_guardrails", !workspace_guardrails_enabled?)
|
|
417
|
+
runtime_output("Workspace guardrails #{workspace_guardrails_enabled? ? "enabled" : "disabled"}.")
|
|
418
|
+
else
|
|
419
|
+
break
|
|
420
|
+
end
|
|
371
421
|
end
|
|
372
422
|
end
|
|
373
423
|
|
|
@@ -376,6 +426,7 @@ module Kward
|
|
|
376
426
|
"#{web_search_enabled? ? "Disable" : "Enable"} web search (currently #{on_off(web_search_enabled?)})",
|
|
377
427
|
"Web search provider (#{web_search_provider})",
|
|
378
428
|
"#{web_search_allow_model_providers? ? "Disallow" : "Allow"} model-provider web search (currently #{on_off(web_search_allow_model_providers?)})",
|
|
429
|
+
"#{project_skills_trusted? ? "Untrust" : "Trust"} project skills (currently #{on_off(project_skills_trusted?)})",
|
|
379
430
|
"#{workspace_guardrails_enabled? ? "Disable" : "Enable"} workspace guardrails (currently #{on_off(workspace_guardrails_enabled?)})",
|
|
380
431
|
"Back"
|
|
381
432
|
]
|
|
@@ -406,26 +457,26 @@ module Kward
|
|
|
406
457
|
web_search_config["allow_model_providers"] == true
|
|
407
458
|
end
|
|
408
459
|
|
|
409
|
-
def
|
|
410
|
-
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
def set_web_search_allow_model_providers(enabled)
|
|
414
|
-
update_nested_config("web_search", "allow_model_providers" => enabled)
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
def set_workspace_guardrails_enabled(enabled)
|
|
418
|
-
update_nested_config("tools", "workspace_guardrails" => enabled)
|
|
460
|
+
def project_skills_trusted?
|
|
461
|
+
ConfigFiles.project_skills_trusted?(safely_read_config.to_h)
|
|
419
462
|
end
|
|
420
463
|
|
|
421
464
|
def configure_context_settings
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
465
|
+
initial_index = 0
|
|
466
|
+
loop do
|
|
467
|
+
selected, selected_index = select_settings_menu_item("Context & Compaction", context_setting_choices, initial_index)
|
|
468
|
+
break unless selected
|
|
469
|
+
|
|
470
|
+
initial_index = selected_index if selected_index
|
|
471
|
+
case selected.to_s.downcase
|
|
472
|
+
when /\Aenable auto-compaction/, /\Adisable auto-compaction/
|
|
473
|
+
set_config_flag("compaction", "enabled", !compaction_enabled?)
|
|
474
|
+
runtime_output("Auto-compaction #{compaction_enabled? ? "enabled" : "disabled"}.")
|
|
475
|
+
when /\Astatus/
|
|
476
|
+
runtime_output(auto_compaction_status_line)
|
|
477
|
+
else
|
|
478
|
+
break
|
|
479
|
+
end
|
|
429
480
|
end
|
|
430
481
|
end
|
|
431
482
|
|
|
@@ -441,17 +492,21 @@ module Kward
|
|
|
441
492
|
Kward::Compaction::Settings.from_config(safely_read_config.to_h).enabled
|
|
442
493
|
end
|
|
443
494
|
|
|
444
|
-
def set_compaction_enabled(enabled)
|
|
445
|
-
update_nested_config("compaction", "enabled" => enabled)
|
|
446
|
-
end
|
|
447
|
-
|
|
448
495
|
def configure_personalization_settings(conversation)
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
496
|
+
initial_index = 0
|
|
497
|
+
loop do
|
|
498
|
+
selected, selected_index = select_settings_menu_item("Personalization", personalization_setting_choices(conversation), initial_index)
|
|
499
|
+
break unless selected
|
|
500
|
+
|
|
501
|
+
initial_index = selected_index if selected_index
|
|
502
|
+
case selected.to_s.downcase
|
|
503
|
+
when /\Adefault persona/
|
|
504
|
+
configure_default_persona(conversation)
|
|
505
|
+
when /\Aactive instructions/
|
|
506
|
+
show_active_instructions_summary(conversation)
|
|
507
|
+
else
|
|
508
|
+
break
|
|
509
|
+
end
|
|
455
510
|
end
|
|
456
511
|
end
|
|
457
512
|
|
|
@@ -500,12 +555,18 @@ module Kward
|
|
|
500
555
|
end
|
|
501
556
|
|
|
502
557
|
def configure_logging_settings
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
558
|
+
initial_index = 0
|
|
559
|
+
loop do
|
|
560
|
+
selected, selected_index = select_settings_menu_item("Logging", logging_setting_choices, initial_index)
|
|
561
|
+
break unless selected
|
|
562
|
+
|
|
563
|
+
initial_index = selected_index if selected_index
|
|
564
|
+
key = logging_key_for_choice(selected)
|
|
565
|
+
break unless key
|
|
506
566
|
|
|
507
|
-
|
|
508
|
-
|
|
567
|
+
set_logging_value(key, !logging_enabled?(key))
|
|
568
|
+
runtime_output("Logging #{key.tr("_", " ")} #{logging_enabled?(key) ? "enabled" : "disabled"}.")
|
|
569
|
+
end
|
|
509
570
|
end
|
|
510
571
|
|
|
511
572
|
def logging_setting_choices
|
|
@@ -536,7 +597,7 @@ module Kward
|
|
|
536
597
|
end
|
|
537
598
|
|
|
538
599
|
def set_logging_value(key, value)
|
|
539
|
-
|
|
600
|
+
set_config_flag("logging", key, value)
|
|
540
601
|
end
|
|
541
602
|
|
|
542
603
|
def show_advanced_settings
|
|
@@ -557,6 +618,15 @@ module Kward
|
|
|
557
618
|
ConfigFiles.update_nested_config(section, values)
|
|
558
619
|
end
|
|
559
620
|
|
|
621
|
+
def set_config_flag(section, key, enabled)
|
|
622
|
+
update_nested_config(section, key => enabled)
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
def select_settings_menu_item(message, choices, initial_index)
|
|
626
|
+
selected = @prompt.select(message, choices, title: "Settings", initial_index: initial_index)
|
|
627
|
+
[selected, choices.index(selected)]
|
|
628
|
+
end
|
|
629
|
+
|
|
560
630
|
def on_off(value)
|
|
561
631
|
value ? "on" : "off"
|
|
562
632
|
end
|
|
@@ -652,7 +722,13 @@ module Kward
|
|
|
652
722
|
end
|
|
653
723
|
|
|
654
724
|
def settings_overlay_available?
|
|
655
|
-
@prompt.respond_to?(:select)
|
|
725
|
+
@prompt.respond_to?(:select)
|
|
726
|
+
end
|
|
727
|
+
|
|
728
|
+
def update_overlay_settings(values)
|
|
729
|
+
settings = ConfigFiles.update_overlay_settings(values)
|
|
730
|
+
@prompt.update_overlay_settings(settings) if @prompt.respond_to?(:update_overlay_settings)
|
|
731
|
+
settings
|
|
656
732
|
end
|
|
657
733
|
|
|
658
734
|
def choose_overlay_setting(message, choices, values)
|
|
@@ -666,15 +742,13 @@ module Kward
|
|
|
666
742
|
current_provider = conversation.provider || (@client.respond_to?(:current_provider) ? @client.current_provider : "Codex")
|
|
667
743
|
current_model = conversation.model || (@client.respond_to?(:current_model) ? @client.current_model : nil)
|
|
668
744
|
current_reasoning = conversation.reasoning_effort || (@client.respond_to?(:current_reasoning_effort) ? @client.current_reasoning_effort : nil)
|
|
669
|
-
models = @client.respond_to?(:available_models) ?
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
)
|
|
677
|
-
end
|
|
745
|
+
models = @client.respond_to?(:available_models) ? @client.available_models : []
|
|
746
|
+
ModelInfo.normalize_available(
|
|
747
|
+
models,
|
|
748
|
+
current_provider: current_provider,
|
|
749
|
+
current_model: current_model,
|
|
750
|
+
current_reasoning_effort: current_reasoning
|
|
751
|
+
)
|
|
678
752
|
end
|
|
679
753
|
|
|
680
754
|
def model_choices(models, conversation = current_footer_conversation)
|