ollama_chat 0.0.113 β†’ 0.0.115

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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +120 -0
  3. data/README.md +7 -0
  4. data/bin/ollama_chat_log +1 -1
  5. data/bin/ollama_chat_send +3 -1
  6. data/lib/ollama_chat/chat.rb +30 -14
  7. data/lib/ollama_chat/commands.rb +36 -18
  8. data/lib/ollama_chat/compaction.rb +289 -0
  9. data/lib/ollama_chat/config_handling.rb +32 -0
  10. data/lib/ollama_chat/database/migrations/010_add_enabled_to_collections.rb +7 -0
  11. data/lib/ollama_chat/database/models/app_state.rb +48 -16
  12. data/lib/ollama_chat/database/models/session.rb +1 -2
  13. data/lib/ollama_chat/database.rb +4 -2
  14. data/lib/ollama_chat/information.rb +53 -6
  15. data/lib/ollama_chat/logging.rb +3 -2
  16. data/lib/ollama_chat/message.rb +22 -1
  17. data/lib/ollama_chat/message_format.rb +1 -2
  18. data/lib/ollama_chat/message_list.rb +223 -9
  19. data/lib/ollama_chat/model_handling.rb +1 -1
  20. data/lib/ollama_chat/oc.rb +17 -7
  21. data/lib/ollama_chat/ollama_chat_config/default_config.yml +72 -3
  22. data/lib/ollama_chat/parsing.rb +2 -1
  23. data/lib/ollama_chat/prompt_handling.rb +1 -1
  24. data/lib/ollama_chat/prompt_management.rb +1 -0
  25. data/lib/ollama_chat/rag_handling.rb +19 -5
  26. data/lib/ollama_chat/session_management.rb +5 -3
  27. data/lib/ollama_chat/token_estimator/crude.rb +1 -1
  28. data/lib/ollama_chat/token_estimator.rb +1 -1
  29. data/lib/ollama_chat/tools/concern.rb +17 -0
  30. data/lib/ollama_chat/tools/directory_structure.rb +11 -7
  31. data/lib/ollama_chat/tools/eval_ruby.rb +16 -6
  32. data/lib/ollama_chat/tools/execute_shell.rb +158 -0
  33. data/lib/ollama_chat/tools/get_rfc.rb +2 -0
  34. data/lib/ollama_chat/tools/lookup_group.rb +100 -0
  35. data/lib/ollama_chat/tools/paste_from_clipboard.rb +1 -1
  36. data/lib/ollama_chat/tools/patch_file.rb +23 -5
  37. data/lib/ollama_chat/tools/read_file.rb +1 -1
  38. data/lib/ollama_chat/tools/resolve_tag.rb +1 -1
  39. data/lib/ollama_chat/tools/search_knowledge.rb +7 -1
  40. data/lib/ollama_chat/tools/write_file.rb +25 -6
  41. data/lib/ollama_chat/tools.rb +2 -0
  42. data/lib/ollama_chat/utils/analyze_directory.rb +5 -4
  43. data/lib/ollama_chat/utils/fetcher.rb +1 -1
  44. data/lib/ollama_chat/utils/log_rotation.rb +29 -0
  45. data/lib/ollama_chat/utils/strip_ansi.rb +22 -0
  46. data/lib/ollama_chat/utils/tag_resolver.rb +3 -3
  47. data/lib/ollama_chat/utils.rb +2 -0
  48. data/lib/ollama_chat/version.rb +1 -1
  49. data/lib/ollama_chat.rb +7 -0
  50. data/ollama_chat.gemspec +5 -5
  51. data/spec/ollama_chat/commands_spec.rb +25 -0
  52. data/spec/ollama_chat/compaction_spec.rb +381 -0
  53. data/spec/ollama_chat/config_handling_spec.rb +60 -0
  54. data/spec/ollama_chat/message_list_spec.rb +229 -0
  55. data/spec/ollama_chat/message_spec.rb +143 -0
  56. data/spec/ollama_chat/rag_handling_spec.rb +3 -0
  57. data/spec/ollama_chat/system_prompt_management_spec.rb +0 -2
  58. data/spec/ollama_chat/tools/browse_spec.rb +7 -0
  59. data/spec/ollama_chat/tools/compute_bmi_spec.rb +15 -0
  60. data/spec/ollama_chat/tools/concern_spec.rb +77 -0
  61. data/spec/ollama_chat/tools/copy_to_clipboard_spec.rb +8 -0
  62. data/spec/ollama_chat/tools/delete_file_spec.rb +8 -0
  63. data/spec/ollama_chat/tools/directory_structure_spec.rb +4 -0
  64. data/spec/ollama_chat/tools/execute_grep_spec.rb +13 -0
  65. data/spec/ollama_chat/tools/execute_ri_spec.rb +8 -0
  66. data/spec/ollama_chat/tools/execute_shell_spec.rb +232 -0
  67. data/spec/ollama_chat/tools/file_context_spec.rb +5 -0
  68. data/spec/ollama_chat/tools/gem_path_lookup_spec.rb +2 -0
  69. data/spec/ollama_chat/tools/generate_image_spec.rb +12 -0
  70. data/spec/ollama_chat/tools/generate_password_spec.rb +5 -0
  71. data/spec/ollama_chat/tools/get_cve_spec.rb +4 -0
  72. data/spec/ollama_chat/tools/get_endoflife_spec.rb +4 -0
  73. data/spec/ollama_chat/tools/get_ghr_spec.rb +6 -0
  74. data/spec/ollama_chat/tools/get_location_spec.rb +4 -0
  75. data/spec/ollama_chat/tools/get_rfc_spec.rb +2 -0
  76. data/spec/ollama_chat/tools/get_time_spec.rb +2 -0
  77. data/spec/ollama_chat/tools/get_url_spec.rb +7 -0
  78. data/spec/ollama_chat/tools/lookup_group_spec.rb +111 -0
  79. data/spec/ollama_chat/tools/move_file_spec.rb +10 -0
  80. data/spec/ollama_chat/tools/open_file_in_editor_spec.rb +6 -0
  81. data/spec/ollama_chat/tools/paste_from_clipboard_spec.rb +5 -0
  82. data/spec/ollama_chat/tools/paste_into_editor_spec.rb +6 -0
  83. data/spec/ollama_chat/tools/patch_file_spec.rb +62 -0
  84. data/spec/ollama_chat/tools/read_file_spec.rb +10 -3
  85. data/spec/ollama_chat/tools/resolve_tag_spec.rb +46 -0
  86. data/spec/ollama_chat/tools/roll_dice_spec.rb +11 -0
  87. data/spec/ollama_chat/tools/run_tests_spec.rb +8 -0
  88. data/spec/ollama_chat/tools/search_knowledge_spec.rb +2 -0
  89. data/spec/ollama_chat/tools/write_file_spec.rb +98 -2
  90. data/spec/ollama_chat/utils/analyze_directory_spec.rb +46 -7
  91. data/spec/ollama_chat/utils/log_rotation_spec.rb +71 -0
  92. data/spec/spec_helper.rb +2 -1
  93. metadata +25 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e618b797bf1b5fa84728816e06b83fe3540424b48256ba107deb29c2beb8a219
