ollama_chat 0.0.99 → 0.0.100

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +71 -0
  3. data/Rakefile +2 -2
  4. data/lib/ollama_chat/chat.rb +51 -26
  5. data/lib/ollama_chat/commands.rb +163 -210
  6. data/lib/ollama_chat/database/migrations/006_rename_system_prompt_context_to_system.rb +13 -0
  7. data/lib/ollama_chat/database/models/prompt.rb +14 -23
  8. data/lib/ollama_chat/dialog.rb +1 -1
  9. data/lib/ollama_chat/document_cache.rb +5 -1
  10. data/lib/ollama_chat/favourites_management.rb +2 -5
  11. data/lib/ollama_chat/follow_chat.rb +15 -14
  12. data/lib/ollama_chat/information.rb +17 -4
  13. data/lib/ollama_chat/logging.rb +24 -6
  14. data/lib/ollama_chat/message.rb +27 -6
  15. data/lib/ollama_chat/message_list.rb +30 -9
  16. data/lib/ollama_chat/model_handling.rb +51 -33
  17. data/lib/ollama_chat/ollama_chat_config/default_config.yml +318 -314
  18. data/lib/ollama_chat/parsing.rb +22 -6
  19. data/lib/ollama_chat/personae_management.rb +22 -9
  20. data/lib/ollama_chat/prompt_handling.rb +18 -56
  21. data/lib/ollama_chat/prompt_management.rb +87 -71
  22. data/lib/ollama_chat/session_management.rb +65 -14
  23. data/lib/ollama_chat/source_fetching.rb +2 -1
  24. data/lib/ollama_chat/system_prompt_management.rb +4 -246
  25. data/lib/ollama_chat/tools/browse.rb +4 -2
  26. data/lib/ollama_chat/tools/compute_bmi.rb +1 -0
  27. data/lib/ollama_chat/tools/copy_to_clipboard.rb +3 -2
  28. data/lib/ollama_chat/tools/delete_file.rb +3 -1
  29. data/lib/ollama_chat/tools/directory_structure.rb +5 -1
  30. data/lib/ollama_chat/tools/eval_ruby.rb +7 -2
  31. data/lib/ollama_chat/tools/execute_grep.rb +3 -1
  32. data/lib/ollama_chat/tools/execute_ri.rb +2 -0
  33. data/lib/ollama_chat/tools/file_context.rb +1 -0
  34. data/lib/ollama_chat/tools/gem_path_lookup.rb +8 -6
  35. data/lib/ollama_chat/tools/generate_image.rb +1 -0
  36. data/lib/ollama_chat/tools/generate_password.rb +13 -2
  37. data/lib/ollama_chat/tools/get_current_weather.rb +1 -0
  38. data/lib/ollama_chat/tools/get_cve.rb +1 -0
  39. data/lib/ollama_chat/tools/get_endoflife.rb +1 -0
  40. data/lib/ollama_chat/tools/get_ghr.rb +1 -0
  41. data/lib/ollama_chat/tools/get_jira_issue.rb +2 -0
  42. data/lib/ollama_chat/tools/get_location.rb +3 -0
  43. data/lib/ollama_chat/tools/get_rfc.rb +1 -0
  44. data/lib/ollama_chat/tools/get_time.rb +5 -1
  45. data/lib/ollama_chat/tools/get_url.rb +1 -0
  46. data/lib/ollama_chat/tools/move_file.rb +3 -1
  47. data/lib/ollama_chat/tools/open_file_in_editor.rb +4 -0
  48. data/lib/ollama_chat/tools/paste_from_clipboard.rb +1 -0
  49. data/lib/ollama_chat/tools/paste_into_editor.rb +7 -13
  50. data/lib/ollama_chat/tools/patch_file.rb +163 -39
  51. data/lib/ollama_chat/tools/read_file.rb +51 -39
  52. data/lib/ollama_chat/tools/resolve_tag.rb +3 -1
  53. data/lib/ollama_chat/tools/retrieve_document_snippets.rb +2 -1
  54. data/lib/ollama_chat/tools/roll_dice.rb +1 -0
  55. data/lib/ollama_chat/tools/run_tests.rb +3 -1
  56. data/lib/ollama_chat/tools/search_web.rb +1 -0
  57. data/lib/ollama_chat/tools/write_file.rb +3 -1
  58. data/lib/ollama_chat/utils/tag_resolver.rb +1 -1
  59. data/lib/ollama_chat/uuid_v7.rb +33 -0
  60. data/lib/ollama_chat/version.rb +1 -1
  61. data/lib/ollama_chat.rb +9 -0
  62. data/ollama_chat.gemspec +8 -8
  63. data/spec/assets/example.epub +0 -0
  64. data/spec/ollama_chat/chat_spec.rb +2 -2
  65. data/spec/ollama_chat/follow_chat_spec.rb +6 -2
  66. data/spec/ollama_chat/message_list_spec.rb +85 -29
  67. data/spec/ollama_chat/parsing_spec.rb +11 -2
  68. data/spec/ollama_chat/session_management_spec.rb +324 -0
  69. data/spec/ollama_chat/source_fetching_spec.rb +26 -0
  70. data/spec/ollama_chat/tools/directory_structure_spec.rb +1 -1
  71. data/spec/ollama_chat/tools/execute_ri_spec.rb +3 -3
  72. data/spec/ollama_chat/tools/gem_path_lookup_spec.rb +8 -2
  73. data/spec/ollama_chat/tools/get_jira_issue_spec.rb +3 -3
  74. data/spec/ollama_chat/tools/paste_into_editor_spec.rb +1 -35
  75. data/spec/ollama_chat/tools/patch_file_spec.rb +121 -87
  76. data/spec/ollama_chat/tools/read_file_spec.rb +76 -0
  77. data/spec/ollama_chat/tools/resolve_tag_spec.rb +2 -2
  78. data/spec/ollama_chat/tools/write_file_spec.rb +15 -11
  79. metadata +13 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0818076703ebd6e8d8babbe5898a6a0069863ce7cebf18658f70e8d4b5592c51'
