discourse-ai/spec/system/llms/ai_llm_spec.rb

186 lines
6.2 KiB
Ruby
Raw Permalink Normal View History

# frozen_string_literal: true
RSpec.describe "Managing LLM configurations", type: :system, js: true do
fab!(:admin)
let(:page_header) { PageObjects::Components::DPageHeader.new }
let(:form) { PageObjects::Components::FormKit.new("form") }
before do
SiteSetting.ai_bot_enabled = true
sign_in(admin)
end
it "correctly sets defaults" do
visit "/admin/plugins/discourse-ai/ai-llms"
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
find("[data-llm-id='anthropic-claude-3-5-haiku'] button").click()
form.field("api_key").fill_in("abcd")
form.field("enabled_chat_bot").toggle
form.submit
expect(page).to have_current_path("/admin/plugins/discourse-ai/ai-llms")
llm = LlmModel.order(:id).last
expect(llm.api_key).to eq("abcd")
preset = DiscourseAi::Completions::Llm.presets.find { |p| p[:id] == "anthropic" }
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
model_preset = preset[:models].find { |m| m[:name] == "claude-3-5-haiku" }
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
expect(llm.name).to eq("claude-3-5-haiku")
expect(llm.url).to eq(preset[:endpoint])
expect(llm.tokenizer).to eq(preset[:tokenizer].to_s)
expect(llm.max_prompt_tokens.to_i).to eq(model_preset[:tokens])
expect(llm.provider).to eq("anthropic")
expect(llm.display_name).to eq(model_preset[:display_name])
expect(llm.user_id).not_to be_nil
end
it "manually configures an LLM" do
visit "/admin/plugins/discourse-ai/ai-llms"
expect(page_header).to be_visible
find("[data-llm-id='none'] button").click()
expect(page_header).to be_hidden
form.field("display_name").fill_in("Self-hosted LLM")
form.field("name").fill_in("llava-hf/llava-v1.6-mistral-7b-hf")
form.field("url").fill_in("srv://self-hostest.test")
form.field("api_key").fill_in("1234")
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
expect(page).to have_current_path("/admin/plugins/discourse-ai/ai-llms")
llm = LlmModel.order(:id).last
expect(llm.display_name).to eq("Self-hosted LLM")
expect(llm.name).to eq("llava-hf/llava-v1.6-mistral-7b-hf")
expect(llm.url).to eq("srv://self-hostest.test")
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
context "when changing the provider" do
it "has the correct provider params when visiting the edit page" do
llm =
Fabricate(:llm_model, provider: "anthropic", provider_params: { enable_reasoning: true })
visit "/admin/plugins/discourse-ai/ai-llms/#{llm.id}/edit"
expect(form).to have_field_with_name("provider_params.disable_native_tools")
expect(form).to have_field_with_name("provider_params.reasoning_tokens")
reasoning = form.field("provider_params.enable_reasoning")
expect(reasoning).to be_checked
end
it "correctly changes the provider params" do
visit "/admin/plugins/discourse-ai/ai-llms"
find("[data-llm-id='none'] button").click()
form.field("provider").select("vllm")
expect(form).to have_field_with_name("provider_params.disable_system_prompt")
expect(form).to have_no_field_with_name("provider_params.disable_native_tools")
form.field("provider").select("open_router")
expect(form).to have_field_with_name("provider_params.disable_streaming")
expect(form).to have_field_with_name("provider_params.disable_native_tools")
end
it "updates if the url can be edited" do
visit "/admin/plugins/discourse-ai/ai-llms"
find("[data-llm-id='none'] button").click()
form.field("provider").select("vllm")
expect(form).to have_field_with_name("url")
form.field("provider").select("aws_bedrock")
expect(form).to have_no_field_with_name("url")
end
end
context "with quotas" do
fab!(:llm_model_1) { Fabricate(:llm_model, name: "claude-2") }
fab!(:group_1) { Fabricate(:group) }
before { Fabricate(:llm_quota, group: group_1, llm_model: llm_model_1, max_tokens: 1000) }
it "prefills the quotas form" do
visit "/admin/plugins/discourse-ai/ai-llms/#{llm_model_1.id}/edit"
expect(page).to have_selector(
".ai-llm-quotas__table .ai-llm-quotas__cell",
text: group_1.name,
)
end
it "can remove a quota" do
visit "/admin/plugins/discourse-ai/ai-llms/#{llm_model_1.id}/edit"
find(".ai-llm-quotas__delete-btn:nth-child(1)").click
expect(page).to have_no_selector(
".ai-llm-quotas__table .ai-llm-quotas__cell",
text: group_1.name,
)
end
it "can add a quota" do
visit "/admin/plugins/discourse-ai/ai-llms/#{llm_model_1.id}/edit"
find(".ai-llm-editor__add-quota-btn").click
select_kit = PageObjects::Components::SelectKit.new(".group-chooser")
select_kit.expand
select_kit.select_row_by_value(1)
form = PageObjects::Components::FormKit.new(".ai-llm-quota-modal form")
form.field("max_tokens").fill_in(2000)
form.submit
expect(page).to have_selector(
".ai-llm-quotas__table .ai-llm-quotas__cell",
text: Group.find(1).name,
)
end
end
context "when seeded LLM is present" do
fab!(:llm_model) { Fabricate(:seeded_model) }
it "shows the provider as CDCK in the UI" do
visit "/admin/plugins/discourse-ai/ai-llms"
expect(page).to have_css(
"[data-llm-id='cdck-hosted']",
text: I18n.t("js.discourse_ai.llms.providers.CDCK"),
)
end
it "seeded LLM has a description" do
visit "/admin/plugins/discourse-ai/ai-llms"
desc = I18n.t("js.discourse_ai.llms.preseeded_model_description", model: llm_model.name)
expect(page).to have_css(
"[data-llm-id='#{llm_model.name}'] .ai-llm-list__description",
text: desc,
)
end
it "seeded LLM has a disabled edit button" do
visit "/admin/plugins/discourse-ai/ai-llms"
expect(page).to have_css("[data-llm-id='cdck-hosted'] .ai-llm-list__edit-disabled-tooltip")
end
end
end