llm_meta_client 0.4.0 → 0.6.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.
Files changed (21) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/app/assets/stylesheets/llm_meta_client/generation_settings.css +90 -0
  4. data/lib/generators/llm_meta_client/scaffold/scaffold_generator.rb +4 -2
  5. data/lib/generators/llm_meta_client/scaffold/templates/app/controllers/chats_controller.rb +13 -3
  6. data/lib/generators/llm_meta_client/scaffold/templates/app/controllers/prompts_controller.rb +2 -2
  7. data/lib/generators/llm_meta_client/scaffold/templates/app/javascript/controllers/generation_settings_controller.js +51 -0
  8. data/lib/generators/llm_meta_client/scaffold/templates/app/models/chat.rb +17 -21
  9. data/lib/generators/llm_meta_client/scaffold/templates/app/models/message.rb +2 -2
  10. data/lib/generators/llm_meta_client/scaffold/templates/app/views/chats/_message.html.erb +3 -3
  11. data/lib/generators/llm_meta_client/scaffold/templates/app/views/chats/create.turbo_stream.erb +2 -2
  12. data/lib/generators/llm_meta_client/scaffold/templates/app/views/chats/edit.html.erb +1 -0
  13. data/lib/generators/llm_meta_client/scaffold/templates/app/views/chats/new.html.erb +1 -0
  14. data/lib/generators/llm_meta_client/scaffold/templates/app/views/chats/update.turbo_stream.erb +2 -2
  15. data/lib/generators/llm_meta_client/scaffold/templates/app/views/layouts/_sidebar.html.erb +1 -1
  16. data/lib/generators/llm_meta_client/scaffold/templates/app/views/layouts/application.html.erb +1 -1
  17. data/lib/generators/llm_meta_client/scaffold/templates/app/views/shared/_generation_settings_field.html.erb +87 -0
  18. data/lib/generators/llm_meta_client/scaffold/templates/db/migrate/create_messages.rb +1 -1
  19. data/lib/llm_meta_client/server_query.rb +4 -3
  20. data/lib/llm_meta_client/version.rb +1 -1
  21. metadata +4 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 620e720960f5e05d563885fa2e00900311d6a7b4543fa13f9d3c476515edd40c
4
- data.tar.gz: 33981d0657e520260b569873c5547e3279eba4325f88a812d8bf28d18941ac88
3
+ metadata.gz: 2e6f2472a161a70eb1e9aa1af8495c25a9a7229d0351663f2b8784759377e813
4
+ data.tar.gz: 7830a137d1a7751942a314e5271a98e5db27aa105aa36885f2a753b02f63f9a3
5
5
  SHA512:
6
- metadata.gz: a557328075624b4ff7d17eda2ed181e178f5dfda39a23a9f87029141e04b22b78e6f648f81d751f6c92add2f0b54462b28c443bce2d4cf6fcc90f0dee5e1f175
7
- data.tar.gz: f5b8ecaeec9af8153d8bbbed4d6056ba5213d267fba01381088d1f53bee80d6f1525d04992b79325476da5ce664976da9ab831844b02828e6b2db9279eb02ef0
6
+ metadata.gz: 8b16d80ac8a8f96fbf3545688a8657ed12ad2ef298707ee6475789b9468399a314b494f7d01e829557039dc11985702fbf1b4a6f1f8f67dab8f9908395fdf1d0
7
+ data.tar.gz: c335cf07ce4e413b7251fdc75ea41d227b89e86ebca4f6e44a526cd8fbb6f44dc3185851d2b1055cf20ae86ee1658e1fd2138924da0370da2d33127699c18fb6
data/CHANGELOG.md CHANGED
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.6.0] - 2026-03-18
9
+
10
+ ### Changed
11
+
12
+ - Rename `prompt_manager` references to `prompt_navigator` across all scaffold templates (models, controllers, views, migrations, generator config)
13
+ - Refactor chat template to use `PromptExecution#build_context` instead of manual message iteration
14
+ - Update `prompt_navigator` gem to 0.3.0
15
+
16
+ ## [0.5.0] - 2026-03-17
17
+
18
+ ### Added
19
+
20
+ - Generation settings support:
21
+ - `generation_settings` parameter in `ServerQuery` API layer for configuring LLM generation parameters
22
+ - `generation_settings` threading through `Chat` model
23
+ - `generation_settings` parameter extraction in `ChatsController`
24
+ - Generation settings UI components for configuring parameters in chat forms
25
+
8
26
  ## [0.4.0] - 2026-03-11