4
- data.tar.gz: f5abee2701f3fc6d7ba09513f0b0bd5133c7ec10ddb511ee5ea4238c14f9988e
3
+ metadata.gz: 18297e3bbf39619c1721b30fdf4f691a2a71b1e15994c2ae28ced14eb7f76c57
4
+ data.tar.gz: 1481131a053ef2d9390456c84e9d58bf0890d1ded23eafb5d15c4b1b70babb99
5
5
  SHA512:
6
- metadata.gz: 2f2172cc90da0a8b8c1b7f2306abbc8480db92abeb3629e20b2471e88fdd79ca2d18c209c05690167b564b6911685222dce48496e9825330e43500ff520aab74
7
- data.tar.gz: da6e5e8583b11cb7d766ff0745e97070f2a39ac8f1ca6314a4bcb93d8e9a6c3ec9ef087a055b7c9844317f831fc4a6a590e11f80eaf6b6c80980143ab8385771
6
+ metadata.gz: 6ec5d58d329bb3b8a25ccdb0ce55cb04be29f5e8b22e2b3f7aa8ce77bfe49cf56d33c6c198c63431b4ccca9e78029887fe221be1effa5306d4aef464fe530fd9
7
+ data.tar.gz: ec410eb4d78a5688cb4b67bec44a3600a8e295578bb9375142957577b92d03c5ae0ada7f0e4f7841b70ed40c9dea8e6f1acc688d76abc6ba4d156c550cbf3324
data/CHANGES.md CHANGED
@@ -1,5 +1,125 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-09-01 v0.0.115
4
+
5
+ * Added `OllamaChat::Tools::ExecuteShell` in
6
+ `lib/ollama_chat/tools/execute_shell.rb`, which executes shell commands via
7
+ `sh -c` after a mandatory human review flow involving an `edit_text` editor
8
+ review and a `y/n/i` confirm prompt.
9
+ * Implemented a `y/n/i` gate in the `execute_shell` tool where `y` executes,
10
+ `n` cancels, and `i` captures user instructions for the LLM to revise the
11
+ command.
12
+ * Configured `require_confirmation: false` in `default_config.yml` to skip
13
+ the preflight confirm in `follow_chat`, relying on the in-tool `confirm?`
14
+ as the primary safety mechanism.
15
+ * Enabled output display via `use_pager` with bold `stdout:`/`stderr:` labels
16
+ and exit codes, with `monochrome: true` (default) stripping ANSI codes
17
+ before returning results to the LLM.
18
+ * Standardized error handling for `execute_shell` failure paths (blank
19
+ command, editor abandoned/cleared, user declined, instruct) to raise
20
+ `OllamaChat::ToolFunctionArgumentError`, which is rescued to log and return
21
+ structured JSON including the `command`.
22
+ * Added a `summary_template` class method to `execute_shell` for one-liner
23
+ output in `lookup_group` compaction.
24
+ * Registered `execute_shell` in `lib/ollama_chat/tools.rb` and configured it
25
+ in `default_config.yml` with `default: false` and `result_display_timeout:
26
+ 10`.
27
+ * Added 18 spec examples in `spec/ollama_chat/tools/execute_shell_spec.rb`
28
+ covering identity, execution, editor cancel, instruct, monochrome, pager
29
+ display, and `summary_template`.
30
+ * Introduced `OllamaChat::Utils::StripANSI` module in
31
+ `lib/ollama_chat/utils/strip_ansi.rb` with a regex-based `strip_ansi`
32
+ method handling both SGR and OSC escape sequences.
33
+ * Replaced `Term::ANSIColor.uncolor` calls with `strip_ansi` in
34
+ `lib/ollama_chat/tools/execute_shell.rb`, `lib/ollama_chat/commands.rb`
35
+ (`/input` path and default subcommands), and `bin/ollama_chat_send`.
36
+ * Registered `lib/ollama_chat/utils/strip_ansi.rb` in `ollama_chat.gemspec`
37
+ file lists.
38
+ * Fixed `read_file` and `write_file` spec assertions in `read_file_spec.rb`
39
+ and `write_file_spec.rb` to match the token-first output format (`tokens
40
+ (bytes)`) shipped in **v0.0.114**.
41
+
42
+ ## 2026-09-01 v0.0.114
43
+
44
+ ### Added
45
+
46
+ * Context compaction pipeline:
47
+ * `OllamaChat::Compaction` module with `summarize_for_compaction`,
48
+ `compact_with_retry`, `compact_ratio_tokens`, `tool_summary_line`, and
49
+ `Result` value object.
50
+ * `CompactionError` exception.
51
+ * `MessageList` methods: `compact!`, `find_cut_point`, `find_summary`,
52
+ `compacted_messages`, `compacted_estimate_tokens`, and
53
+ `full_estimate_tokens`.
54
+ * `lookup_group` tool for retrieving pre-summary group content by UUID
55
+ suffix.
56
+ * `summary_template` base method in `Tools::Concern` and `message` field in
57
+ `eval_ruby` and `get_rfc` results.
58
+ * `compaction:` configuration block (`enabled`, `reserve`, `keep_recent`) and
59
+ `prompts.compaction` templates in `default_config.yml`.
60
+ * `conversation_length` in `Information` and dynamic runtime values.
61
+ * Per-message token estimation:
62
+ * `#token_estimate(strip_thinking:)` in `OllamaChat::MessageMixin`.
63
+ * `#total_tokens(strip_thinking:)` in `OllamaChat::MessageList`.
64
+ * Color-coded context gauge:
65
+ * `context_gauge` method in `information.rb` displaying context usage with
66
+ ANSI colors and emoji indicators.
67
+ * Configurable syntax checkers for file tools:
68
+ * `syntax_checkers:` block in `default_config.yml` for `ruby`, `javascript`,
69
+ `python`, and `shell`.
70
+ * `ConfigHandling#syntax_checker_for` and `ConfigHandling#run_syntax_check`
71
+ methods.
72
+ * Integration into `Tools::WriteFile#execute` and `Tools::PatchFile#execute`.
73
+ * Log rotation and restructured log configuration:
74
+ * `LOG` module (`CHAT`, `DATABASE`, `TAIL_LINES`) in `oc.rb`.
75
+ * `OllamaChat::Utils::LogRotation.truncate_tail` for in-place log truncation.
76
+ * `truncate_logs` call in `OllamaChat::Chat#initialize`.
77
+ * Database `Logger` level set to `WARN`.
78
+ * Enabled flag for RAG collections:
79
+ * Migration adding `enabled` boolean to `collections` table.
80
+ * Filtering of disabled collections in `information.rb` and
81
+ `search_knowledge`.
82
+ * Interactive toggle in `edit_collection` and `[DISABLED]` suffix in
83
+ `list_collections`.
84
+ * Monochrome flags:
85
+ * `-m` flag for `bin/ollama_chat_send` to strip ANSI codes from stdin.
86
+ * `-m` flag for `/input` command to strip ANSI codes from file content and
87
+ import results.
88
+ * Session synchronization:
89
+ * `session_sync` method extracted from `session_close` in
90
+ `session_management.rb`.
91
+ * `ensure session.lock` in `set_new_session`.
92
+
93
+ ### Changed
94
+
95
+ * Increased `compaction.reserve.ratio` from **0.30** to **0.60** in
96
+ `default_config.yml`.
97
+ * Switched `Struct.new` to `Data.define` in `ModelMetadata`, `Estimate`, and
98
+ `TagResult`.
99
+ * Standardized user-facing output format to `tokens (bytes)` across
100
+ `read_file`, `write_file`, `session_management`, and `information`.
101
+ * Replaced `.size` with `.bytesize` for multi-byte-safe byte counts in
102
+ `token_estimator/crude.rb`, `fetcher.rb`, `paste_from_clipboard.rb`, and
103
+ `prompt_handling.rb`.
104
+ * Updated `/conversation compact` to delegate to `compact_with_retry`.
105
+ * Threaded `chat` into `TagResolver` for logging, fixing `NoMethodError` in
106
+ rescue blocks.
107
+ * Capped inline directory structure depth:
108
+ * Added `parsing.directory_structure_max_depth` (default **1**) to
109
+ `default_config.yml`.
110
+ * Shifted `max_depth` semantics: **1** = immediate children, **2** = children
111
+ + grandchildren, `nil` = unlimited.
112
+ * Acknowledged prompt state after `/prompt sync` to suppress boot drift nag.
113
+ * Reordered `session_title` prompt for reliability.
114
+ * `/config diff` now calls `reload_config` after `diff_config`.
115
+ * Reordered `/config` subcommand alternatives to `edit diff reload`.
116
+ * Clarified `suffix` description in `directory_structure` as "file extension".
117
+
118
+ ### Fixed
119
+
120
+ * `NoMethodError` in `TagResolver#resolve` rescue block.
121
+ * Unbounded tree expansion in directory structure parsing.
122
+
3
123
  ## 2026-08-25 v0.0.113
