FEATURE: Enhance LLM context window settings (#1271)

### 🔍 Overview
This update performs some enhancements to the LLM configuration screen. In particular, it renames the UI for the number of tokens for the prompt to "Context window" since the naming can be confusing to the user. Additionally, it adds a new optional field called "Max output tokens".
This commit is contained in:
Keegan George 2025-04-17 14:44:15 -07:00 committed by GitHub
parent 0c8718e0d5
commit e2b0287333
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 41 additions and 3 deletions

View File

@ -157,6 +157,7 @@ module DiscourseAi
:provider,
:tokenizer,
:max_prompt_tokens,
:max_output_tokens,
:api_key,
:enabled_chat_bot,
:vision_enabled,

View File

@ -13,6 +13,7 @@ class LlmModel < ActiveRecord::Base
validates :url, presence: true, unless: -> { provider == BEDROCK_PROVIDER_NAME }
validates_presence_of :name, :api_key
validates :max_prompt_tokens, numericality: { greater_than: 0 }
validates :max_output_tokens, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
validate :required_provider_params
scope :in_use,
-> do
@ -183,4 +184,5 @@ end
# enabled_chat_bot :boolean default(FALSE), not null
# provider_params :jsonb
# vision_enabled :boolean default(FALSE), not null
# max_output_tokens :integer
#

View File

@ -11,6 +11,7 @@ class LlmModelSerializer < ApplicationSerializer
:name,
:provider,
:max_prompt_tokens,
:max_output_tokens,
:tokenizer,
:api_key,
:url,

View File

@ -10,6 +10,7 @@ export default class AiLlm extends RestModel {
"provider",
"tokenizer",
"max_prompt_tokens",
"max_output_tokens",
"url",
"api_key",
"enabled_chat_bot",

View File

@ -40,6 +40,7 @@ export default class AiLlmEditorForm extends Component {
return {
max_prompt_tokens: modelInfo.tokens,
max_output_tokens: modelInfo.max_output_tokens,
tokenizer: info.tokenizer,
url: modelInfo.endpoint || info.endpoint,
display_name: modelInfo.display_name,
@ -53,6 +54,7 @@ export default class AiLlmEditorForm extends Component {
return {
max_prompt_tokens: model.max_prompt_tokens,
max_output_tokens: model.max_output_tokens,
api_key: model.api_key,
tokenizer: model.tokenizer,
url: model.url,
@ -183,8 +185,18 @@ export default class AiLlmEditorForm extends Component {
this.isSaving = true;
const isNew = this.args.model.isNew;
const updatedData = {
...data,
};
// If max_prompt_tokens input is cleared,
// we want the db to store null
if (!data.max_output_tokens) {
updatedData.max_output_tokens = null;
}
try {
await this.args.model.save(data);
await this.args.model.save(updatedData);
if (isNew) {
this.args.llms.addObject(this.args.model);
@ -399,6 +411,16 @@ export default class AiLlmEditorForm extends Component {
<field.Input @type="number" step="any" min="0" lang="en" />
</form.Field>
<form.Field
@name="max_output_tokens"
@title={{i18n "discourse_ai.llms.max_output_tokens"}}
@tooltip={{i18n "discourse_ai.llms.hints.max_output_tokens"}}
@format="large"
as |field|
>
<field.Input @type="number" step="any" min="0" lang="en" />
</form.Field>
<form.Field
@name="vision_enabled"
@title={{i18n "discourse_ai.llms.vision_enabled"}}

View File

@ -397,7 +397,8 @@ en:
name: "Model id"
provider: "Provider"
tokenizer: "Tokenizer"
max_prompt_tokens: "Number of tokens for the prompt"
max_prompt_tokens: "Context window"
max_output_tokens: "Max output tokens"
url: "URL of the service hosting the model"
api_key: "API Key of the service hosting the model"
enabled_chat_bot: "Allow AI bot selector"
@ -480,7 +481,8 @@ en:
failure: "Trying to contact the model returned this error: %{error}"
hints:
max_prompt_tokens: "Max numbers of tokens for the prompt. As a rule of thumb, this should be 50% of the model's context window."
max_prompt_tokens: "The maximum number of tokens the model can process in a single request"
max_output_tokens: "The maximum number of tokens the model can generate in a single request"
display_name: "The name used to reference this model across your site's interface."
name: "We include this in the API call to specify which model we'll use"
vision_enabled: "If enabled, the AI will attempt to understand images. It depends on the model being used supporting vision. Supported by latest models from Anthropic, Google, and OpenAI."

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddMaxOutputTokensToLlmModel < ActiveRecord::Migration[7.2]
def change
add_column :llm_models, :max_output_tokens, :integer
end
end

View File

@ -53,6 +53,7 @@ RSpec.describe "Managing LLM configurations", type: :system, js: true do
form.field("max_prompt_tokens").fill_in(8000)
form.field("provider").select("vllm")
form.field("tokenizer").select("DiscourseAi::Tokenizer::Llama3Tokenizer")
form.field("max_output_tokens").fill_in(2000)
form.field("vision_enabled").toggle
form.field("enabled_chat_bot").toggle
form.submit
@ -67,6 +68,7 @@ RSpec.describe "Managing LLM configurations", type: :system, js: true do
expect(llm.tokenizer).to eq("DiscourseAi::Tokenizer::Llama3Tokenizer")
expect(llm.max_prompt_tokens.to_i).to eq(8000)
expect(llm.provider).to eq("vllm")
expect(llm.max_output_tokens.to_i).to eq(2000)
expect(llm.vision_enabled).to eq(true)
expect(llm.user_id).not_to be_nil
end