9
27
 
10
28
  ### Added
@@ -0,0 +1,90 @@
1
+ /* Generation Settings */
2
+ .generation-settings-field {
3
+ margin-bottom: 10px;
4
+ }
5
+
6
+ .generation-settings-toggle-button {
7
+ display: flex;
8
+ align-items: center;
9
+ gap: 6px;
10
+ background: none;
11
+ border: 1px solid #d1d5db;
12
+ border-radius: 6px;
13
+ padding: 6px 12px;
14
+ font-size: 13px;
15
+ font-weight: 600;
16
+ color: #374151;
17
+ cursor: pointer;
18
+ transition: border-color 0.2s, background-color 0.2s;
19
+
20
+ &:hover {
21
+ background-color: #f9fafb;
22
+ border-color: #9ca3af;
23
+ }
24
+ }
25
+
26
+ .generation-settings-panel {
27
+ margin-top: 8px;
28
+ border: 1px solid #e5e7eb;
29
+ border-radius: 8px;
30
+ background-color: #f9fafb;
31
+ padding: 12px 16px;
32
+ }
33
+
34
+ .generation-setting-item {
35
+ margin-bottom: 14px;
36
+
37
+ &:last-child {
38
+ margin-bottom: 0;
39
+ }
40
+
41
+ label {
42
+ display: flex;
43
+ align-items: center;
44
+ gap: 8px;
45
+ font-size: 13px;
46
+ font-weight: 600;
47
+ color: #374151;
48
+ margin-bottom: 4px;
49
+ }
50
+
51
+ input[type="range"] {
52
+ width: 100%;
53
+ accent-color: #3b82f6;
54
+ cursor: pointer;
55
+ }
56
+
57
+ .max-tokens-input {
58
+ width: 100%;
59
+ padding: 6px 10px;
60
+ border: 1px solid #d1d5db;
61
+ border-radius: 6px;
62
+ font-size: 13px;
63
+ background-color: white;
64
+ transition: border-color 0.2s;
65
+
66
+ &:focus {
67
+ outline: none;
68
+ border-color: #3b82f6;
69
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
70
+ }
71
+
72
+ &::placeholder {
73
+ color: #9ca3af;
74
+ }
75
+ }
76
+ }
77
+
78
+ .setting-value {
79
+ font-weight: 700;
80
+ color: #3b82f6;
81
+ font-size: 13px;
82
+ }
83
+
84
+ .setting-range-labels {
85
+ display: flex;
86
+ justify-content: space-between;
87
+ font-size: 11px;
88
+ color: #9ca3af;
89
+ margin-top: 2px;
90
+ }
@@ -34,6 +34,7 @@ module LlmMetaClient
34
34
  template "app/views/shared/_api_key_field.html.erb"
35
35
  template "app/views/shared/_model_field.html.erb"
36
36
  template "app/views/shared/_tool_selector_field.html.erb"
37
+ template "app/views/shared/_generation_settings_field.html.erb"
37
38
  template "app/views/layouts/application.html.erb"
38
39
  template "app/views/layouts/_header.html.erb"
39
40
  template "app/views/layouts/_sidebar.html.erb"
@@ -44,6 +45,7 @@ module LlmMetaClient
44
45
  template "app/javascript/controllers/chats_form_controller.js"
45
46
  template "app/javascript/controllers/chat_title_edit_controller.js"
46
47
  template "app/javascript/controllers/tool_selector_controller.js"
48
+ template "app/javascript/controllers/generation_settings_controller.js"
47
49
  copy_file "app/javascript/popover.js"
48
50
  end
49
51
 
@@ -95,8 +97,8 @@ module LlmMetaClient
95
97
 
96
98
  def configure_asset_paths
97
99
  inject_into_class "config/application.rb", "Application", <<-RUBY