4
124
 
5
125
  * Simplified hash syntax by replacing `text: text` with `text:` etc.
data/README.md CHANGED
@@ -37,6 +37,9 @@ The following environment variables can be used to configure behavior:
37
37
  - `OLLAMA_CHAT_HISTORY` - Chat history filename
38
38
  - `OLLAMA_CHAT_USER` - Full name of the chat user
39
39
  - `OLLAMA_CHAT_DEBUG` - Debug mode toggle (1 = enabled)
40
+ - `OLLAMA_CHAT_LOG_CHAT` - Chat log file path (default: `$XDG_STATE_HOME/chat.log`)
41
+ - `OLLAMA_CHAT_LOG_DATABASE` - Database log file path (default: `$XDG_STATE_HOME/database.log`)
42
+ - `OLLAMA_CHAT_LOG_TAIL_LINES` - Max lines to retain in log files (default: `10000`)
40
43
 
41
44
  #### Tool Configuration
42
45
  - `OLLAMA_CHAT_TOOLS_TEST_RUNNER` - Configured test runner for `run_tests` (default: `rspec`)
@@ -45,11 +48,14 @@ The following environment variables can be used to configure behavior:
45
48
  - `OLLAMA_CHAT_TOOLS_JIRA_URL` - Base URL for Jira instance