4
- data.tar.gz: 7e9f768d41bff3560c2d22ac20ace84da0b580b3b17f8f9d1ffd3522af5d8db1
3
+ metadata.gz: 436406ccfaa267c8996e6986759b3f79773ad8b48127ed8b7f7bd749b8c82dd1
4
+ data.tar.gz: f2a66b87ebc221adf19e382568979f57baabfabef49929e123bbe0cc1932916d
5
5
  SHA512:
6
- metadata.gz: 4864950b3246106793b51ffe74e3ead6dad4683f1b9fcaf710bf7f672264c646dc90dacdbcef437725b725230b8d0b70938045729ca982c83845ebce41bb773d
7
- data.tar.gz: 5b99426668efc34bbb89a17faf2dcf016c1a6ada4c69d44882ebb40bcb836907741f96b5fb66ee99ea75b78abbdd34069ddbc186d525acd015302bcea95e55a7
6
+ metadata.gz: 576fc144f38595bec62043b30c170dc65a2bb891df41ab36bdd1b4bef2ad32dbe0b72b413d0e0f785604c0c0e3add5ca847e6da25144011518d67241b7fb8771
7
+ data.tar.gz: e3c808321e651a55bdf29326d41150700bcd2c8b28d4b2b407c49fdd6aff156e4e4d8555eafb1cf10c46589e44963714dafea95f667305c4173e788cd514da7f
data/CHANGES.md CHANGED
@@ -1,5 +1,76 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-07-23 v0.0.100
4
+
5
+ ### New Features
6
+
7
+ - **UUID v7 Integration**: Implemented a compatibility shim via
8
+ `OllamaChat::UUIDV7.generate` that utilizes native `SecureRandom.uuid_v7` for
9
+ Ruby **3.3**+ and a custom RFC 9562 compliant implementation for older
10
+ versions.
11
+ - **Document Parsing & Embeddings**:
12
+ - Added EPUB support using `pandoc` via the `epub_read` method and updated
13
+ `parse_source` to handle `application/epub+zip`.
14
+ - Enhanced retrieval precision by prepending source identifiers to document
15
+ chunks in `embed_source`.
16
+ - **Structured Logging**: Implemented a JSON formatter in `OllamaChat::Logging`
17
+ with a `data:` keyword argument for structured context, including separate
18
+ capture of backtraces and tool execution details.
19
+ - **Prompt Management Refactor**:
20
+ - Unified prompt API using a `context:` keyword argument across `prompt`,
21
+ `each_prompt`, `delete_prompt`, `store_prompt`, and `write_prompt`.
22
+ - Introduced dynamic context parameters (defaulting to `'prompt'`) and
23
+ restructured `default_config.yml` to nest prompts under `prompt:`,
24
+ `suggest:`, and `system:`.
25
+ - Promoted `/suggest` to a top-level command and simplified the `/system`
26
+ command.
27
+ - **Conversation Grouping**: Introduced `group_uuid` in `OllamaChat::Message`
28
+ to enable conversation grouping, including a `repair_group_uuids` method in
29
+ `OllamaChat::SessionManagement` for legacy data migration.
30
+ - **Tool Enhancements**:
31
+ - **`read_file`**: Added support for line numbering via the `line_numbers`
32
+ parameter and range extraction using `start_line` and `end_line`. Now
33
+ returns total `line_count` and file `mtime` in ISO8601 format.
34
+ - **`patch_file`**: Refactored to support coordinate-based patching via an
35
+ `edits` parameter for targeted line-range replacements, including overlap
36
+ detection and freshness checks using `mtime`.
37
+ - **`generate_password`**: Added `base64url` alphabet support and critical
38
+ security warnings to discourage the use of `eval_ruby` for secret
39
+ generation.
40
+
41
+ ### Improvements & Refactoring
42
+
43
+ - **CLI & UX**:
44
+ - Refactored command help strings with emoji prefixes and a more concise,
45
+ scannable multi-line format using heredocs.
46
+ - Added a welcome message upon startup displaying the version, connected
47
+ server version, and URL via `print_welcome`.
48
+ - Standardized the creation workflow for prompts and personae with a source
49
+ selection menu (`[CLIPBOARD]`, `[FILES]`, `[EMPTY/MANUAL]`).
50
+ - **Application Flow**:
51
+ - Implemented `OllamaChatQuitError` to handle graceful application
52
+ shutdowns via exception-based control flow.
53
+ - Added a `[QUIT-APP]` option to the session chooser after deletion.
54
+ - **Internal Logic**:
55
+ - Optimized `ps_read` by replacing manual read loops with `IO.copy_stream`.
56
+ - Centralized Ollama chat request logging through a new `call_ollama_chat`
57
+ wrapper.
58
+ - Refactored model option reconfiguration into a dedicated
59
+ `reconfigure_model_options` method in
60
+ `lib/ollama_chat/model_handling.rb`.
61
+ - Updated dependencies: `ollama-ruby` to **1.23** and `tins` to **1.54**.
62
+
63
+ ### Bug Fixes & Stability
64
+
65
+ - Added error logging (`chat.log(:error, e)`) to the `rescue` blocks of all 33
66
+ tool execution methods.
67
+ - Fixed a typo in the Ghostscript error message within `ps_read`.
68
+ - Added defensive handling for `JSON.load` results in `model_handling.rb` using
69
+ `.full? || {}` to prevent `nil` propagation.
70
+ - Removed implicit fallbacks to the last assistant response in
71
+ `copy_to_clipboard` and `paste_into_editor`, making `text` a required
72
+ parameter.
73
+
3
74
  ## 2026-07-13 v0.0.99