98
- # Add asset paths for prompt_manager gem
99
- config.assets.paths << Rails.root.join("../prompt_manager/app/assets/stylesheets")
100
+ # Add asset paths for prompt_navigator gem
101
+ config.assets.paths << Rails.root.join("../prompt_navigator/app/assets/stylesheets")
100
102
  # Add asset paths for chat_manager gem
101
103
  config.assets.paths << Rails.root.join("../chat_manager/app/assets/stylesheets")
102
104
  RUBY
@@ -1,7 +1,7 @@
1
1
  class ChatsController < ApplicationController
2
2
  include ChatManager::ChatManageable
3
3
  include ChatManager::CsvDownloadable
4
- include PromptManager::HistoryManageable
4
+ include PromptNavigator::HistoryManageable
5
5
  # Allow access without login
6
6
  skip_before_action :authenticate_user!, raise: false
7
7
  before_action :authenticate_user!, only: [ :update_title, :download_csv, :download_all_csv ]
@@ -82,7 +82,7 @@ class ChatsController < ApplicationController
82
82
 
83
83
  # Send to LLM and get assistant response
84
84
  begin
85
- @assistant_message = @chat.add_assistant_response(@prompt_execution, jwt_token, tool_ids: tool_ids_param)
85
+ @assistant_message = @chat.add_assistant_response(@prompt_execution, jwt_token, tool_ids: tool_ids_param, generation_settings: generation_settings_param)
86
86
  # Generate chat title from the user's prompt (only if title is not yet set)
87
87
  @chat.generate_title(params[:message], jwt_token)
88
88
  rescue StandardError => e
@@ -172,7 +172,7 @@ class ChatsController < ApplicationController
172
172
 
173
173
  # Send to LLM and get assistant response
174
174
  begin
175
- @assistant_message = @chat.add_assistant_response(@prompt_execution, jwt_token, tool_ids: tool_ids_param)
175
+ @assistant_message = @chat.add_assistant_response(@prompt_execution, jwt_token, tool_ids: tool_ids_param, generation_settings: generation_settings_param)
176
176
  rescue StandardError => e
177
177
  Rails.logger.error "Error in chat response: #{e.class} - #{e.message}\n#{e.backtrace&.join("\n")}"
178
178
  @error_message = "An error occurred while getting the response. Please try again."
@@ -191,4 +191,14 @@ class ChatsController < ApplicationController
191
191
  def tool_ids_param
192
192
  params[:tool_ids].presence || []
193
193
  end
194
+
195
+ def generation_settings_param
196
+ settings = {}
197
+ settings[:temperature] = params[:temperature].to_f if params[:temperature].present?
198
+ settings[:top_k] = params[:top_k].to_i if params[:top_k].present?
199
+ settings[:top_p] = params[:top_p].to_f if params[:top_p].present?
200
+ settings[:max_tokens] = params[:max_tokens].to_i if params[:max_tokens].present?
201
+ settings[:repeat_penalty] = params[:repeat_penalty].to_f if params[:repeat_penalty].present?
202
+ settings
203
+ end
194
204
  end
@@ -1,10 +1,10 @@
1
1
  class PromptsController < ApplicationController
2
2
  include ChatManager::ChatManageable
3
- include PromptManager::HistoryManageable
3
+ include PromptNavigator::HistoryManageable
4
4
  skip_before_action :authenticate_user!, raise: false
5
5
 
6
6
  def show
7
- @prompt_execution = PromptManager::PromptExecution.includes(:messages).find_by(execution_id: params[:id])
7
+ @prompt_execution = PromptNavigator::PromptExecution.includes(:messages).find_by(execution_id: params[:id])
8
8
  @message = @prompt_execution.messages.first
9
9
  @chat = @message.chat
10
10
  @messages = @chat.ordered_messages