46
49
  - `OLLAMA_CHAT_TOOLS_JIRA_USER` - Username for Jira authentication
47
50
  - `OLLAMA_CHAT_TOOLS_JIRA_API_TOKEN` - API token for Jira authentication
51
+ - `OLLAMA_CHAT_TOOLS_JIRA_TWG` - Path to the twg CLI binary
48
52
  - `OLLAMA_CHAT_TOOLS_IMAGE_GENERATOR_URL` - Base URL for ComfyUI server
49
53
  - `OLLAMA_CHAT_TOOLS_IMAGE_GENERATOR_WORKFLOW` - ComfyUI workflow as JSON string
50
54
  - `OLLAMA_CHAT_TOOLS_IMAGE_GENERATOR_PROMPT_NODE_ID` - Prompt node ID
51
55
  - `OLLAMA_CHAT_TOOLS_IMAGE_GENERATOR_FILENAME_PREFIX_NODE_ID` - Filename prefix node ID
52
56
  - `OLLAMA_CHAT_TOOLS_PIRATEWEATHER_API_KEY` - Pirate Weather API key
57
+ - `OLLAMA_CHAT_TOOLS_GHR_URL` - Base URL for GHR API server
58
+ - `OLLAMA_CHAT_TOOLS_RUBY_EVAL_IMAGE_TEMPLATE` - Docker image template for `eval_ruby` (default: `ruby:%{version}-alpine`)
53
59
 