4
75
 
5
76
  ### Changed
data/Rakefile CHANGED
@@ -39,7 +39,7 @@ GemHadar do
39
39
  )
40
40
 
41
41
  dependency 'excon', '~> 1.0'
42
- dependency 'ollama-ruby', '~> 1.22'
42
+ dependency 'ollama-ruby', '~> 1.23'
43
43
  dependency 'documentrix', '>= 0.6.0'
44
44
  dependency 'unix_socks', '>= 0.4'
45
45
  dependency 'rss', '~> 0.3'
@@ -49,7 +49,7 @@ GemHadar do
49
49
  dependency 'reverse_markdown', '~> 3.0'
50
50
  dependency 'kramdown-ansi', '~> 0.5'
51
51
  dependency 'complex_config', '~> 0.22', '>= 0.22.2'
52
- dependency 'tins', '~> 1.53'
52
+ dependency 'tins', '~> 1.55'
53
53
  dependency 'search_ui', '>= 0.2'
54
54
  dependency 'amatch', '~> 0.4'
55
55
  dependency 'pdf-reader', '~> 2.0'
@@ -116,6 +116,7 @@ class OllamaChat::Chat
116
116
  else
117
117
  messages.read_conversation_jsonl(session.messages.to_s)
118
118
  end
119
+ repair_group_uuids
119
120
  embedding_enabled.set(config.embedding.enabled && !@opts[?E])