@@ -0,0 +1,51 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="generation-settings"
4
+ export default class extends Controller {
5
+ static targets = [
6
+ "toggleButton",
7
+ "toggleIcon",
8
+ "panel",
9
+ "temperatureRange",
10
+ "temperatureValue",
11
+ "topKRange",
12
+ "topKValue",
13
+ "topPRange",
14
+ "topPValue",
15
+ "maxTokensInput",
16
+ "repeatPenaltyRange",
17
+ "repeatPenaltyValue",
18
+ ]
19
+
20
+ connect() {
21
+ this.expanded = false
22
+ }
23
+
24
+ toggle() {
25
+ if (!this.hasPanelTarget) return
26
+
27
+ this.expanded = !this.expanded
28
+ this.panelTarget.style.display = this.expanded ? "block" : "none"
29
+
30
+ if (this.hasToggleIconTarget) {
31
+ this.toggleIconTarget.classList.toggle("bi-chevron-down", !this.expanded)
32
+ this.toggleIconTarget.classList.toggle("bi-chevron-up", this.expanded)
33
+ }
34
+ }
35
+
36
+ updateTemperature() {
37
+ this.temperatureValueTarget.textContent = this.temperatureRangeTarget.value
38
+ }
39
+
40
+ updateTopK() {
41
+ this.topKValueTarget.textContent = this.topKRangeTarget.value
42
+ }
43
+
44
+ updateTopP() {
45
+ this.topPValueTarget.textContent = this.topPRangeTarget.value
46
+ }
47
+
48
+ updateRepeatPenalty() {
49
+ this.repeatPenaltyValueTarget.textContent = this.repeatPenaltyRangeTarget.value
50
+ }
51
+ }
@@ -51,31 +51,31 @@ class Chat < ApplicationRecord
51
51
  # Add a user message to the chat
52
52
  def add_user_message(message, model, branch_from_uuid = nil)
53
53
  parent_message = branch_from_uuid.present? ? messages.find_by(uuid: branch_from_uuid) : nil