54
60
  #### System & Infrastructure
55
61
  - `XDG_CONFIG_HOME` - XDG Configuration home directory
@@ -59,6 +65,7 @@ The following environment variables can be used to configure behavior:
59
65
  - `EDITOR` - Default text editor
60
66
  - `BROWSER` - Default web browser
61
67
  - `DIFF_TOOL` - Tool for diff operations (default: `vimdiff`)
68
+ - `DIFF_COMMAND` - Command to generate unified diffs (default: `diff -u --color=always`)
62
69
  - `KRAMDOWN_ANSI_OLLAMA_CHAT_STYLES` - Custom ANSI styles for Markdown formatting
63
70
  - `KRAMDOWN_ANSI_STYLES` - Fallback ANSI styles configuration
64
71
  - `OLLAMA_REDIS_URL` - Redis connection URL for documents (documentrix)
data/bin/ollama_chat_log CHANGED
@@ -5,7 +5,7 @@ require 'file/tail'
5
5
  require 'tins/xt'
6
6
 
7
7
  opts = Tins::GO.go 'fm:n:h:', defaults: { ?n => 10 }
8
- log_path = ARGV.shift || OC::OLLAMA::CHAT::LOGFILE
8
+ log_path = ARGV.shift || OC::OLLAMA::CHAT::LOG::CHAT
9
9
 