120
121
  @documents = setup_documents
121
122
  @cache = setup_cache
@@ -124,7 +125,6 @@ class OllamaChat::Chat
124
125
  @tool_call_results = Hash.new { |h, name| h[name] = [] }
125
126
  setup_personae_directory
126
127
  @opts[?S] and init_server_socket
127
- info_session
128
128
  rescue ComplexConfig::AttributeMissing, ComplexConfig::ConfigurationSyntaxError => e
129
129
  fix_config(e)
130
130
  end
@@ -183,6 +183,7 @@ class OllamaChat::Chat
183
183
  setup_persona_from_session
184
184
  setup_system_prompt
185
185
 
186
+ print_welcome
186
187
  info_session
187
188
 
188
189
  STDOUT.puts "\nType /help to display the chat help."
@@ -255,7 +256,7 @@ class OllamaChat::Chat
255
256
  ),
256
257
  ]
257
258
 
258
- content = ollama.chat(
259
+ content = call_ollama_chat(
259
260
  model: @model,
260
261
  messages: ,
261
262
  options: model_options,
@@ -265,22 +266,33 @@ class OllamaChat::Chat
265
266
  )&.message&.content.to_s
266
267
 
267
268
  if content.empty?
268
- log(
269
- :warn,
270
- "Sent #{prompt.inspect} to LLM for generation, received no content!"
271
- )
269
+ log(:warn, "LLM generation returned empty content", data: { prompt: })
272
270
  else
273
- log(
274
- :info,
275
- "Sent #{prompt.inspect} to LLM for generation, received #{content.inspect}"
276
- )
271
+ log(:info, "LLM generation successful", data: { prompt:, content: })
277
272
  end
278
273
 
279
274
  content
280
275
  end
281
276
 
277
+ # Returns a human-readable string representation of the Chat object,
278
+ # including the class name and the base URL.
279
+ #
280
+ # @return [String] the inspected string
281
+ def inspect
282
+ "#<#{self.class}: #{base_url.to_s}>"
283
+ end
284
+
282
285
  private
283
286
 
287
+ # Wrapper for ollama.chat to provide consistent logging of all arguments.
288
+ #
289
+ # @param opts [Hash] keyword arguments for the chat call
290
+ # @param block [Proc] optional handler block
291
+ def call_ollama_chat(**opts, &block)
292
+ log(:info, "Ollama chat request", data: { opts: })
293
+ ollama.chat(**opts, &block)
294
+ end
295
+
284
296
  # @return [Module] The module containing the database models.
285
297
  def models
286
298
  OllamaChat::Database::Models
@@ -328,6 +340,14 @@ class OllamaChat::Chat
328
340
  # @param prefill_prompt [String, nil] The text to prefill, or nil to clear it
329
341
  attr_writer :prefill_prompt
330
342
 
343
+ # Signals a graceful shutdown of the application.
344
+ #
345
+ # Raises {OllamaChat::OllamaChatQuitError} which is caught by the main
346
+ # interaction loop to terminate the session cleanly.
347
+ def quit_app
348
+ raise OllamaChat::OllamaChatQuitError
349
+ end
350
+
331
351
  # Handles user input commands and processes chat interactions.
332
352
  #
333
353
  # @param content [String] The input content to process
@@ -397,10 +417,11 @@ class OllamaChat::Chat
397
417
  def interact_with_user
398
418
  loop do
399
419
  content = nil
420
+ group_uuid = OllamaChat::UUIDV7.generate
400
421
  tools_were_called = false
401
422
  enable_content_parsing
402
- type = :terminal_input
403
- input_prompt = bold { color(172) { message_type(@images) + " user" } } + bold { "> " }
423
+ type = :terminal_input
424
+ input_prompt = bold { color(172) { message_type(@images) + " user" } } + bold { "> " }
404
425
  begin
405
426
  tools_were_called = handle_tool_call_results? { |index, tool_name, content|
406
427
  messages << OllamaChat::Message.new(
@@ -408,7 +429,8 @@ class OllamaChat::Chat
408
429
  sender_name: tool_name,
409
430
  tool_name: ,
410
431
  content: ,
411
- images: @images.dup
432
+ images: @images.dup,
433
+ group_uuid:
412
434
  )
413
435
  }
414
436
  tools_were_called and type = :tool_input
@@ -444,8 +466,6 @@ class OllamaChat::Chat
444
466
  next
445
467
  when :redo
446
468
  redo
447
- when :return
448
- return
449
469
  when String
450
470
  content = next_action
451
471
  end
@@ -458,6 +478,14 @@ class OllamaChat::Chat
458
478
 
459
479
  parse_content? and content = parse_content(content, @images)
460
480
 
481
+ messages << OllamaChat::Message.new(
482
+ role: 'user',
483
+ sender_name: user_name,
484
+ content: ,
485
+ images: @images.dup,
486
+ group_uuid:
487
+ )
488
+
461
489
  if runtime_info.on?
462
490
  tool_name = 'runtime_information'
463
491
  messages << OllamaChat::Message.new(
@@ -465,22 +493,17 @@ class OllamaChat::Chat
465
493
  tool_name: ,
466
494
  sender_name: tool_name,
467
495
  content: dynamic_runtime_information,
468
- images: @images.dup
496
+ images: @images.dup,
497
+ group_uuid:
469
498
  )
470
499
  end
471
-
472
- messages << OllamaChat::Message.new(
473
- role: 'user',
474
- sender_name: user_name,
475
- content: ,
476
- images: @images.dup
477
- )
478
500
  end
479
501
  @images.clear
480
502
  handler = OllamaChat::FollowChat.new(
481
503
  chat: self,
482
504
  messages:,
483
- voice: (voices.selected if voice.on?)
505
+ voice: (voices.selected if voice.on?),
506
+ group_uuid:
484
507
  )
485
508
  begin
486
509
  retried = false
@@ -493,7 +516,7 @@ class OllamaChat::Chat
493
516
  }
494
517
  end
495
518
  prepare_model(@model)
496
- ollama.chat(
519
+ call_ollama_chat(
497
520
  model: @model,
498
521
  messages: sent_messages,
499
522
  options: model_options,
@@ -534,6 +557,8 @@ class OllamaChat::Chat
534
557
  self.server_socket_message = nil
535
558
  end
536
559
  0
560
+ rescue OllamaChat::OllamaChatQuitError
561
+ STDOUT.puts "Goodbye."
537
562
  rescue ComplexConfig::AttributeMissing, ComplexConfig::ConfigurationSyntaxError => e
538
563
  log(:error, e)
539
564
  fix_config(e)
@@ -572,7 +597,7 @@ class OllamaChat::Chat
572
597
  if server_version.version < '0.9.0'.version
573
598
  raise 'require ollama API version 0.9.0 or higher'
574
599
  end
575
- log(:info, "Connection to #{base_url} established.")
600
+ log(:info, "Connection established", data: { base_url: })
576
601
  @ollama
577
602
  end
578
603