54
- prompt_execution = PromptManager::PromptExecution.create!(
54
+ prompt_execution = PromptNavigator::PromptExecution.create!(
55
55
  prompt: message,
56
56
  model: model,
57
57
  configuration: "",
58
- previous_id: parent_message&.prompt_manager_prompt_execution_id
58
+ previous_id: parent_message&.prompt_navigator_prompt_execution_id
59
59
  )
60
60
 
61
61
  new_message = messages.create!(
62
62
  role: "user",
63
- prompt_manager_prompt_execution: prompt_execution
63
+ prompt_navigator_prompt_execution: prompt_execution
64
64
  )
65
65
 
66
66
  [ prompt_execution, new_message ]
67
67
  end
68
68
 
69
69
  # Add assistant response by sending to LLM
70
- def add_assistant_response(prompt_execution, jwt_token, tool_ids: [])
71
- response_content = send_to_llm(jwt_token, tool_ids: tool_ids)
70
+ def add_assistant_response(prompt_execution, jwt_token, tool_ids: [], generation_settings: {})
71
+ response_content = send_to_llm(jwt_token, tool_ids: tool_ids, generation_settings: generation_settings)
72
72
  prompt_execution.update!(
73
73
  llm_platform: llm_type(jwt_token),
74
74
  response: response_content
75
75
  )
76
76
  new_message = messages.create!(
77
77
  role: "assistant",
78
- prompt_manager_prompt_execution: prompt_execution
78
+ prompt_navigator_prompt_execution: prompt_execution
79
79
  )
80
80
 
81
81
  new_message
@@ -84,18 +84,18 @@ class Chat < ApplicationRecord
84
84
  # Get all messages in order
85
85
  def ordered_messages
86
86
  messages
87
- .includes(:prompt_manager_prompt_execution)
87
+ .includes(:prompt_navigator_prompt_execution)
88
88
  .order(:created_at)
89
89
  end
90
90
 
91
91
  def ordered_by_descending_prompt_executions
92
92
  messages
93
93
  .where(role: "user")
94
- .includes(:prompt_manager_prompt_execution)
94
+ .includes(:prompt_navigator_prompt_execution)
95
95
  .order(created_at: :desc)
96
96
  .to_a
97
- .select { |msg| msg.prompt_manager_prompt_execution }
98
- .map(&:prompt_manager_prompt_execution)
97
+ .select { |msg| msg.prompt_navigator_prompt_execution }
98
+ .map(&:prompt_navigator_prompt_execution)
99
99
  end
100
100
 
101
101
  # Check if chat needs to be reset due to LLM or model change
@@ -122,33 +122,29 @@ class Chat < ApplicationRecord
122
122
  end
123
123
 
124
124
  # Send messages to LLM and get response
125
- def send_to_llm(jwt_token, tool_ids: [])
125
+ def send_to_llm(jwt_token, tool_ids: [], generation_settings: {})
126
126
  # Get LLM options
127
127
  llm_options = LlmMetaClient::ServerResource.available_llm_options(jwt_token)
128
128
 
129
129
  # Error if no LLM is available
130
130
  raise LlmMetaClient::Exceptions::OllamaUnavailableError, "No LLM available" if llm_options.empty?
131
131
 
132
- # Prepare messages for LLM
133
- all_messages = ordered_messages.to_a
134
- last_msg = all_messages.last
132
+ # Build prompt and context from direct lineage via PromptExecution
133
+ last_msg = ordered_messages.last
134
+ pe = last_msg.prompt_manager_prompt_execution
135
135
 
136
- # Prepare prompt and context
137
- prompt = { role: last_msg.role, prompt: last_msg.prompt_manager_prompt_execution.prompt }
138
- context = all_messages[0...-1].last(Rails.configuration.summarize_conversation_count).map do |msg|
139
- { role: msg.role, prompt: msg.prompt_manager_prompt_execution.prompt, response: msg.prompt_manager_prompt_execution&.response }
140
- end
136
+ prompt = { role: last_msg.role, prompt: pe.prompt }
137
+ context = pe.build_context(limit: Rails.configuration.summarize_conversation_count)
141
138
 
142
139
  if context.empty?
143
140
  summarized_context = "No context available."
144
141
  else
145
- # Summarize context
146
142
  summarized_context = LlmMetaClient::ServerQuery.new.call(jwt_token, llm_uuid, model, context, "Please summarize the context")
147
143
  end
148
144
 
149
145
  summarized_context += "Additional prompt: Responses from the assistant must consist solely of the response body."
150
146
 
151
147
  # Send chat request using LlmMetaClient::ServerQuery
152
- LlmMetaClient::ServerQuery.new.call(jwt_token, llm_uuid, model, summarized_context, prompt, tool_ids: tool_ids)
148
+ LlmMetaClient::ServerQuery.new.call(jwt_token, llm_uuid, model, summarized_context, prompt, tool_ids: tool_ids, generation_settings: generation_settings)
153
149
  end
154
150
  end
@@ -1,7 +1,7 @@
1
1
  class Message < ApplicationRecord
2
2
  belongs_to :chat
3
- belongs_to :prompt_manager_prompt_execution,
4
- class_name: "PromptManager::PromptExecution",
3
+ belongs_to :prompt_navigator_prompt_execution,
4
+ class_name: "PromptNavigator::PromptExecution",
5
5
  optional: false
6
6
 
7
7
  validates :role, presence: true, inclusion: { in: %w[user assistant] }
@@ -3,14 +3,14 @@
3
3
  <%% if message.role == 'user' %>
4
4
  👤 You
5
5
  <%% else %>
6
- 🤖 <%%= message.prompt_manager_prompt_execution.llm_platform&.capitalize || 'LLM' %>
6
+ 🤖 <%%= message.prompt_navigator_prompt_execution.llm_platform&.capitalize || 'LLM' %>
7
7
  <%% end %>
8
8
  </div>
9
9
  <div class="message-content">
10
10
  <%% if message.role == 'user' %>
11
- <%%= simple_format(message.prompt_manager_prompt_execution&.prompt) %>
11
+ <%%= simple_format(message.prompt_navigator_prompt_execution&.prompt) %>
12
12
  <%% else %>
13
- <%%= simple_format(message.prompt_manager_prompt_execution&.response) %>
13
+ <%%= simple_format(message.prompt_navigator_prompt_execution&.response) %>
14
14
  <%% end %>
15
15
  </div>
16
16
  </div>
@@ -36,14 +36,14 @@
36
36
  <div id="history-content">
37
37
  <h2>History</h2>
38
38
  <div class="history-stack" id="history-stack" data-controller="history">
39
- <%%= render 'prompt_manager/history_card', locals: {
39
+ <%%= render 'prompt_navigator/history_card', locals: {
40
40
  ann: @prompt_execution,
41
41
  next_ann: nil,
42
42
  is_active: @prompt_execution.execution_id == @active_message_uuid,
43
43
  card_path: ->(uuid) { prompt_path(uuid) }
44
44
  } %>
45
45
  <%% (@chat&.ordered_by_descending_prompt_executions || []).drop(1).each_with_index do |ann, idx| %>
46
- <%%= render 'prompt_manager/history_card', locals: {
46
+ <%%= render 'prompt_navigator/history_card', locals: {
47
47
  ann: ann,
48
48
  next_ann: @chat.ordered_by_descending_prompt_executions[idx + 2],
49
49
  is_active: ann.execution_id == @active_message_uuid,
@@ -18,6 +18,7 @@
18
18
  <%% if user_signed_in? %>
19
19
  <%%= render "shared/tool_selector_field", stimulus_controller: "tool-selector" %>
20
20
  <%% end %>
21
+ <%%= render "shared/generation_settings_field", stimulus_controller: "generation-settings" %>
21
22
  <%% end %>
22
23
  <div class="input-wrapper">
23
24
  <%%= f.text_area :message,
@@ -18,6 +18,7 @@
18
18
  <%% if user_signed_in? %>
19
19
  <%%= render "shared/tool_selector_field", stimulus_controller: "tool-selector" %>
20
20
  <%% end %>
21
+ <%%= render "shared/generation_settings_field", stimulus_controller: "generation-settings" %>
21
22
  <%% end %>
22
23
  <div class="input-wrapper">
23
24
  <%%= f.text_area :message,
@@ -30,14 +30,14 @@
30
30
  <div id="history-content">
31
31
  <h2>History</h2>
32
32
  <div class="history-stack" id="history-stack" data-controller="history">
33
- <%%= render 'prompt_manager/history_card', locals: {
33
+ <%%= render 'prompt_navigator/history_card', locals: {
34
34
  ann: @prompt_execution,
35
35
  next_ann: nil,
36
36
  is_active: @prompt_execution.execution_id == @active_message_uuid,
37
37
  card_path: ->(uuid) { prompt_path(uuid) }
38
38
  } %>
39
39
  <%% (@chat&.ordered_by_descending_prompt_executions || []).drop(1).each_with_index do |ann, idx| %>
40
- <%%= render 'prompt_manager/history_card', locals: {
40
+ <%%= render 'prompt_navigator/history_card', locals: {
41
41
  ann: ann,
42
42
  next_ann: @chat.ordered_by_descending_prompt_executions[idx + 2],
43
43
  is_active: ann.execution_id == @active_message_uuid,
@@ -12,7 +12,7 @@
12
12
  <%% if history.present? %>
13
13
  <div class="history-stack" id="history-stack" data-controller="history">
14
14
  <%% history.each_with_index do |ann, idx| %>
15
- <%%= render 'prompt_manager/history_card', locals: {
15
+ <%%= render 'prompt_navigator/history_card', locals: {
16
16
  ann: ann,
17
17
  next_ann: history[idx + 1],
18
18
  is_active: ann.uuid == active_uuid,
@@ -20,7 +20,7 @@
20
20
 
21
21
  <%% # Includes all stylesheet files in app/assets/stylesheets %>
22
22
  <%%= stylesheet_link_tag :app %>
23
- <%%= stylesheet_link_tag "prompt_manager/history", "data-turbo-track": "reload" %>
23
+ <%%= stylesheet_link_tag "prompt_navigator/history", "data-turbo-track": "reload" %>
24
24
  <%%= stylesheet_link_tag "chat_manager/chat", "data-turbo-track": "reload" %>
25
25
  <%%= javascript_importmap_tags %>
26
26
  </head>
@@ -0,0 +1,87 @@
1
+ <%%
2
+ stimulus_controller = local_assigns[:stimulus_controller] || "generation-settings"
3
+ %>
4
+ <div class="generation-settings-field" data-controller="<%%= stimulus_controller %>">
5
+ <div class="generation-settings-toggle">
6
+ <button type="button"
7
+ class="generation-settings-toggle-button"
8
+ data-<%%= stimulus_controller %>-target="toggleButton"
9
+ data-action="click-><%%= stimulus_controller %>#toggle">
10
+ <i class="bi bi-sliders"></i>
11
+ Generation Settings
12
+ <i class="bi bi-chevron-down toggle-icon" data-<%%= stimulus_controller %>-target="toggleIcon"></i>
13
+ </button>
14
+ </div>
15
+ <div class="generation-settings-panel" data-<%%= stimulus_controller %>-target="panel" style="display: none;">
16
+ <div class="generation-setting-item">
17
+ <label for="temperature">
18
+ Temperature
19
+ <span class="setting-value" data-<%%= stimulus_controller %>-target="temperatureValue">0.7</span>
20
+ </label>
21
+ <input type="range" name="temperature" id="temperature"
22
+ min="0" max="2" step="0.1" value="0.7"
23
+ data-<%%= stimulus_controller %>-target="temperatureRange"
24
+ data-action="input-><%%= stimulus_controller %>#updateTemperature">
25
+ <div class="setting-range-labels">
26
+ <span>0 (deterministic)</span>
27
+ <span>2 (creative)</span>
28
+ </div>
29
+ </div>
30
+
31
+ <div class="generation-setting-item">
32
+ <label for="top_k">
33
+ Top-K
34
+ <span class="setting-value" data-<%%= stimulus_controller %>-target="topKValue">40</span>
35
+ </label>
36
+ <input type="range" name="top_k" id="top_k"
37
+ min="1" max="100" step="1" value="40"
38
+ data-<%%= stimulus_controller %>-target="topKRange"
39
+ data-action="input-><%%= stimulus_controller %>#updateTopK">
40
+ <div class="setting-range-labels">
41
+ <span>1 (focused)</span>
42
+ <span>100 (diverse)</span>
43
+ </div>
44
+ </div>
45
+
46
+ <div class="generation-setting-item">
47
+ <label for="top_p">
48
+ Top-P
49
+ <span class="setting-value" data-<%%= stimulus_controller %>-target="topPValue">0.9</span>
50
+ </label>
51
+ <input type="range" name="top_p" id="top_p"
52
+ min="0" max="1" step="0.05" value="0.9"
53
+ data-<%%= stimulus_controller %>-target="topPRange"
54
+ data-action="input-><%%= stimulus_controller %>#updateTopP">
55
+ <div class="setting-range-labels">
56
+ <span>0 (narrow)</span>
57
+ <span>1 (broad)</span>
58
+ </div>
59
+ </div>
60
+
61
+ <div class="generation-setting-item">
62
+ <label for="max_tokens">
63
+ Max Tokens
64
+ </label>
65
+ <input type="number" name="max_tokens" id="max_tokens"
66
+ min="1" max="128000" step="1" value=""
67
+ placeholder="Default (model-dependent)"
68
+ class="max-tokens-input"
69
+ data-<%%= stimulus_controller %>-target="maxTokensInput">
70
+ </div>
71
+
72
+ <div class="generation-setting-item">
73
+ <label for="repeat_penalty">
74
+ Repeat Penalty
75
+ <span class="setting-value" data-<%%= stimulus_controller %>-target="repeatPenaltyValue">1.1</span>
76
+ </label>
77
+ <input type="range" name="repeat_penalty" id="repeat_penalty"
78
+ min="1" max="2" step="0.05" value="1.1"
79
+ data-<%%= stimulus_controller %>-target="repeatPenaltyRange"
80
+ data-action="input-><%%= stimulus_controller %>#updateRepeatPenalty">
81
+ <div class="setting-range-labels">
82
+ <span>1.0 (no penalty)</span>
83
+ <span>2.0 (strong)</span>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </div>
@@ -3,7 +3,7 @@ class CreateMessages < ActiveRecord::Migration[8.1]
3
3
  create_table :messages do |t|
4
4
  t.references :chat, null: false, foreign_key: true
5
5
  # t.references :parent, foreign_key: { to_table: :messages }, index: true, null: true
6
- t.references :prompt_manager_prompt_execution, null: true, foreign_key: { to_table: :prompt_manager_prompt_executions }
6
+ t.references :prompt_navigator_prompt_execution, null: true, foreign_key: { to_table: :prompt_navigator_prompt_executions }
7
7
  t.string :role
8
8
 
9
9
  t.timestamps
@@ -1,11 +1,11 @@
1
1
  module LlmMetaClient
2
2
  class ServerQuery
3
- def call(id_token, api_key_uuid, model_id, context, user_content, tool_ids: [])
3
+ def call(id_token, api_key_uuid, model_id, context, user_content, tool_ids: [], generation_settings: {})
4
4
  debug_log "Context: #{context}"
5
5
  context_and_user_content = "Context:#{context}, User Prompt: #{user_content}"
6
6
  debug_log "Request to LLM: \n===>\n#{context_and_user_content}\n===>"
7
7
 
8
- response = request(api_key_uuid, id_token, model_id, context_and_user_content, tool_ids)
8
+ response = request(api_key_uuid, id_token, model_id, context_and_user_content, tool_ids, generation_settings)
9
9
 
10
10
  raise Exceptions::ServerError, "LLM server returned HTTP #{response.code}" unless response.success?
11
11
 
@@ -28,12 +28,13 @@ module LlmMetaClient
28
28
  Rails.logger.info(message) if Rails.env.development?
29
29
  end
30
30
 
31
- def request(api_key_uuid, id_token, model_id, user_content, tool_ids)
31
+ def request(api_key_uuid, id_token, model_id, user_content, tool_ids, generation_settings)
32
32
  headers = { "Content-Type" => "application/json" }
33
33
  headers["Authorization"] = "Bearer #{id_token}" if id_token.present?
34
34
 
35
35
  body = { prompt: user_content.to_s }
36
36
  body[:tool_ids] = tool_ids if tool_ids.present?
37
+ body[:generation_settings] = generation_settings if generation_settings.present?
37
38
 
38
39
  HTTParty.post(
39
40
  url(api_key_uuid, model_id),
@@ -1,3 +1,3 @@
1
1
  module LlmMetaClient
2
- VERSION = "0.4.0"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: llm_meta_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dhq_boiler
@@ -85,6 +85,7 @@ files:
85
85
  - README.md
86
86
  - Rakefile
87
87
  - app/assets/stylesheets/llm_meta_client/application.css
88
+ - app/assets/stylesheets/llm_meta_client/generation_settings.css
88
89
  - app/controllers/llm_meta_client/application_controller.rb
89
90
  - app/helpers/llm_meta_client/application_helper.rb
90
91
  - app/jobs/llm_meta_client/application_job.rb
@@ -106,6 +107,7 @@ files:
106
107
  - lib/generators/llm_meta_client/scaffold/templates/app/controllers/prompts_controller.rb
107
108
  - lib/generators/llm_meta_client/scaffold/templates/app/javascript/controllers/chat_title_edit_controller.js
108
109
  - lib/generators/llm_meta_client/scaffold/templates/app/javascript/controllers/chats_form_controller.js
110
+ - lib/generators/llm_meta_client/scaffold/templates/app/javascript/controllers/generation_settings_controller.js
109
111
  - lib/generators/llm_meta_client/scaffold/templates/app/javascript/controllers/llm_selector_controller.js
110
112
  - lib/generators/llm_meta_client/scaffold/templates/app/javascript/controllers/tool_selector_controller.js
111
113
  - lib/generators/llm_meta_client/scaffold/templates/app/javascript/popover.js
@@ -122,6 +124,7 @@ files:
122
124
  - lib/generators/llm_meta_client/scaffold/templates/app/views/layouts/application.html.erb
123
125
  - lib/generators/llm_meta_client/scaffold/templates/app/views/shared/_api_key_field.html.erb
124
126
  - lib/generators/llm_meta_client/scaffold/templates/app/views/shared/_family_field.html.erb
127
+ - lib/generators/llm_meta_client/scaffold/templates/app/views/shared/_generation_settings_field.html.erb
125
128
  - lib/generators/llm_meta_client/scaffold/templates/app/views/shared/_model_field.html.erb
126
129
  - lib/generators/llm_meta_client/scaffold/templates/app/views/shared/_tool_selector_field.html.erb
127
130
  - lib/generators/llm_meta_client/scaffold/templates/config/initializers/llm_service.rb