10
10
  if opts[?h]
11
11
  puts <<~EOT
data/bin/ollama_chat_send CHANGED
@@ -5,7 +5,7 @@ include OllamaChat::FileEditing
5
5
  require 'tins/go'
6
6
  include Tins::GO
7
7
 
8
- opts = go 'f:d:F:rteph', ARGV
8
+ opts = go 'f:d:F:rtemph', ARGV
9
9
 
10
10
  # Displays the usage information for the ollama_chat_send command.
11
11
  #
@@ -25,6 +25,7 @@ def usage(rc = 0)
25
25
  -f CONFIG file to read
26
26
  -d DIR the working directory to derive the socket file from
27
27
  -e Edit content in editor before sending
28
+ -m Strip ANSI color codes from content before sending
28
29
  -F FORMAT file extension for editor (e.g., rb, md)
29
30
  -h Show this help message
30
31
 
@@ -42,6 +43,7 @@ begin
42
43
  opts[?r] ? :socket_input_with_response : :socket_input
43
44
  end
44
45
  content = STDIN.read
46
+ content = OllamaChat::Utils::StripANSI.strip_ansi(content) if opts[?m]
45
47
  if opts[?e]
46
48
  basename = %w[ text ]
47
49
  basename << opts[?F]&.sub(/\A(?=[^.])/, ?.) || '.md'
@@ -69,6 +69,7 @@ class OllamaChat::Chat
69
69
  include OllamaChat::PromptHandling
70
70
  include OllamaChat::SystemPromptManagement
71
71
  include OllamaChat::PromptManagement
72
+ include OllamaChat::Compaction
72
73
  include OllamaChat::Utils::Chooser
73
74
  include OllamaChat::Utils::ValueFormatter
74
75
  include OllamaChat::Utils::UTF8Converter
@@ -106,10 +107,11 @@ class OllamaChat::Chat
106
107
  @opts[?V] and exit version
107
108
  @ollama_chat_config = OllamaChat::OllamaChatConfig.new(@opts[?f])
108
109
  self.config = @ollama_chat_config.config
110
+ truncate_logs
109
111
  @messages = OllamaChat::MessageList.new(self)
110
112
  OllamaChat::Database.setup_models.each { _1.ask_and_send(:seed, self) }
111
- setup_session
112
113
  setup_switches
114
+ setup_session
113
115
  setup_state_selectors(config)
114
116
  connect_ollama
115
117
  @documents = setup_documents
@@ -254,12 +256,14 @@ class OllamaChat::Chat
254
256
  # and a user message, executing it as a one-shot chat interaction.
255
257
  #
256
258
  # @param system [String] the system prompt to guide the model's behavior
257
- # (defaults to current raw_system_prompt)
258
- #
259
+ # (defaults to current raw_system_prompt)
259
260
  # @param prompt [String] the user prompt to send to the model
261
+ # @param stream [Boolean] whether to stream the response (default: false)
262
+ # @param think [Boolean] enable thinking mode for hybrid-thinking models
263
+ # (default: false)
260
264
  #
261
265
  # @return [String] the content of the resulting response message
262
- def generate(system: raw_system_prompt, prompt:)
266
+ def generate(system: raw_system_prompt, prompt:, stream: false, think: false)
263
267
  messages = [
264
268
  OllamaChat::Message.new(
265
269
  role: 'system',
@@ -276,9 +280,8 @@ class OllamaChat::Chat
276
280
  model: @model,
277
281
  messages: ,
278
282
  options: model_options,
279
- stream: false,
280
- think: false,
281
- tools:
283
+ stream: ,
284
+ think:
282
285
  )&.message&.content.to_s
283
286
 
284
287
  if content.empty?
@@ -315,6 +318,18 @@ class OllamaChat::Chat
315
318
  ollama.chat(**opts, &block)
316
319
  end
317
320
 
321
+ # Truncates chat.log and database.log to the configured tail line count
322
+ # before any new logging begins for this session.
323
+ def truncate_logs
324
+ keep = OC::OLLAMA::CHAT::LOG::TAIL_LINES
325
+ OllamaChat::Utils::LogRotation.truncate_tail(
326
+ OC::OLLAMA::CHAT::LOG::CHAT, keep_lines: keep
327
+ )
328
+ OllamaChat::Utils::LogRotation.truncate_tail(
329
+ OC::OLLAMA::CHAT::LOG::DATABASE, keep_lines: keep
330
+ )
331
+ end
332
+
318
333
  # @return [Module] The module containing the database models.
319
334
  def models
320
335
  OllamaChat::Database::Models
@@ -532,14 +547,15 @@ class OllamaChat::Chat
532
547
  )
533
548
  begin
534
549
  retried = false
535
- sent_messages = messages.to_ary
536
- if think_strip.on?
537
- sent_messages = sent_messages.map {
538
- _1.dup.tap { |message|
539
- message.thinking = nil
540
- }
550
+ sent_messages = messages.compacted_messages
551
+ sent_messages = sent_messages.map {
552
+ _1.dup.tap { |message|
553
+ message.sender_name = nil
554
+ message.group_uuid = nil
555
+ message.tool_calls = nil
556
+ message.thinking = nil if think_strip.on?
541
557
  }
542
- end
558
+ }
543
559
  prepare_model(@model)
544
560
  call_ollama_chat(
545
561
  model: @model,
@@ -62,8 +62,8 @@ module OllamaChat::Commands
62
62
 
63
63
  command(
64
64
  name: :config,
65
- regexp: %r(^/config(?:\s+(edit|reload|diff))?$),
66
- complete: [ 'config', %w[ edit reload diff ] ],
65
+ regexp: %r(^/config(?:\s+(edit|diff|reload))?$),
66
+ complete: [ 'config', %w[ edit diff reload ] ],
67
67
  optional: true,
68
68
  help: <<~EOT
69
69
  \u2699\uFE0F View, edit, diff, or reload configuration
@@ -72,11 +72,11 @@ module OllamaChat::Commands
72
72
  case subcommand
73
73
  when 'edit'
74
74
  edit_config
75
- when 'reload'
76
- reload_config
77
75
  when 'diff'
78
76
  diff_config
79
77
  reload_config
78
+ when 'reload'
79
+ reload_config
80
80
  else
81
81
  display_config
82
82
  end
@@ -598,14 +598,15 @@ module OllamaChat::Commands
598
598
 
599
599
  command(
600
600
  name: :conversation,
601
- regexp: %r(^/conversation\s+(clean|save|load)(\s+-c)?(?:\s+([^-].*\.jsonl?))?$),
602
- complete: [ 'conversation', %w[ save load clean ] ],
601
+ regexp: %r(^/conversation\s+(clean|compact|save|load)(\s+-c)?(?:\s+([^-].*\.jsonl?))?$),
602
+ complete: [ 'conversation', %w[ save load clean compact ] ],
603
603
  options: '[-c] [FILENAME]',
604
604
  help: <<~EOT
605
605
  πŸ’Ύ Save/Load conversation state
606
606
  (-c to clean before saving)
607
607
  FILENAME ends with .json or .jsonl
608
608
  Or clean inplace (removes tool content, images, and thinking)
609
+ Or compact (summarize old messages, keep recent)
609
610
  EOT
610
611
  ) do |subcommand,opts,path|
611
612
  if %w[ save load ].include?(subcommand) && path.blank?
@@ -631,6 +632,16 @@ module OllamaChat::Commands
631
632
  else
632
633
  STDOUT.puts 'Cancelled.'
633
634
  end
635
+ when 'compact'
636
+ if confirm?(
637
+ prompt: 'πŸ”” Compact conversation? Old messages will be summarized. (y/n) ',
638
+ yes: /\Ay/i
639
+ )
640
+ then
641
+ compact_with_retry
642
+ else
643
+ STDOUT.puts 'Cancelled.'
644
+ end
634
645
  end
635
646
  :next
636
647
  end
@@ -836,22 +847,23 @@ module OllamaChat::Commands
836
847
 
837
848
  command(
838
849
  name: :input,
839
- regexp: %r(^/input(?:\s+(path|context|embedding|summary)(?:\s*(?=\z))?)?((?:\s+-(?:[apre]|c\s*#{OllamaChat::COLLECTION_NAME_REGEXP.source}|w\s*\d+|t\s*[-\w\.]+(?:,[-\w\.]+)*))*)(?:\s+([^-].*))?$),
850
+ regexp: %r(^/input(?:\s+(path|context|embedding|summary)(?:\s*(?=\z))?)?((?:\s+-(?:[aprem]|c\s*#{OllamaChat::COLLECTION_NAME_REGEXP.source}|w\s*\d+|t\s*[-\w\.]+(?:,[-\w\.]+)*))*)(?:\s+([^-].*))?$),
840
851
  optional: true,
841
852
  complete: [ 'input', %w[ path context embedding summary ] ],
842
853
  options: <<~EOT,
843
- [
844
- -w|-a|-p|-e|
845
- -c <collection>|
846
- -t <tags>
847
- ]
854
+ [
855
+ -w|-a|-p|-e|-m|
856
+ -c <collection>|
857
+ -t <tags>
858
+ ]
848
859
  [arg…]
849
860
  EOT
850
861
  help: <<~EOT
851
862
  πŸ“₯ Import content (read, summarize, embed, context)
852
863
  Subcommands: path, context, embedding, summary
853
- Options: -p (pattern), -w [words], -a (all),
854
- -c [collection], -t [tags], -e (edit)
864
+ Options: -p (pattern), -w [words], -a (all),
865
+ -c [collection], -t [tags], -e (edit),
866
+ -m (monochrome, strip ANSI from file content)
855
867
  EOT
856
868
  ) do |input_mode,opts,arg|
857
869
  disable_content_parsing
@@ -907,19 +919,21 @@ module OllamaChat::Commands
907
919
  end
908
920
  end
909
921
  when 'path'
910
- opts = go_command('pae', opts)
922
+ opts = go_command('paem', opts)
911
923
  if opts[?p]
912
924
  all = opts.fetch(?a, false)
913
925
  patterns = extract_patterns(arg)
914
926
  read = -> pathname {
915
927
  STDOUT.puts "Reading #{pathname.to_s.inspect}."
916
- pathname.read
928
+ content = pathname.read
929
+ opts[?m] ? OllamaChat::Utils::StripANSI.strip_ansi(content) : content
917
930
  }
918
931
  next provide_file_set_content(patterns, all:, &read) || :next
919
932
  elsif arg
920
933
  filename = Pathname.new(arg).expand_path
921
934
  filename.file? or next :next
922
935
  content = filename.read
936
+ content = OllamaChat::Utils::StripANSI.strip_ansi(content) if opts[?m]
923
937
  content = edit_text(content) if opts[?e]
924
938
  content
925
939
  else
@@ -927,14 +941,18 @@ module OllamaChat::Commands
927
941
  next :next
928
942
  end
929
943
  else
930
- opts = go_command('pae', opts)
944
+ opts = go_command('paem', opts)
931
945
  if opts[?p]
932
946
  all = opts.fetch(?a, false)
933
947
  patterns = extract_patterns(arg)
934
- next provide_file_set_content(patterns, all:, skip_blank: true) { import(_1) } || :next
948
+ next provide_file_set_content(patterns, all:, skip_blank: true) do |src|
949
+ content = import(src)
950
+ opts[?m] ? OllamaChat::Utils::StripANSI.strip_ansi(content) : content
951
+ end || :next
935
952
  elsif arg
936
953
  source = arg
937
954
  content = import(source) or next :next
955
+ content = OllamaChat::Utils::StripANSI.strip_ansi(content) if opts[?m]
938
956
  content = edit_text(content) if opts[?e]
939
957
  content
940
958
  else