From 52a7dd2a4b73e62fa4436ef50a14354a31f43ffd Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 11 Jun 2024 18:14:14 +1000 Subject: [PATCH] FEATURE: optional tool detail blocks (#662) This is a rather huge refactor with 1 new feature (tool details can be suppressed) Previously we use the name "Command" to describe "Tools", this unifies all the internal language and simplifies the code. We also amended the persona UI to use less DToggles which aligns with our design guidelines. Co-authored-by: Martin Brennan --- .../admin/ai_personas_controller.rb | 19 +- app/models/ai_persona.rb | 224 ++++-------------- .../localized_ai_persona_serializer.rb | 5 +- .../discourse/admin/models/ai-persona.js | 65 ++--- .../components/ai-persona-command-options.gjs | 81 ------- .../components/ai-persona-editor.gjs | 155 ++++++------ ....gjs => ai-persona-tool-option-editor.gjs} | 6 +- .../components/ai-persona-tool-options.gjs | 79 ++++++ ...ommand-selector.js => ai-tool-selector.js} | 2 +- .../modules/ai-bot/common/ai-persona.scss | 25 +- config/locales/client.ar.yml | 2 +- config/locales/client.de.yml | 2 +- config/locales/client.en.yml | 8 +- config/locales/client.es.yml | 2 +- config/locales/client.fi.yml | 2 +- config/locales/client.fr.yml | 2 +- config/locales/client.he.yml | 2 +- config/locales/client.it.yml | 2 +- config/locales/client.ja.yml | 2 +- config/locales/client.nl.yml | 2 +- config/locales/client.pl_PL.yml | 2 +- config/locales/client.pt_BR.yml | 2 +- config/locales/client.ru.yml | 2 +- config/locales/client.tr_TR.yml | 2 +- config/locales/client.zh_CN.yml | 2 +- config/locales/server.ar.yml | 8 +- config/locales/server.be.yml | 2 +- config/locales/server.bg.yml | 2 +- config/locales/server.bs_BA.yml | 2 +- config/locales/server.ca.yml | 2 +- config/locales/server.cs.yml | 2 +- config/locales/server.da.yml | 2 +- config/locales/server.de.yml | 8 +- config/locales/server.el.yml | 2 +- config/locales/server.en.yml | 10 +- config/locales/server.es.yml | 8 +- config/locales/server.et.yml | 2 +- config/locales/server.fa_IR.yml | 4 +- config/locales/server.fi.yml | 8 +- config/locales/server.fr.yml | 8 +- config/locales/server.gl.yml | 2 +- config/locales/server.he.yml | 8 +- config/locales/server.hr.yml | 2 +- config/locales/server.hu.yml | 2 +- config/locales/server.hy.yml | 2 +- config/locales/server.id.yml | 8 +- config/locales/server.it.yml | 8 +- config/locales/server.ja.yml | 8 +- config/locales/server.ko.yml | 2 +- config/locales/server.lt.yml | 2 +- config/locales/server.lv.yml | 2 +- config/locales/server.nb_NO.yml | 2 +- config/locales/server.nl.yml | 8 +- config/locales/server.pl_PL.yml | 8 +- config/locales/server.pt.yml | 2 +- config/locales/server.pt_BR.yml | 8 +- config/locales/server.ro.yml | 2 +- config/locales/server.ru.yml | 8 +- config/locales/server.sk.yml | 2 +- config/locales/server.sl.yml | 2 +- config/locales/server.sq.yml | 2 +- config/locales/server.sr.yml | 2 +- config/locales/server.sv.yml | 2 +- config/locales/server.sw.yml | 2 +- config/locales/server.te.yml | 2 +- config/locales/server.th.yml | 2 +- config/locales/server.tr_TR.yml | 8 +- config/locales/server.ug.yml | 2 +- config/locales/server.uk.yml | 2 +- config/locales/server.ur.yml | 2 +- config/locales/server.vi.yml | 2 +- config/locales/server.zh_CN.yml | 8 +- config/locales/server.zh_TW.yml | 2 +- db/fixtures/ai_bot/603_bot_ai_personas.rb | 2 +- ...061418_tool_details_and_command_removal.rb | 14 ++ ...09232736_drop_commands_from_ai_personas.rb | 10 + lib/ai_bot/playground.rb | 4 +- lib/ai_bot/tools/option.rb | 4 +- lib/ai_bot/tools/tool.rb | 8 +- .../modules/ai_bot/personas/persona_spec.rb | 2 +- spec/lib/modules/ai_bot/playground_spec.rb | 30 ++- spec/models/ai_persona_spec.rb | 10 +- .../admin/ai_personas_controller_spec.rb | 44 ++-- spec/system/ai_bot/persona_spec.rb | 8 +- .../unit/models/ai-persona-test.js | 40 ++-- 85 files changed, 495 insertions(+), 574 deletions(-) delete mode 100644 assets/javascripts/discourse/components/ai-persona-command-options.gjs rename assets/javascripts/discourse/components/{ai-persona-command-option-editor.gjs => ai-persona-tool-option-editor.gjs} (82%) create mode 100644 assets/javascripts/discourse/components/ai-persona-tool-options.gjs rename assets/javascripts/discourse/components/{ai-command-selector.js => ai-tool-selector.js} (94%) create mode 100644 db/migrate/20240609061418_tool_details_and_command_removal.rb create mode 100644 db/post_migrate/20240609232736_drop_commands_from_ai_personas.rb diff --git a/app/controllers/discourse_ai/admin/ai_personas_controller.rb b/app/controllers/discourse_ai/admin/ai_personas_controller.rb index ca52ea56..3dc17a15 100644 --- a/app/controllers/discourse_ai/admin/ai_personas_controller.rb +++ b/app/controllers/discourse_ai/admin/ai_personas_controller.rb @@ -23,7 +23,7 @@ module DiscourseAi DiscourseAi::Configuration::LlmEnumerator.values.map do |hash| { id: hash[:value], name: hash[:name] } end - render json: { ai_personas: ai_personas, meta: { commands: tools, llms: llms } } + render json: { ai_personas: ai_personas, meta: { tools: tools, llms: llms } } end def show @@ -126,28 +126,29 @@ module DiscourseAi :rag_conversation_chunks, :question_consolidator_llm, :allow_chat, + :tool_details, allowed_group_ids: [], rag_uploads: [:id], ) - if commands = params.dig(:ai_persona, :commands) - permitted[:commands] = permit_commands(commands) + if tools = params.dig(:ai_persona, :tools) + permitted[:tools] = permit_tools(tools) end permitted end - def permit_commands(commands) - return [] if !commands.is_a?(Array) + def permit_tools(tools) + return [] if !tools.is_a?(Array) - commands.filter_map do |command, options| - break nil if !command.is_a?(String) + tools.filter_map do |tool, options| + break nil if !tool.is_a?(String) options&.permit! if options && options.is_a?(ActionController::Parameters) if options - [command, options] + [tool, options] else - command + tool end end end diff --git a/app/models/ai_persona.rb b/app/models/ai_persona.rb index 7db31800..0d979ed8 100644 --- a/app/models/ai_persona.rb +++ b/app/models/ai_persona.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class AiPersona < ActiveRecord::Base + # TODO remove this line 01-11-2024 + self.ignored_columns = [:commands] + # places a hard limit, so per site we cache a maximum of 500 classes MAX_PERSONAS_PER_SITE = 500 @@ -102,96 +105,49 @@ class AiPersona < ActiveRecord::Base end def class_instance - allowed_group_ids = self.allowed_group_ids - id = self.id - system = self.system - user_id = self.user_id - mentionable = self.mentionable - default_llm = self.default_llm - max_context_posts = self.max_context_posts - vision_enabled = self.vision_enabled - vision_max_pixels = self.vision_max_pixels - rag_conversation_chunks = self.rag_conversation_chunks - question_consolidator_llm = self.question_consolidator_llm - allow_chat = self.allow_chat + attributes = %i[ + id + user_id + system + mentionable + default_llm + max_context_posts + vision_enabled + vision_max_pixels + rag_conversation_chunks + question_consolidator_llm + allow_chat + name + description + allowed_group_ids + tool_details + ] persona_class = DiscourseAi::AiBot::Personas::Persona.system_personas_by_id[self.id] + + instance_attributes = {} + attributes.each do |attr| + value = self.read_attribute(attr) + instance_attributes[attr] = value + end + if persona_class - persona_class.define_singleton_method :allowed_group_ids do - allowed_group_ids + instance_attributes.each do |key, value| + # description/name are localized + persona_class.define_singleton_method(key) { value } if key != :description && key != :name end - - persona_class.define_singleton_method :id do - id - end - - persona_class.define_singleton_method :system do - system - end - - persona_class.define_singleton_method :user_id do - user_id - end - - persona_class.define_singleton_method :allow_chat do - allow_chat - end - - persona_class.define_singleton_method :mentionable do - mentionable - end - - persona_class.define_singleton_method :default_llm do - default_llm - end - - persona_class.define_singleton_method :max_context_posts do - max_context_posts - end - - persona_class.define_singleton_method :vision_enabled do - vision_enabled - end - - persona_class.define_singleton_method :vision_max_pixels do - vision_max_pixels - end - - persona_class.define_singleton_method :question_consolidator_llm do - question_consolidator_llm - end - - persona_class.define_singleton_method :rag_conversation_chunks do - rag_conversation_chunks - end - return persona_class end - name = self.name - description = self.description - ai_persona_id = self.id - options = {} - - tools = self.respond_to?(:commands) ? self.commands : self.tools - tools = - tools.filter_map do |element| - inner_name = element - current_options = nil - - if element.is_a?(Array) - inner_name = element[0] - current_options = element[1] - end - - # Won't migrate data yet. Let's rewrite to the tool name. - inner_name = inner_name.gsub("Command", "") + self.tools.filter_map do |element| + inner_name, current_options = element.is_a?(Array) ? element : [element, nil] + inner_name = inner_name.gsub("Tool", "") inner_name = "List#{inner_name}" if %w[Categories Tags].include?(inner_name) begin - klass = ("DiscourseAi::AiBot::Tools::#{inner_name}").constantize + klass = "DiscourseAi::AiBot::Tools::#{inner_name}".constantize options[klass] = current_options if current_options klass rescue StandardError @@ -199,107 +155,28 @@ class AiPersona < ActiveRecord::Base end end + ai_persona_id = self.id + Class.new(DiscourseAi::AiBot::Personas::Persona) do - define_singleton_method :id do - id + instance_attributes.each { |key, value| define_singleton_method(key) { value } } + + define_singleton_method(:to_s) do + "#<#{self.class.name} @name=#{name} @allowed_group_ids=#{allowed_group_ids.join(",")}>" end - define_singleton_method :name do - name - end + define_singleton_method(:inspect) { to_s } - define_singleton_method :user_id do - user_id - end - - define_singleton_method :description do - description - end - - define_singleton_method :system do - system - end - - define_singleton_method :allowed_group_ids do - allowed_group_ids - end - - define_singleton_method :user_id do - user_id - end - - define_singleton_method :mentionable do - mentionable - end - - define_singleton_method :default_llm do - default_llm - end - - define_singleton_method :max_context_posts do - max_context_posts - end - - define_singleton_method :vision_enabled do - vision_enabled - end - - define_singleton_method :vision_max_pixels do - vision_max_pixels - end - - define_singleton_method :rag_conversation_chunks do - rag_conversation_chunks - end - - define_singleton_method :question_consolidator_llm do - question_consolidator_llm - end - - define_singleton_method :allow_chat do - allow_chat - end - - define_singleton_method :to_s do - "#" - end - - define_singleton_method :inspect do - "#" - end - - define_method :initialize do |*args, **kwargs| + define_method(:initialize) do |*args, **kwargs| @ai_persona = AiPersona.find_by(id: ai_persona_id) super(*args, **kwargs) end - define_method :persona_id do - @ai_persona&.id - end - - define_method :tools do - tools - end - - define_method :options do - options - end - - define_method :temperature do - @ai_persona&.temperature - end - - define_method :top_p do - @ai_persona&.top_p - end - - define_method :system_prompt do - @ai_persona&.system_prompt || "You are a helpful bot." - end - - define_method :uploads do - @ai_persona&.uploads - end + define_method(:tools) { tools } + define_method(:options) { options } + define_method(:temperature) { @ai_persona&.temperature } + define_method(:top_p) { @ai_persona&.top_p } + define_method(:system_prompt) { @ai_persona&.system_prompt || "You are a helpful bot." } + define_method(:uploads) { @ai_persona&.uploads } end end @@ -357,7 +234,7 @@ class AiPersona < ActiveRecord::Base end def system_persona_unchangeable - if top_p_changed? || temperature_changed? || system_prompt_changed? || commands_changed? || + if top_p_changed? || temperature_changed? || system_prompt_changed? || tools_changed? || name_changed? || description_changed? errors.add(:base, I18n.t("discourse_ai.ai_bot.personas.cannot_edit_system_persona")) end @@ -378,7 +255,7 @@ end # id :bigint not null, primary key # name :string(100) not null # description :string(2000) not null -# commands :json not null +# tools :json not null # system_prompt :string(10000000) not null # allowed_group_ids :integer default([]), not null, is an Array # created_by_id :integer @@ -408,6 +285,7 @@ end # role_max_responses_per_hour :integer default(50), not null # question_consolidator_llm :text # allow_chat :boolean default(FALSE), not null +# tool_details :boolean default(TRUE), not null # # Indexes # diff --git a/app/serializers/localized_ai_persona_serializer.rb b/app/serializers/localized_ai_persona_serializer.rb index a3e41b26..da6660b0 100644 --- a/app/serializers/localized_ai_persona_serializer.rb +++ b/app/serializers/localized_ai_persona_serializer.rb @@ -9,7 +9,7 @@ class LocalizedAiPersonaSerializer < ApplicationSerializer :enabled, :system, :priority, - :commands, + :tools, :system_prompt, :allowed_group_ids, :temperature, @@ -24,7 +24,8 @@ class LocalizedAiPersonaSerializer < ApplicationSerializer :rag_chunk_overlap_tokens, :rag_conversation_chunks, :question_consolidator_llm, - :allow_chat + :allow_chat, + :tool_details has_one :user, serializer: BasicUserSerializer, embed: :object has_many :rag_uploads, serializer: UploadSerializer, embed: :object diff --git a/assets/javascripts/discourse/admin/models/ai-persona.js b/assets/javascripts/discourse/admin/models/ai-persona.js index 7b06baf2..c12c461c 100644 --- a/assets/javascripts/discourse/admin/models/ai-persona.js +++ b/assets/javascripts/discourse/admin/models/ai-persona.js @@ -6,7 +6,7 @@ const CREATE_ATTRIBUTES = [ "id", "name", "description", - "commands", + "tools", "system_prompt", "allowed_group_ids", "enabled", @@ -27,6 +27,7 @@ const CREATE_ATTRIBUTES = [ "rag_conversation_chunks", "question_consolidator_llm", "allow_chat", + "tool_details", ]; const SYSTEM_ATTRIBUTES = [ @@ -48,37 +49,37 @@ const SYSTEM_ATTRIBUTES = [ "rag_conversation_chunks", "question_consolidator_llm", "allow_chat", + "tool_details", ]; -class CommandOption { +class ToolOption { @tracked value = null; } export default class AiPersona extends RestModel { // this code is here to convert the wire schema to easier to work with object - // on the wire we pass in/out commands as an Array. - // [[CommandName, {option1: value, option2: value}], CommandName2, CommandName3] - // So we rework this into a "commands" property and nested commandOptions + // on the wire we pass in/out tools as an Array. + // [[ToolName, {option1: value, option2: value}], ToolName2, ToolName3] + // So we rework this into a "tools" property and nested toolOptions init(properties) { - if (properties.commands) { - properties.commands = properties.commands.map((command) => { - if (typeof command === "string") { - return command; + if (properties.tools) { + properties.tools = properties.tools.map((tool) => { + if (typeof tool === "string") { + return tool; } else { - let [commandId, options] = command; + let [toolId, options] = tool; for (let optionId in options) { if (!options.hasOwnProperty(optionId)) { continue; } - this.getCommandOption(commandId, optionId).value = - options[optionId]; + this.getToolOption(toolId, optionId).value = options[optionId]; } - return commandId; + return toolId; } }); } super.init(properties); - this.commands = properties.commands; + this.tools = properties.tools; } async createUser() { @@ -93,23 +94,23 @@ export default class AiPersona extends RestModel { return this.user; } - getCommandOption(commandId, optionId) { - this.commandOptions ||= {}; - this.commandOptions[commandId] ||= {}; - return (this.commandOptions[commandId][optionId] ||= new CommandOption()); + getToolOption(toolId, optionId) { + this.toolOptions ||= {}; + this.toolOptions[toolId] ||= {}; + return (this.toolOptions[toolId][optionId] ||= new ToolOption()); } - populateCommandOptions(attrs) { - if (!attrs.commands) { + populateToolOptions(attrs) { + if (!attrs.tools) { return; } - let commandsWithOptions = []; - attrs.commands.forEach((commandId) => { - if (typeof commandId !== "string") { - commandId = commandId[0]; + let toolsWithOptions = []; + attrs.tools.forEach((toolId) => { + if (typeof toolId !== "string") { + toolId = toolId[0]; } - if (this.commandOptions && this.commandOptions[commandId]) { - let options = this.commandOptions[commandId]; + if (this.toolOptions && this.toolOptions[toolId]) { + let options = this.toolOptions[toolId]; let optionsWithValues = {}; for (let optionId in options) { if (!options.hasOwnProperty(optionId)) { @@ -118,12 +119,12 @@ export default class AiPersona extends RestModel { let option = options[optionId]; optionsWithValues[optionId] = option.value; } - commandsWithOptions.push([commandId, optionsWithValues]); + toolsWithOptions.push([toolId, optionsWithValues]); } else { - commandsWithOptions.push(commandId); + toolsWithOptions.push(toolId); } }); - attrs.commands = commandsWithOptions; + attrs.tools = toolsWithOptions; } updateProperties() { @@ -131,20 +132,20 @@ export default class AiPersona extends RestModel { ? this.getProperties(SYSTEM_ATTRIBUTES) : this.getProperties(CREATE_ATTRIBUTES); attrs.id = this.id; - this.populateCommandOptions(attrs); + this.populateToolOptions(attrs); return attrs; } createProperties() { let attrs = this.getProperties(CREATE_ATTRIBUTES); - this.populateCommandOptions(attrs); + this.populateToolOptions(attrs); return attrs; } workingCopy() { let attrs = this.getProperties(CREATE_ATTRIBUTES); - this.populateCommandOptions(attrs); + this.populateToolOptions(attrs); return AiPersona.create(attrs); } } diff --git a/assets/javascripts/discourse/components/ai-persona-command-options.gjs b/assets/javascripts/discourse/components/ai-persona-command-options.gjs deleted file mode 100644 index dd792ecf..00000000 --- a/assets/javascripts/discourse/components/ai-persona-command-options.gjs +++ /dev/null @@ -1,81 +0,0 @@ -import Component from "@glimmer/component"; -import I18n from "discourse-i18n"; -import AiPersonaCommandOptionEditor from "./ai-persona-command-option-editor"; - -export default class AiPersonaCommandOptions extends Component { - get showCommandOptions() { - const allCommands = this.args.allCommands; - if (!allCommands) { - return false; - } - - return this.commandNames.any( - (command) => allCommands.find((c) => c.id === command)?.options - ); - } - - get commandNames() { - if (!this.args.commands) { - return []; - } - return this.args.commands.map((command) => { - if (typeof command === "string") { - return command; - } else { - return command[0]; - } - }); - } - - get commandOptions() { - if (!this.args.commands) { - return []; - } - - const allCommands = this.args.allCommands; - if (!allCommands) { - return []; - } - - const options = []; - this.commandNames.forEach((commandId) => { - const command = allCommands.find((c) => c.id === commandId); - - const commandName = command?.name; - const commandOptions = command?.options; - - if (commandOptions) { - const mappedOptions = Object.keys(commandOptions).map((key) => { - const value = this.args.persona.getCommandOption(commandId, key); - return Object.assign({}, commandOptions[key], { id: key, value }); - }); - - options.push({ commandName, options: mappedOptions }); - } - }); - - return options; - } - - -} diff --git a/assets/javascripts/discourse/components/ai-persona-editor.gjs b/assets/javascripts/discourse/components/ai-persona-editor.gjs index cdd2eabf..a4ba5580 100644 --- a/assets/javascripts/discourse/components/ai-persona-editor.gjs +++ b/assets/javascripts/discourse/components/ai-persona-editor.gjs @@ -20,9 +20,9 @@ import AdminUser from "admin/models/admin-user"; import ComboBox from "select-kit/components/combo-box"; import GroupChooser from "select-kit/components/group-chooser"; import DTooltip from "float-kit/components/d-tooltip"; -import AiCommandSelector from "./ai-command-selector"; import AiLlmSelector from "./ai-llm-selector"; -import AiPersonaCommandOptions from "./ai-persona-command-options"; +import AiPersonaToolOptions from "./ai-persona-tool-options"; +import AiToolSelector from "./ai-tool-selector"; import PersonaRagUploader from "./persona-rag-uploader"; export default class PersonaEditor extends Component { @@ -201,21 +201,6 @@ export default class PersonaEditor extends Component { await this.toggleField("priority", true); } - @action - async toggleMentionable() { - await this.toggleField("mentionable"); - } - - @action - async toggleAllowChat() { - await this.toggleField("allow_chat"); - } - - @action - async toggleVisionEnabled() { - await this.toggleField("vision_enabled"); - } - @action async createUser() { try { @@ -303,45 +288,6 @@ export default class PersonaEditor extends Component { @content={{I18n.t "discourse_ai.ai_persona.priority_help"}} /> - {{#if this.editingModel.user}} - {{#if this.chatPluginEnabled}} -
- - -
- {{/if}} -
- - -
- {{/if}} -
- - -
{{/unless}}
- - {{I18n.t "discourse_ai.ai_persona.tools"}} +
{{#unless this.editingModel.system}} - {{/unless}}
@@ -433,6 +379,65 @@ export default class PersonaEditor extends Component { disabled={{this.editingModel.system}} />
+ {{#if this.editingModel.user}} + {{#if this.chatPluginEnabled}} +
+ + +
+ {{/if}} +
+ + +
+ {{/if}} +
+ + +
+
+ + +
+ {{#if this.editingModel.vision_enabled}} +
+ + +
+ {{/if}}
- {{#if @model.vision_enabled}} + {{#if this.showTemperature}}
- - -
- {{/if}} -
- {{#if this.showTemperature}} - {{/if}} - {{#if this.showTopP}} +
+ {{/if}} + {{#if this.showTopP}} +
- {{/if}} -
+
+ {{/if}} {{#if this.siteSettings.ai_embeddings_enabled}}
-
+
@@ -35,7 +35,7 @@ export default class AiPersonaCommandOptionEditor extends Component { {{/if}}
{{#unless this.isBoolean}} -
+
{{@option.description}}
{{/unless}} diff --git a/assets/javascripts/discourse/components/ai-persona-tool-options.gjs b/assets/javascripts/discourse/components/ai-persona-tool-options.gjs new file mode 100644 index 00000000..fde07e72 --- /dev/null +++ b/assets/javascripts/discourse/components/ai-persona-tool-options.gjs @@ -0,0 +1,79 @@ +import Component from "@glimmer/component"; +import I18n from "discourse-i18n"; +import AiPersonaToolOptionEditor from "./ai-persona-tool-option-editor"; + +export default class AiPersonaToolOptions extends Component { + get showToolOptions() { + const allTools = this.args.allTools; + if (!allTools) { + return false; + } + + return this.toolNames.any((tool) => allTools.findBy("id", tool)?.options); + } + + get toolNames() { + if (!this.args.tools) { + return []; + } + return this.args.tools.map((tool) => { + if (typeof tool === "string") { + return tool; + } else { + return tool[0]; + } + }); + } + + get toolOptions() { + if (!this.args.tools) { + return []; + } + + const allTools = this.args.allTools; + if (!allTools) { + return []; + } + + const options = []; + this.toolNames.forEach((toolId) => { + const tool = allTools.findBy("id", toolId); + + const toolName = tool?.name; + const toolOptions = tool?.options; + + if (toolOptions) { + const mappedOptions = Object.keys(toolOptions).map((key) => { + const value = this.args.persona.getToolOption(toolId, key); + return Object.assign({}, toolOptions[key], { id: key, value }); + }); + + options.push({ toolName, options: mappedOptions }); + } + }); + + return options; + } + + +} diff --git a/assets/javascripts/discourse/components/ai-command-selector.js b/assets/javascripts/discourse/components/ai-tool-selector.js similarity index 94% rename from assets/javascripts/discourse/components/ai-command-selector.js rename to assets/javascripts/discourse/components/ai-tool-selector.js index 5812c963..0060e06f 100644 --- a/assets/javascripts/discourse/components/ai-command-selector.js +++ b/assets/javascripts/discourse/components/ai-tool-selector.js @@ -7,7 +7,7 @@ export default MultiSelectComponent.extend({ }), content: computed(function () { - return this.commands; + return this.tools; }), value: "", diff --git a/assets/stylesheets/modules/ai-bot/common/ai-persona.scss b/assets/stylesheets/modules/ai-bot/common/ai-persona.scss index c7d14a9d..1a9067ab 100644 --- a/assets/stylesheets/modules/ai-bot/common/ai-persona.scss +++ b/assets/stylesheets/modules/ai-bot/common/ai-persona.scss @@ -23,7 +23,7 @@ } } -.ai-persona-command-option-editor { +.ai-persona-tool-option-editor { &__instructions { color: var(--primary-medium); font-size: var(--font-down-1); @@ -49,12 +49,12 @@ label { display: block; } - &__command-options { + &__tool-options { padding: 5px 10px 5px; border: 1px solid var(--primary-low-mid); width: 480px; } - &__command-options-name { + &__tool-options-name { margin-bottom: 10px; font-size: var(--font-down-1); } @@ -65,25 +65,16 @@ width: 500px; height: 400px; } - &__priority { - display: flex; - align-items: center; - } + + &__tool-details, + &__vision_enabled, + &__allow_chat, + &__priority, &__mentionable { display: flex; align-items: center; } - &__allow_chat { - display: flex; - align-items: center; - } - - &__vision_enabled { - display: flex; - align-items: center; - } - &__indexing-options { display: block; margin-top: 1em; diff --git a/config/locales/client.ar.yml b/config/locales/client.ar.yml index bde5f823..74df8f0d 100644 --- a/config/locales/client.ar.yml +++ b/config/locales/client.ar.yml @@ -111,7 +111,7 @@ ar: delete: حذف priority: الأولوية priority_help: يتم عرض الشخصيات ذات الأولوية للمستخدمين في أعلى قائمة الشخصيات. إذا كانت الأولوية لعدة أشخاص، فسيتم فرزهم أبجديًا. - command_options: "خيارات الأوامر" + tool_options: "خيارات الأوامر" uploads: title: "التحميلات" uploading: "جارٍ التحميل..." diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml index 936989e1..67247a19 100644 --- a/config/locales/client.de.yml +++ b/config/locales/client.de.yml @@ -169,7 +169,7 @@ de: top_p_help: Top P für die LLM, erhöhen, um die Zufälligkeit zu erhöhen (leer lassen, um die Modellvorgabe zu verwenden, in der Regel ein Wert zwischen 0,0 und 1,0) priority: Priorität priority_help: Personas mit Priorität werden den Benutzern am Anfang der Persona-Liste angezeigt. Wenn mehrere Personas Priorität haben, werden sie alphabetisch sortiert. - command_options: "Befehlsoptionen" + tool_options: "Befehlsoptionen" rag_chunk_tokens: "Chunk-Token hochladen" rag_chunk_tokens_help: "Die Anzahl der Token, die für jeden Chunk im RAG-Modell verwendet werden. Erhöhen, um die Menge des Kontexts zu erhöhen, den die KI verwenden kann. (Eine Änderung führt zu einer Neuindizierung aller Uploads)" rag_chunk_overlap_tokens: "Chunk-Überlappungs-Token hochladen" diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 132fad8b..5eaa78bb 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -131,12 +131,14 @@ en: max_context_posts: "Max Context Posts" max_context_posts_help: "The maximum number of posts to use as context for the AI when responding to a user. (empty for default)" vision_enabled: Vision Enabled - vision_enabled_help: If enabled, the AI will attempt to understand images users post in the topic, depends on the model being used supporting vision. Anthropic Claude 3 models support vision. + vision_enabled_help: If enabled, the AI will attempt to understand images users post in the topic, depends on the model being used supporting vision. Supported by latest models from Anthropic, Google, and OpenAI. vision_max_pixels: Supported image size vision_max_pixel_sizes: low: Low Quality - cheapest (256x256) medium: Medium Quality (512x512) high: High Quality - slowest (1024x1024) + tool_details: Show Tool Details + tool_details_help: Will show end users details on which tools the language model has triggered. mentionable: Allow Mentions mentionable_help: If enabled, users in allowed groups can mention this user in posts, the AI will respond as this persona. user: User @@ -154,7 +156,7 @@ en: save: Save saved: AI Persona Saved enabled: "Enabled?" - commands: Enabled Commands + tools: Enabled Tools allowed_groups: Allowed Groups confirm_delete: Are you sure you want to delete this persona? new: "New Persona" @@ -167,7 +169,7 @@ en: top_p_help: Top P to use for the LLM, increase to increase randomness (leave empty to use model default, generally a value from 0.0 to 1.0) priority: Priority priority_help: Priority personas are displayed to users at the top of the persona list. If multiple personas have priority, they will be sorted alphabetically. - command_options: "Command Options" + tool_options: "Tool Options" rag_chunk_tokens: "Upload Chunk Tokens" rag_chunk_tokens_help: "The number of tokens to use for each chunk in the RAG model. Increase to increase the amount of context the AI can use. (changing will re-index all uploads)" rag_chunk_overlap_tokens: "Upload Chunk Overlap Tokens" diff --git a/config/locales/client.es.yml b/config/locales/client.es.yml index 53484a3c..48c9a852 100644 --- a/config/locales/client.es.yml +++ b/config/locales/client.es.yml @@ -111,7 +111,7 @@ es: delete: Eliminar priority: Prioridad priority_help: Las personas prioritarias se muestran a los usuarios en la parte superior de la lista de personas. Si varias personas tienen prioridad, se ordenarán alfabéticamente. - command_options: "Opciones de comando" + tool_options: "Opciones de comando" uploads: title: "Subidos" uploading: "Subiendo..." diff --git a/config/locales/client.fi.yml b/config/locales/client.fi.yml index abdbe47a..039ae0ef 100644 --- a/config/locales/client.fi.yml +++ b/config/locales/client.fi.yml @@ -111,7 +111,7 @@ fi: delete: Poista priority: Prioriteetti priority_help: Prioriteettipersoonat näytetään käyttäjille ensimmäisinä persoonaluettelossa. Jos useilla persoonilla on prioriteetti, ne järjestetään aakkosjärjestyksessä. - command_options: "Komentoasetukset" + tool_options: "Komentoasetukset" uploads: title: "Lataukset" uploading: "Ladataan..." diff --git a/config/locales/client.fr.yml b/config/locales/client.fr.yml index aa1d9ea2..3a45829d 100644 --- a/config/locales/client.fr.yml +++ b/config/locales/client.fr.yml @@ -111,7 +111,7 @@ fr: delete: Supprimer priority: Priorité priority_help: Les personnages prioritaires sont affichés aux utilisateurs en haut de la liste des personnages. Si plusieurs personnages sont prioritaires, ils seront triés par ordre alphabétique. - command_options: "Options de commande" + tool_options: "Options de commande" uploads: title: "Fichiers envoyés" uploading: "Envoi en cours…" diff --git a/config/locales/client.he.yml b/config/locales/client.he.yml index fec09b4d..55eb6e40 100644 --- a/config/locales/client.he.yml +++ b/config/locales/client.he.yml @@ -169,7 +169,7 @@ he: top_p_help: ה־P המובילים לשימוש למודל השפה הגדול (LLM), הגדלה תגדיל את היצירתיות (אפשר להשאיר ריק לשימוש בברירת המחדל של הדגם, בדרך כלל זה ערך בין 0.0 לבין 1.0) priority: עדיפות priority_help: דמויות בעדיפות גבוהה מוצגות למשתמשים בראש רשימת הדמויות. אם מספר דמויות הן בעדיפות הן תסודרנה לפי האלפבית. - command_options: "אפשרויות פקודה" + tool_options: "אפשרויות פקודה" rag_chunk_tokens: "העלאת אסימוני חלקים" rag_chunk_tokens_help: "מספר האסימונים לשימוש לכל נתח במודל ה־RAG. הגדלה תגדיל את כמות ההקשר בו יכולה להשתמש הבינה המלאכותית. (שינוי יסדר את כל ההעלאות במפתח מחדש)" rag_chunk_overlap_tokens: "העלאת אסימוני חפיפת חלקים" diff --git a/config/locales/client.it.yml b/config/locales/client.it.yml index f73397c5..65b338c4 100644 --- a/config/locales/client.it.yml +++ b/config/locales/client.it.yml @@ -111,7 +111,7 @@ it: delete: Elimina priority: Priorità priority_help: I personaggi prioritari vengono visualizzati agli utenti nella parte superiore dell'elenco dei personaggi. Se più personaggi hanno la priorità, verranno ordinati in ordine alfabetico. - command_options: "Opzioni di comando" + tool_options: "Opzioni di comando" uploads: title: "Caricamenti" uploading: "Caricamento..." diff --git a/config/locales/client.ja.yml b/config/locales/client.ja.yml index c48a9cf2..9a7430bc 100644 --- a/config/locales/client.ja.yml +++ b/config/locales/client.ja.yml @@ -111,7 +111,7 @@ ja: delete: 削除 priority: 優先度 priority_help: 優先ペルソナはペルソナリストの先頭に表示されます。複数のペルソナが優先されている場合は、アルファベット順に並べ替えられます。 - command_options: "コマンドオプション" + tool_options: "コマンドオプション" uploads: title: "アップロード" uploading: "アップロード中..." diff --git a/config/locales/client.nl.yml b/config/locales/client.nl.yml index e3513692..c94a7409 100644 --- a/config/locales/client.nl.yml +++ b/config/locales/client.nl.yml @@ -111,7 +111,7 @@ nl: delete: Verwijderen priority: Prioriteit priority_help: Prioritaire persona's worden bovenaan de personalijst weergegeven voor gebruikers. Als meerdere persona's prioriteit hebben, worden deze alfabetisch gesorteerd. - command_options: "Opdrachtopties" + tool_options: "Opdrachtopties" uploads: title: "Uploads" uploading: "Uploaden..." diff --git a/config/locales/client.pl_PL.yml b/config/locales/client.pl_PL.yml index 9cde14bd..0ff70afa 100644 --- a/config/locales/client.pl_PL.yml +++ b/config/locales/client.pl_PL.yml @@ -137,7 +137,7 @@ pl_PL: temperature_help: Temperatura do zastosowania w LLM, zwiększ, aby zwiększyć kreatywność (pozostaw puste, aby użyć domyślnego modelu, zazwyczaj wartość od 0,0 do 2,0) priority: Priorytet priority_help: Priorytetowe persony są wyświetlane użytkownikom na górze listy person. Jeśli wiele person ma priorytet, zostaną one posortowane alfabetycznie. - command_options: "Opcje poleceń" + tool_options: "Opcje poleceń" uploads: title: "Pliki" button: "Dodaj pliki" diff --git a/config/locales/client.pt_BR.yml b/config/locales/client.pt_BR.yml index acfe47a8..f3746680 100644 --- a/config/locales/client.pt_BR.yml +++ b/config/locales/client.pt_BR.yml @@ -112,7 +112,7 @@ pt_BR: delete: Excluir priority: Prioridade priority_help: Personas de prioridade são exibidas aos(às) usuários(as) no topo da lista de personas. Se várias personas tiverem prioridade, serão escolhidas em ordem alfabética. - command_options: "Opções de comando" + tool_options: "Opções de comando" uploads: title: "Envios" uploading: "Enviando..." diff --git a/config/locales/client.ru.yml b/config/locales/client.ru.yml index 6cac182f..35d7fadb 100644 --- a/config/locales/client.ru.yml +++ b/config/locales/client.ru.yml @@ -111,7 +111,7 @@ ru: delete: Удалить priority: Приоритет priority_help: Приоритетные персоны показываются пользователям вверху списка персон. Если приоритет имеют несколько персон, они будут отсортированы в алфавитном порядке. - command_options: "Параметры команды" + tool_options: "Параметры команды" uploads: title: "Загрузки" uploading: "Загрузка…" diff --git a/config/locales/client.tr_TR.yml b/config/locales/client.tr_TR.yml index 22ff06b9..e022d51f 100644 --- a/config/locales/client.tr_TR.yml +++ b/config/locales/client.tr_TR.yml @@ -153,7 +153,7 @@ tr_TR: top_p_help: LLM için kullanılacak en yüksek P, rastgeleliği artırmak için artırın (model varsayılanını kullanmak için boş bırakın, genellikle 0.0 ila 1.0 arasında bir değer) priority: Öncelik priority_help: Öncelikli kişilikler kullanıcılara kişilik listesinin en üstünde gösterilir. Birden fazla kişiliğin önceliği varsa bunlar alfabetik olarak sıralanır. - command_options: "Komut Seçenekleri" + tool_options: "Komut Seçenekleri" what_are_personas: "Yapay Zeka Personaları nedir?" no_persona_selected: | YZ Kişilikleri, Discourse forumunuzda YZ motorunun davranışını özelleştirebilmenizi sağlayan güçlü bir özelliktir. YZ'nin yanıt ve etkileşimlerine rehberlik eden bir "sistem mesajı" görevi görerek daha kişiselleştirilmiş ve etkileşimli bir kullanıcı deneyimi oluşturmaya yardımcı olurlar. diff --git a/config/locales/client.zh_CN.yml b/config/locales/client.zh_CN.yml index a45116d6..b0a35a55 100644 --- a/config/locales/client.zh_CN.yml +++ b/config/locales/client.zh_CN.yml @@ -128,7 +128,7 @@ zh_CN: top_p_help: 用于 LLM 的 Top P,增大它可提升创造力(留空以使用模型默认值,通常为 0.0 到 1.0 之间的值) priority: 优先 priority_help: 优先角色会在角色列表的顶部向用户显示。如果多个角色都具有优先级,将按字母顺序排序。 - command_options: "命令选项" + tool_options: "命令选项" uploads: title: "上传" uploading: "正在上传…" diff --git a/config/locales/server.ar.yml b/config/locales/server.ar.yml index 42b1f764..1d17b507 100644 --- a/config/locales/server.ar.yml +++ b/config/locales/server.ar.yml @@ -151,7 +151,7 @@ ar: topic_not_found: "الملخص غير متوفر، الموضوع غير موجود!" summarizing: "جارٍ تلخيص الموضوع" searching: "جارٍ البحث عن: '%{query}'" - command_options: + tool_options: search: max_results: name: "الحد الأقصى لعدد النتائج" @@ -159,7 +159,7 @@ ar: base_query: name: "استعلام البحث الأساسي" description: "استعلام البحث الأساسي الذي سيتم استخدامه عند البحث. على سبيل المثال: سيسبق \"#urgent\" \"#urgent\" في استعلام البحث وسيتضمن الموضوعات ذات الفئة أو الوسم العاجل فقط." - command_summary: + tool_summary: categories: "إدراج الفئات" search: "البحث" tags: "إدراج الوسوم" @@ -172,7 +172,7 @@ ar: schema: "البحث عن مخطط قاعدة البيانات" search_settings: "جارٍ البحث في إعدادات الموقع" dall_e: "إنشاء صورة" - command_help: + tool_help: categories: "إدراج جميع الفئات المرئية بشكلٍ عام في المنتدى" search: "البحث في جميع الموضوعات العامة في المنتدى" tags: "إدراج جميع الوسوم في المنتدى" @@ -185,7 +185,7 @@ ar: schema: "البحث عن مخطط قاعدة البيانات" search_settings: "البحث في إعدادات الموقع" dall_e: "إنشاء صورة باستخدام DALL-E 3" - command_description: + tool_description: read: "القراءة: %{title}" time: "الوقت في المنطقة الزمنية %{timezone} هو %{time}" summarize: "تم تلخيص %{title}" diff --git a/config/locales/server.be.yml b/config/locales/server.be.yml index e362d6a7..fbad8ce9 100644 --- a/config/locales/server.be.yml +++ b/config/locales/server.be.yml @@ -7,7 +7,7 @@ be: discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Пошук" sentiment: reports: diff --git a/config/locales/server.bg.yml b/config/locales/server.bg.yml index 18617be4..93eb07fa 100644 --- a/config/locales/server.bg.yml +++ b/config/locales/server.bg.yml @@ -10,7 +10,7 @@ bg: yaxis: "Дата" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Търсене" time: "Време " summarize: "Обобщаване" diff --git a/config/locales/server.bs_BA.yml b/config/locales/server.bs_BA.yml index 1b75d4c9..d7c2b3ac 100644 --- a/config/locales/server.bs_BA.yml +++ b/config/locales/server.bs_BA.yml @@ -10,6 +10,6 @@ bs_BA: yaxis: "Datum" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Pretraži" time: "Vrijeme" diff --git a/config/locales/server.ca.yml b/config/locales/server.ca.yml index 8e0619d3..f7e4f181 100644 --- a/config/locales/server.ca.yml +++ b/config/locales/server.ca.yml @@ -10,7 +10,7 @@ ca: yaxis: "Data" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Cerca" time: "Hora" sentiment: diff --git a/config/locales/server.cs.yml b/config/locales/server.cs.yml index 2e6e6cc5..f1f6031d 100644 --- a/config/locales/server.cs.yml +++ b/config/locales/server.cs.yml @@ -10,7 +10,7 @@ cs: yaxis: "Datum" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Vyhledat" tags: "Seznam značek" time: "Čas" diff --git a/config/locales/server.da.yml b/config/locales/server.da.yml index 89e3cd45..da063cae 100644 --- a/config/locales/server.da.yml +++ b/config/locales/server.da.yml @@ -10,7 +10,7 @@ da: yaxis: "Dato" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Søg" time: "Tidspunkt" sentiment: diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml index 9607a333..86e44b71 100644 --- a/config/locales/server.de.yml +++ b/config/locales/server.de.yml @@ -193,7 +193,7 @@ de: topic_not_found: "Zusammenfassung nicht verfügbar, Thema nicht gefunden!" summarizing: "Thema zusammenfassen" searching: "Suche nach: „%{query}“" - command_options: + tool_options: search: search_private: name: "Suche Privat" @@ -204,7 +204,7 @@ de: base_query: name: "Basissuchanfrage" description: "Basisanfrage, die bei der Suche verwendet wird. Beispiel: Bei „#dringend“ wird der Suchanfrage „#dringend“ vorangestellt und es werden nur Themen mit der Kategorie oder dem Schlagwort „dringend“ angezeigt." - command_summary: + tool_summary: web_browser: "Web durchsuchen" github_search_files: "GitHub Datei-Suche" github_search_code: "GitHub Code-Suche" @@ -225,7 +225,7 @@ de: dall_e: "Bild generieren" search_meta_discourse: "Suche Meta Discourse" javascript_evaluator: "JavaScript auswerten" - command_help: + tool_help: web_browser: "Webseite mit dem KI Bot durchsuchen" github_search_code: "Suche nach Code in einem GitHub-Repository" github_search_files: "Suche nach Dateien in einem GitHub-Repository" @@ -246,7 +246,7 @@ de: dall_e: "Bild mit DALL-E 3 generieren" search_meta_discourse: "Suche Meta Discourse" javascript_evaluator: "JavaScript auswerten" - command_description: + tool_description: web_browser: "Lesen %{url}" github_search_files: "Gesucht wurde nach '%{keywords}' in %{repo}/%{branch}" github_search_code: "Gesucht wurde nach '%{query}' in %{repo}" diff --git a/config/locales/server.el.yml b/config/locales/server.el.yml index 3b25de83..1821c9b7 100644 --- a/config/locales/server.el.yml +++ b/config/locales/server.el.yml @@ -10,6 +10,6 @@ el: yaxis: "Ημερομηνία" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Αναζήτηση" time: "Ώρα" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 2bb29c83..50b90e5a 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -175,7 +175,7 @@ en: personas: default_llm_required: "Default LLM model is required prior to enabling Chat" cannot_delete_system_persona: "System personas cannot be deleted, please disable it instead" - cannot_edit_system_persona: "System personas can only be renamed, you may not edit commands or system prompt, instead disable and make a copy" + cannot_edit_system_persona: "System personas can only be renamed, you may not edit tools or system prompt, instead disable and make a copy" github_helper: name: "GitHub Helper" description: "AI Bot specialized in assisting with GitHub-related tasks and questions" @@ -206,7 +206,7 @@ en: topic_not_found: "Summary unavailable, topic not found!" summarizing: "Summarizing topic" searching: "Searching for: '%{query}'" - command_options: + tool_options: search: search_private: name: "Search Private" @@ -217,7 +217,7 @@ en: base_query: name: "Base Search Query" description: "Base query to use when searching. Example: '#urgent' will prepend '#urgent' to the search query and only include topics with the urgent category or tag." - command_summary: + tool_summary: web_browser: "Browse Web" github_search_files: "GitHub search files" github_search_code: "GitHub code search" @@ -238,7 +238,7 @@ en: dall_e: "Generate image" search_meta_discourse: "Search Meta Discourse" javascript_evaluator: "Evaluate JavaScript" - command_help: + tool_help: web_browser: "Browse web page using the AI Bot" github_search_code: "Search for code in a GitHub repository" github_search_files: "Search for files in a GitHub repository" @@ -259,7 +259,7 @@ en: dall_e: "Generate image using DALL-E 3" search_meta_discourse: "Search Meta Discourse" javascript_evaluator: "Evaluate JavaScript" - command_description: + tool_description: web_browser: "Reading %{url}" github_search_files: "Searched for '%{keywords}' in %{repo}/%{branch}" github_search_code: "Searched for '%{query}' in %{repo}" diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml index 18a7ba3a..395a5fbc 100644 --- a/config/locales/server.es.yml +++ b/config/locales/server.es.yml @@ -151,7 +151,7 @@ es: topic_not_found: "¡Resumen no disponible, tema no encontrado!" summarizing: "Resumiendo tema" searching: "Buscando: '%{query}'" - command_options: + tool_options: search: max_results: name: "Número máximo de resultados" @@ -159,7 +159,7 @@ es: base_query: name: "Consulta de búsqueda básica" description: "Consulta base a utilizar en la búsqueda. Ejemplo: «#urgente» antepondrá «#urgente» a la consulta de búsqueda y solo incluirá temas con la categoría o etiqueta urgente." - command_summary: + tool_summary: categories: "Lista de categorías" search: "Buscar" tags: "Listar etiquetas" @@ -172,7 +172,7 @@ es: schema: "Buscar esquema de base de datos" search_settings: "Buscando los ajustes del sitio" dall_e: "Generar imagen" - command_help: + tool_help: categories: "Listar todas las categorías visibles públicamente en el foro" search: "Buscar todos los temas públicos en el foro." tags: "Listar todas las etiquetas en el foro" @@ -185,7 +185,7 @@ es: schema: "Buscar esquema de base de datos" search_settings: "Buscar ajustes del sitio" dall_e: "Generar imagen usando DALL-E 3" - command_description: + tool_description: read: "Leyendo: %{title}" time: "La hora en %{timezone} es %{time}" summarize: "Resumido %{title}" diff --git a/config/locales/server.et.yml b/config/locales/server.et.yml index bca01158..a6afdb20 100644 --- a/config/locales/server.et.yml +++ b/config/locales/server.et.yml @@ -10,7 +10,7 @@ et: yaxis: "Date" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Otsi" time: "Aeg" sentiment: diff --git a/config/locales/server.fa_IR.yml b/config/locales/server.fa_IR.yml index 3efece9d..4a00368f 100644 --- a/config/locales/server.fa_IR.yml +++ b/config/locales/server.fa_IR.yml @@ -19,7 +19,7 @@ fa_IR: personas: dall_e3: name: "DALL-E 3" - command_summary: + tool_summary: categories: "فهرست دسته‌بندی‌ها" search: "جستجو" tags: "فهرست برچسب‌ها" @@ -28,7 +28,7 @@ fa_IR: image: "تولید تصویر" google: "جستجو در گوگل" dall_e: "تولید تصویر" - command_description: + tool_description: summarize: "خلاصه شده %{title}" dall_e: "%{prompt}" image: "%{prompt}" diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml index b8d1ec64..fdc74957 100644 --- a/config/locales/server.fi.yml +++ b/config/locales/server.fi.yml @@ -151,7 +151,7 @@ fi: topic_not_found: "Yhteenveto ei ole saatavilla, ketjua ei löydy!" summarizing: "Laaditaan yhteenvetoa ketjusta" searching: "Haetaan: \"%{query}\"" - command_options: + tool_options: search: max_results: name: "Tulosten enimmäismäärä" @@ -159,7 +159,7 @@ fi: base_query: name: "Perushakukysely" description: "Peruskysely, jota käytetään haussa. Esimerkki: \"#kiireellinen\" lisää hakukyselyn alkuun \"#kiireellinen\" ja sisältää vain ketjut, joissa on kiireellinen alue tai tunniste." - command_summary: + tool_summary: categories: "Listaa alueet" search: "Haku" tags: "Listaa tunnisteet" @@ -172,7 +172,7 @@ fi: schema: "Etsi tietokantaskeema" search_settings: "Haetaan sivustoasetuksia" dall_e: "Luo kuva" - command_help: + tool_help: categories: "Listaa kaikki foorumin julkisesti näkyvät alueet" search: "Hae kaikista foorumin julkisista ketjuista" tags: "Listaa kaikki foorumin tunnisteet" @@ -185,7 +185,7 @@ fi: schema: "Etsi tietokantaskeema" search_settings: "Hae sivustoasetuksia" dall_e: "Luo kuva DALL-E 3:lla" - command_description: + tool_description: read: "Luetaan: %{title}" time: "Aika aikavyöhykkeellä %{timezone} on %{time}" summarize: "Yhteenveto: %{title}" diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml index e2eb0dab..59d34eaa 100644 --- a/config/locales/server.fr.yml +++ b/config/locales/server.fr.yml @@ -151,7 +151,7 @@ fr: topic_not_found: "Résumé indisponible, sujet introuvable !" summarizing: "Synthèse du sujet" searching: "Recherche de : '%{query}'" - command_options: + tool_options: search: max_results: name: "Nombre maximal de résultats" @@ -159,7 +159,7 @@ fr: base_query: name: "Requête de recherche de base" description: "Requête de base à utiliser lors de la recherche. Exemple : « #urgent » ajoutera « #urgent » à la requête de recherche et inclura uniquement les sujets avec la catégorie ou l'étiquette correspondante." - command_summary: + tool_summary: categories: "Lister les catégories" search: "Rechercher" tags: "Répertorier les étiquettes" @@ -172,7 +172,7 @@ fr: schema: "Rechercher le schéma de la base de données" search_settings: "Recherche des paramètres du site" dall_e: "Générer une image" - command_help: + tool_help: categories: "Répertoriez toutes les catégories visibles publiquement sur le forum" search: "Rechercher dans tous les sujets publics sur le forum" tags: "Répertorier toutes les étiquettes du forum" @@ -185,7 +185,7 @@ fr: schema: "Rechercher le schéma de la base de données" search_settings: "Paramètres du site de recherche" dall_e: "Générer une image à l'aide de DALL-E 3" - command_description: + tool_description: read: "Lecture : %{title}" time: "L'heure (%{timezone}) est %{time}" summarize: "Résumé de %{title}" diff --git a/config/locales/server.gl.yml b/config/locales/server.gl.yml index a5e54742..a48e0d6e 100644 --- a/config/locales/server.gl.yml +++ b/config/locales/server.gl.yml @@ -10,7 +10,7 @@ gl: yaxis: "Data" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Buscar" time: "Hora" sentiment: diff --git a/config/locales/server.he.yml b/config/locales/server.he.yml index 57c00e5a..fc8fc943 100644 --- a/config/locales/server.he.yml +++ b/config/locales/server.he.yml @@ -192,7 +192,7 @@ he: topic_not_found: "תקציר לא זמין, לא נמצא נושא!" summarizing: "הנושא מסוכם" searching: "חיפוש אחר: ‚%{query}’" - command_options: + tool_options: search: search_private: name: "חיפוש פרטי" @@ -203,7 +203,7 @@ he: base_query: name: "שאילתת חיפוש בסיסית" description: "שאילתת בסיס לשימוש בעת חיפוש. למשל: ‚‎#urgent’ יוסיף את ‚‎#urgent’ לשאילתת החיפוש ויכלול רק נושאים עם הקטגוריה או התגית urgent (דחוף)." - command_summary: + tool_summary: web_browser: "גלישה באינטרנט" github_search_files: "חיפוש קבצים ב־GitHub" github_search_code: "חיפוש קוד ב־GitHub" @@ -224,7 +224,7 @@ he: dall_e: "יצירת תמונה" search_meta_discourse: "חיפוש ב־Meta Discrouse" javascript_evaluator: "שערוך JavaScript" - command_help: + tool_help: web_browser: "גלישה באינטרנט באמצעות בוט בינה מלאכותית" github_search_code: "חיפוש אחר קוד במאגר GitHub" github_search_files: "חיפוש אחר קבצים במאגר GitHub" @@ -245,7 +245,7 @@ he: dall_e: "יצירת תמונה באמצעות DALL-E 3" search_meta_discourse: "חיפוש ב־Meta Discrouse" javascript_evaluator: "שערוך JavaScript" - command_description: + tool_description: web_browser: "קורא את %{url}" github_search_files: "בוצע חיפוש אחר ‚%{keywords}’ בתוך %{repo}/%{branch}" github_search_code: "בוצע חיפוש אחר ‚%{query}’ בתוך %{repo}" diff --git a/config/locales/server.hr.yml b/config/locales/server.hr.yml index 01932825..7ec9cb20 100644 --- a/config/locales/server.hr.yml +++ b/config/locales/server.hr.yml @@ -10,7 +10,7 @@ hr: yaxis: "Datum" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Pretraživanje" time: "Vrijeme" summarize: "Rezimirati" diff --git a/config/locales/server.hu.yml b/config/locales/server.hu.yml index 1bead8d6..b36bfe99 100644 --- a/config/locales/server.hu.yml +++ b/config/locales/server.hu.yml @@ -10,7 +10,7 @@ hu: yaxis: "Dátum" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Keresés" tags: "Címkék listázása" time: "Idő" diff --git a/config/locales/server.hy.yml b/config/locales/server.hy.yml index c045d42c..adbc0b07 100644 --- a/config/locales/server.hy.yml +++ b/config/locales/server.hy.yml @@ -10,7 +10,7 @@ hy: yaxis: "Ամսաթիվ" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Որոնում" time: "Ժամ" sentiment: diff --git a/config/locales/server.id.yml b/config/locales/server.id.yml index ab67880d..b4935116 100644 --- a/config/locales/server.id.yml +++ b/config/locales/server.id.yml @@ -71,19 +71,19 @@ id: ai_bot: personas: default_llm_required: "Model LLM default diperlukan sebelum mengaktifkan Obrolan" - command_options: + tool_options: search: search_private: name: "Pencarian Pribadi" description: "Sertakan semua topik yang dapat diakses pengguna dalam hasil pencarian (secara bawaan hanya topik publik yang disertakan)" - command_summary: + tool_summary: github_search_files: "File pencarian GitHub" search: "Cari" time: "Waktu" summarize: "Meringkas" - command_help: + tool_help: github_search_files: "Cari file di repositori GitHub" summary: "Meringkas suatu topik" - command_description: + tool_description: github_search_files: "Mencari '%{keywords}' di %{repo}/%{branch}" github_search_code: "Mencari '%{query}' di %{repo}" diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml index 5871619f..408e44e0 100644 --- a/config/locales/server.it.yml +++ b/config/locales/server.it.yml @@ -151,7 +151,7 @@ it: topic_not_found: "Riepilogo non disponibile, argomento non trovato!" summarizing: "Riepilogo argomento" searching: "Ricerca di: '%{query}'" - command_options: + tool_options: search: max_results: name: "Numero massimo di risultati" @@ -159,7 +159,7 @@ it: base_query: name: "Query di ricerca di base" description: "Query di base da utilizzare durante la ricerca. Esempio: \"#urgente\" anteporrà \"#urgente\" alla query di ricerca e includerà solo gli argomenti con la categoria o l'etichetta urgente." - command_summary: + tool_summary: categories: "Elenca le categorie" search: "Cerca" tags: "Elenca le etichette" @@ -172,7 +172,7 @@ it: schema: "Cerca lo schema del database" search_settings: "Ricerca nelle impostazioni del sito" dall_e: "Genera immagine" - command_help: + tool_help: categories: "Elenca tutte le categorie visibili pubblicamente sul forum" search: "Cerca tutti gli argomenti pubblici sul forum" tags: "Elenca tutte le etichette sul forum" @@ -185,7 +185,7 @@ it: schema: "Cerca lo schema del database" search_settings: "Cerca le impostazioni del sito" dall_e: "Genera immagine utilizzando DALL-E 3" - command_description: + tool_description: read: "Lettura: %{title}" time: "L'orario in %{timezone} è %{time}" summarize: "Riassunto di %{title}" diff --git a/config/locales/server.ja.yml b/config/locales/server.ja.yml index 804516e5..fda5bd52 100644 --- a/config/locales/server.ja.yml +++ b/config/locales/server.ja.yml @@ -151,7 +151,7 @@ ja: topic_not_found: "要約がありません。トピックが見つかりません!" summarizing: "トピックの要約を生成中" searching: "検索中: '%{query}'" - command_options: + tool_options: search: max_results: name: "結果の最大件数" @@ -159,7 +159,7 @@ ja: base_query: name: "ベース検索クエリ" description: "検索時に使用するベースクエリ。例: '#urgent' は検索クエリの先頭に '#urgent' を追加し、緊急のカテゴリまたはタグを持つトピックのみが含まれます。" - command_summary: + tool_summary: categories: "カテゴリをリスト表示" search: "検索" tags: "タグをリスト" @@ -172,7 +172,7 @@ ja: schema: "データベーススキーマを検索" search_settings: "サイト設定を検索中" dall_e: "画像を生成" - command_help: + tool_help: categories: "フォーラムのすべての公開カテゴリをリストします" search: "フォーラムのすべての公開トピックを検索します" tags: "フォーラムのすべてのタグをリストします" @@ -185,7 +185,7 @@ ja: schema: "データベーススキーマを検索します" search_settings: "サイト設定を検索します" dall_e: "DALL-E 3 を使って画像を生成します" - command_description: + tool_description: read: "読み取り中: %{title}" time: "%{timezone} の時刻は %{time} です" summarize: "%{title} の要約" diff --git a/config/locales/server.ko.yml b/config/locales/server.ko.yml index 73db1035..7c1e5fbc 100644 --- a/config/locales/server.ko.yml +++ b/config/locales/server.ko.yml @@ -10,7 +10,7 @@ ko: yaxis: "날짜" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "검색" time: "시간" summarize: "요약하기" diff --git a/config/locales/server.lt.yml b/config/locales/server.lt.yml index 73c5deac..0f058a31 100644 --- a/config/locales/server.lt.yml +++ b/config/locales/server.lt.yml @@ -17,7 +17,7 @@ lt: image_caption: attribution: "Antraštė teikiama AI" ai_bot: - command_summary: + tool_summary: search: "Paieška" time: "Laikas" summarize: "Apibendrinti" diff --git a/config/locales/server.lv.yml b/config/locales/server.lv.yml index 465092ed..3de3db75 100644 --- a/config/locales/server.lv.yml +++ b/config/locales/server.lv.yml @@ -10,6 +10,6 @@ lv: yaxis: "Datums" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Meklēt" time: "Laiks" diff --git a/config/locales/server.nb_NO.yml b/config/locales/server.nb_NO.yml index 7329b136..4392908d 100644 --- a/config/locales/server.nb_NO.yml +++ b/config/locales/server.nb_NO.yml @@ -10,6 +10,6 @@ nb_NO: yaxis: "Dato" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Søk" time: "Tid" diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml index 29cc4db8..4431a359 100644 --- a/config/locales/server.nl.yml +++ b/config/locales/server.nl.yml @@ -151,7 +151,7 @@ nl: topic_not_found: "Samenvatting niet beschikbaar, topic niet gevonden!" summarizing: "Topic samenvatten" searching: "Zoeken naar: '%{query}'" - command_options: + tool_options: search: max_results: name: "Maximaal aantal resultaten" @@ -159,7 +159,7 @@ nl: base_query: name: "Basiszoekopdracht" description: "Basisquery om te gebruiken bij het zoeken. Voorbeeld: '#urgent' voegt '#urgent' toe aan de zoekquery en neemt alleen topics mee met de categorie of tag 'urgent'." - command_summary: + tool_summary: categories: "Categorieën weergeven" search: "Zoeken" tags: "Tags weergeven" @@ -172,7 +172,7 @@ nl: schema: "Databaseschema opzoeken" search_settings: "Zoeken in site-instellingen" dall_e: "Afbeelding genereren" - command_help: + tool_help: categories: "Geef een lijst weer van alle openbaar zichtbare categorieën op het forum" search: "Doorzoek alle openbare topics op het forum" tags: "Geef een lijst weer van alle tags op het forum" @@ -185,7 +185,7 @@ nl: schema: "Zoek een databaseschema op" search_settings: "Zoek site-instellingen" dall_e: "Genereer een afbeelding met DALL-E 3" - command_description: + tool_description: read: "Lezen: %{title}" time: "De tijd in %{timezone} is %{time}" summarize: "%{title} samengevat" diff --git a/config/locales/server.pl_PL.yml b/config/locales/server.pl_PL.yml index ff970682..da1f9dd9 100644 --- a/config/locales/server.pl_PL.yml +++ b/config/locales/server.pl_PL.yml @@ -150,7 +150,7 @@ pl_PL: topic_not_found: "Podsumowanie niedostępne, nie znaleziono tematu!" summarizing: "Podsumowanie tematu" searching: "Wyszukiwanie: '%{query}'" - command_options: + tool_options: search: max_results: name: "Maksymalna liczba wyników" @@ -158,7 +158,7 @@ pl_PL: base_query: name: "Podstawowe zapytanie wyszukiwania" description: "Podstawowe zapytanie używane podczas wyszukiwania. Przykład: '#pilne' spowoduje dodanie '#pilne' do zapytania wyszukiwania i uwzględnienie tylko tematów z kategorią lub tagiem pilne." - command_summary: + tool_summary: random_picker: "Losowy selektor" categories: "Wymień kategorie" search: "Szukaj" @@ -172,7 +172,7 @@ pl_PL: schema: "Wyszukaj schemat bazy danych" search_settings: "Wyszukiwanie ustawień witryny" dall_e: "Wygeneruj obraz" - command_help: + tool_help: random_picker: "Wybierz losową liczbę lub losowy element listy" categories: "Wyświetl wszystkie publicznie widoczne kategorie na forum" search: "Przeszukaj wszystkie publiczne tematy na forum" @@ -186,7 +186,7 @@ pl_PL: schema: "Wyszukaj schemat bazy danych" search_settings: "Wyszukaj ustawienia witryny" dall_e: "Wygeneruj obraz za pomocą DALL-E 3" - command_description: + tool_description: random_picker: "Wybieranie z %{options}, wybrane: %{result}" read: "Czytanie: %{title}" time: "Czas w %{timezone} wynosi %{time}" diff --git a/config/locales/server.pt.yml b/config/locales/server.pt.yml index 85273b2d..a6c9ed58 100644 --- a/config/locales/server.pt.yml +++ b/config/locales/server.pt.yml @@ -10,7 +10,7 @@ pt: yaxis: "Data" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Pesquisar" time: "Hora" summarize: "Resumir" diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml index 2aa52082..793dc1a8 100644 --- a/config/locales/server.pt_BR.yml +++ b/config/locales/server.pt_BR.yml @@ -151,7 +151,7 @@ pt_BR: topic_not_found: "Resumo indisponível, tópico não encontrado!" summarizing: "Resumindo tópico" searching: "Pesquisando: \"%{query}\"" - command_options: + tool_options: search: max_results: name: "O número máximo de resultados" @@ -159,7 +159,7 @@ pt_BR: base_query: name: "Consulta de pesquisa básica" description: "A consulta de base para usar ao pesquisar. Exemplo: \"#urgent\" precederá \"#urgent\" para a consulta de pesquisa e incluirá apenas tópicos com a etiqueta ou categoria urgente." - command_summary: + tool_summary: categories: "Listar categorias" search: "Pesquisar" tags: "Listar etiquetas" @@ -172,7 +172,7 @@ pt_BR: schema: "Procurar esquema de banco de dados" search_settings: "Pesquisando configurações do site" dall_e: "Gerar imagem" - command_help: + tool_help: categories: "Listar todas as categorias visíveis publicamente no fórum" search: "Pesquisar todos os tópicos públicos no fórum" tags: "Listar todas as etiquetas no fórum" @@ -185,7 +185,7 @@ pt_BR: schema: "Procurar esquema de banco de dados" search_settings: "Pesquisar configurações do site" dall_e: "Gerar imagem usando DALL-E 3" - command_description: + tool_description: read: "Lendo: %{title}" time: "A hora em %{timezone} é %{time}" summarize: "Resumo de %{title}" diff --git a/config/locales/server.ro.yml b/config/locales/server.ro.yml index bb322f76..8b453e78 100644 --- a/config/locales/server.ro.yml +++ b/config/locales/server.ro.yml @@ -10,7 +10,7 @@ ro: yaxis: "Dată" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Caută" time: "Oră" summarize: "Rezumat" diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml index 2fb470e2..d15c6a3a 100644 --- a/config/locales/server.ru.yml +++ b/config/locales/server.ru.yml @@ -151,7 +151,7 @@ ru: topic_not_found: "Сводка недоступна: тема не найдена!" summarizing: "Аналитик темы" searching: "Поиск: '%{query}'" - command_options: + tool_options: search: max_results: name: "Максимальное количество результатов" @@ -159,7 +159,7 @@ ru: base_query: name: "Базовый поисковый запрос" description: "Базовый запрос, используемый при поиске. Пример: '#urgent' добавит '#urgent' к поисковому запросу и будет включать только темы со срочной категорией или тегом." - command_summary: + tool_summary: categories: "Вывод списка категорий" search: "Поиск" tags: "Вывод списка тегов" @@ -172,7 +172,7 @@ ru: schema: "Найти схему базы данных" search_settings: "Поиск настроек сайта" dall_e: "Сгенерировать изображение" - command_help: + tool_help: categories: "Вывод всех общедоступных категорий на форуме" search: "Поиск по всем общедоступным темам на форуме" tags: "Вывод всех тегов на форуме" @@ -185,7 +185,7 @@ ru: schema: "Найти схему базы данных" search_settings: "Настройки поиска по сайту" dall_e: "Создать изображение с помощью DALL-E 3" - command_description: + tool_description: read: "Чтение: %{title}" time: "Время по часовому поясу %{timezone} — %{time}" summarize: "Получена сводка: %{title}" diff --git a/config/locales/server.sk.yml b/config/locales/server.sk.yml index 739a75b5..092e3e5f 100644 --- a/config/locales/server.sk.yml +++ b/config/locales/server.sk.yml @@ -10,7 +10,7 @@ sk: yaxis: "Dátum" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Hľadať" tags: "Zoznam značiek" time: "Čas" diff --git a/config/locales/server.sl.yml b/config/locales/server.sl.yml index 60c61b8b..cda98ac1 100644 --- a/config/locales/server.sl.yml +++ b/config/locales/server.sl.yml @@ -10,6 +10,6 @@ sl: yaxis: "Datum" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Išči" time: "Čas" diff --git a/config/locales/server.sq.yml b/config/locales/server.sq.yml index 974f06b4..4c01ab00 100644 --- a/config/locales/server.sq.yml +++ b/config/locales/server.sq.yml @@ -7,6 +7,6 @@ sq: discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Kërko" time: "Koha" diff --git a/config/locales/server.sr.yml b/config/locales/server.sr.yml index 8412922a..b62eb641 100644 --- a/config/locales/server.sr.yml +++ b/config/locales/server.sr.yml @@ -7,6 +7,6 @@ sr: discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Pretraži" time: "Vreme" diff --git a/config/locales/server.sv.yml b/config/locales/server.sv.yml index 8f61ee4d..e5c0bfb8 100644 --- a/config/locales/server.sv.yml +++ b/config/locales/server.sv.yml @@ -10,7 +10,7 @@ sv: yaxis: "Datum" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Sök" time: "Tid" summarize: "Sammanfatta" diff --git a/config/locales/server.sw.yml b/config/locales/server.sw.yml index 5c83c4d9..87f11162 100644 --- a/config/locales/server.sw.yml +++ b/config/locales/server.sw.yml @@ -10,6 +10,6 @@ sw: yaxis: "Tarehe" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Tafuta" time: "Muda" diff --git a/config/locales/server.te.yml b/config/locales/server.te.yml index 5713ad06..0bd17219 100644 --- a/config/locales/server.te.yml +++ b/config/locales/server.te.yml @@ -10,7 +10,7 @@ te: yaxis: "తేదీ" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "వెతుకు" time: "కాలం" sentiment: diff --git a/config/locales/server.th.yml b/config/locales/server.th.yml index 5ff92f58..0ac2daff 100644 --- a/config/locales/server.th.yml +++ b/config/locales/server.th.yml @@ -10,6 +10,6 @@ th: yaxis: "วันที่" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "ค้นหา" time: "เวลา" diff --git a/config/locales/server.tr_TR.yml b/config/locales/server.tr_TR.yml index 0a9f2bf4..edd8ca1f 100644 --- a/config/locales/server.tr_TR.yml +++ b/config/locales/server.tr_TR.yml @@ -187,7 +187,7 @@ tr_TR: topic_not_found: "Özet mevcut değil, konu bulunamadı!" summarizing: "Konu özetleniyor" searching: "Aranıyor: '%{query}'" - command_options: + tool_options: search: max_results: name: "Maksimum sonuç sayısı" @@ -195,7 +195,7 @@ tr_TR: base_query: name: "Temel Arama Sorgusu" description: "Arama yaparken kullanılacak temel sorgu. Örnek: '#urgent', arama sorgusuna '#urgent' ekler ve yalnızca acil kategorisine veya etiketine sahip konuları içerir." - command_summary: + tool_summary: web_browser: "Web'e Gözat" github_search_code: "GitHub kodu arama" github_file_content: "GitHub dosya içeriği" @@ -214,7 +214,7 @@ tr_TR: search_settings: "Site ayarları aranıyor" dall_e: "Görüntü oluştur" search_meta_discourse: "Discourse Metada arama yapın" - command_help: + tool_help: web_browser: "Yapay Zeka Botunu kullanarak web sayfasına göz atın" github_search_code: "GitHub deposunda kod arama" github_file_content: "Bir GitHub deposundan dosyaların içeriğini alma" @@ -233,7 +233,7 @@ tr_TR: search_settings: "Site ayarlarını ara" dall_e: "DALL-E 3 kullanarak görüntü oluştur" search_meta_discourse: "Discourse Metada arama yapın" - command_description: + tool_description: web_browser: "Okunuyor %{url}" github_search_code: "%{repo} içinde '%{query}' araması yapıldı" github_pull_request_diff: "%{repo} %{pull_id}" diff --git a/config/locales/server.ug.yml b/config/locales/server.ug.yml index fca0aefd..1c3ba554 100644 --- a/config/locales/server.ug.yml +++ b/config/locales/server.ug.yml @@ -10,7 +10,7 @@ ug: yaxis: "چېسلا" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "ئىزدە" tags: "بەلگە تىزىمىنى كۆرسىتىدۇ" time: "ۋاقىت" diff --git a/config/locales/server.uk.yml b/config/locales/server.uk.yml index 99081ca5..e5e2dee9 100644 --- a/config/locales/server.uk.yml +++ b/config/locales/server.uk.yml @@ -10,7 +10,7 @@ uk: yaxis: "Дата" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Пошук" tags: "Список тегів" time: "Час" diff --git a/config/locales/server.ur.yml b/config/locales/server.ur.yml index 0f3bf0a8..e4a07ccd 100644 --- a/config/locales/server.ur.yml +++ b/config/locales/server.ur.yml @@ -10,7 +10,7 @@ ur: yaxis: "تاریخ" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "تلاش کریں" time: "وقت" summarize: "خلاصہ" diff --git a/config/locales/server.vi.yml b/config/locales/server.vi.yml index 37b25825..7b63e1d2 100644 --- a/config/locales/server.vi.yml +++ b/config/locales/server.vi.yml @@ -10,7 +10,7 @@ vi: yaxis: "Ngày" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "Tìm kiếm" time: "Thời gian" summarize: "Tóm tắt" diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml index 9a76e0ae..8c5ab281 100644 --- a/config/locales/server.zh_CN.yml +++ b/config/locales/server.zh_CN.yml @@ -154,7 +154,7 @@ zh_CN: topic_not_found: "总结不可用,找不到话题!" summarizing: "正在总结话题" searching: "搜索:'%{query}'" - command_options: + tool_options: search: max_results: name: "最大结果数" @@ -162,7 +162,7 @@ zh_CN: base_query: name: "基本搜索查询" description: "搜索时要使用的基本查询。示例:'#urgent' 会在搜索查询前面加上 '#urgent',并且仅包含具有紧急类别或标签的话题。" - command_summary: + tool_summary: categories: "列出类别" search: "搜索" tags: "列出标签" @@ -175,7 +175,7 @@ zh_CN: schema: "查找数据库架构" search_settings: "正在搜索站点设置" dall_e: "生成图片" - command_help: + tool_help: categories: "列出论坛上所有公开可见的类别" search: "搜索论坛上的所有公共话题" tags: "列出论坛上的所有标签" @@ -188,7 +188,7 @@ zh_CN: schema: "查找数据库架构" search_settings: "搜索站点设置" dall_e: "使用 DALL-E 3 生成图片" - command_description: + tool_description: read: "阅读:%{title}" time: "%{timezone} 的时间为 %{time}" summarize: "已总结 %{title}" diff --git a/config/locales/server.zh_TW.yml b/config/locales/server.zh_TW.yml index b78a76e9..a59306e6 100644 --- a/config/locales/server.zh_TW.yml +++ b/config/locales/server.zh_TW.yml @@ -10,7 +10,7 @@ zh_TW: yaxis: "日期" discourse_ai: ai_bot: - command_summary: + tool_summary: search: "搜尋" time: "時間" summarize: "總結" diff --git a/db/fixtures/ai_bot/603_bot_ai_personas.rb b/db/fixtures/ai_bot/603_bot_ai_personas.rb index 30d4ef2d..4f833e34 100644 --- a/db/fixtures/ai_bot/603_bot_ai_personas.rb +++ b/db/fixtures/ai_bot/603_bot_ai_personas.rb @@ -32,7 +32,7 @@ DiscourseAi::AiBot::Personas::Persona.system_personas.each do |persona_class, id persona.system = true instance = persona_class.new - persona.commands = instance.tools.map { |tool| tool.to_s.split("::").last } + persona.tools = instance.tools.map { |tool| tool.to_s.split("::").last } persona.system_prompt = instance.system_prompt persona.top_p = instance.top_p persona.temperature = instance.temperature diff --git a/db/migrate/20240609061418_tool_details_and_command_removal.rb b/db/migrate/20240609061418_tool_details_and_command_removal.rb new file mode 100644 index 00000000..b728c2e9 --- /dev/null +++ b/db/migrate/20240609061418_tool_details_and_command_removal.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class ToolDetailsAndCommandRemoval < ActiveRecord::Migration[7.0] + def change + add_column :ai_personas, :tool_details, :boolean, default: true, null: false + add_column :ai_personas, :tools, :json, null: false, default: [] + Migration::ColumnDropper.mark_readonly(:ai_personas, :commands) + + execute <<~SQL + UPDATE ai_personas + SET tools = commands + SQL + end +end diff --git a/db/post_migrate/20240609232736_drop_commands_from_ai_personas.rb b/db/post_migrate/20240609232736_drop_commands_from_ai_personas.rb new file mode 100644 index 00000000..1a3ae897 --- /dev/null +++ b/db/post_migrate/20240609232736_drop_commands_from_ai_personas.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +class DropCommandsFromAiPersonas < ActiveRecord::Migration[7.0] + def down + raise ActiveRecord::IrreversibleMigration + end + + def up + Migration::ColumnDropper.execute_drop(:ai_personas, [:commands]) + end +end diff --git a/lib/ai_bot/playground.rb b/lib/ai_bot/playground.rb index 5d752747..39f78388 100644 --- a/lib/ai_bot/playground.rb +++ b/lib/ai_bot/playground.rb @@ -420,11 +420,13 @@ module DiscourseAi Discourse.redis.setex(redis_stream_key, 60, 1) end + context[:skip_tool_details] ||= !bot.persona.class.tool_details + new_custom_prompts = bot.reply(context) do |partial, cancel, placeholder| reply << partial raw = reply.dup - raw << "\n\n" << placeholder if placeholder.present? + raw << "\n\n" << placeholder if placeholder.present? && !context[:skip_tool_details] if stream_reply && !Discourse.redis.get(redis_stream_key) cancel&.call diff --git a/lib/ai_bot/tools/option.rb b/lib/ai_bot/tools/option.rb index 1723e7d1..eb0b6e1f 100644 --- a/lib/ai_bot/tools/option.rb +++ b/lib/ai_bot/tools/option.rb @@ -13,11 +13,11 @@ module DiscourseAi end def localized_name - I18n.t("discourse_ai.ai_bot.command_options.#{tool.signature[:name]}.#{name}.name") + I18n.t("discourse_ai.ai_bot.tool_options.#{tool.signature[:name]}.#{name}.name") end def localized_description - I18n.t("discourse_ai.ai_bot.command_options.#{tool.signature[:name]}.#{name}.description") + I18n.t("discourse_ai.ai_bot.tool_options.#{tool.signature[:name]}.#{name}.description") end end end diff --git a/lib/ai_bot/tools/tool.rb b/lib/ai_bot/tools/tool.rb index d4411e0b..8b8065f9 100644 --- a/lib/ai_bot/tools/tool.rb +++ b/lib/ai_bot/tools/tool.rb @@ -22,7 +22,7 @@ module DiscourseAi end def help - I18n.t("discourse_ai.ai_bot.command_help.#{signature[:name]}") + I18n.t("discourse_ai.ai_bot.tool_help.#{signature[:name]}") end def custom_system_message @@ -54,15 +54,15 @@ module DiscourseAi end def summary - I18n.t("discourse_ai.ai_bot.command_summary.#{name}") + I18n.t("discourse_ai.ai_bot.tool_summary.#{name}") end def details - I18n.t("discourse_ai.ai_bot.command_description.#{name}", description_args) + I18n.t("discourse_ai.ai_bot.tool_description.#{name}", description_args) end def help - I18n.t("discourse_ai.ai_bot.command_help.#{name}") + I18n.t("discourse_ai.ai_bot.tool_help.#{name}") end def options diff --git a/spec/lib/modules/ai_bot/personas/persona_spec.rb b/spec/lib/modules/ai_bot/personas/persona_spec.rb index 145e0dbc..2571ed84 100644 --- a/spec/lib/modules/ai_bot/personas/persona_spec.rb +++ b/spec/lib/modules/ai_bot/personas/persona_spec.rb @@ -226,7 +226,7 @@ RSpec.describe DiscourseAi::AiBot::Personas::Persona do name: "zzzpun_bot", description: "you write puns", system_prompt: "you are pun bot", - commands: ["ImageCommand"], + tools: ["Image"], allowed_group_ids: [Group::AUTO_GROUPS[:trust_level_0]], ) diff --git a/spec/lib/modules/ai_bot/playground_spec.rb b/spec/lib/modules/ai_bot/playground_spec.rb index 6fbe0f26..b5643e3d 100644 --- a/spec/lib/modules/ai_bot/playground_spec.rb +++ b/spec/lib/modules/ai_bot/playground_spec.rb @@ -290,7 +290,7 @@ RSpec.describe DiscourseAi::AiBot::Playground do end it "can run tools" do - persona.update!(commands: ["TimeCommand"]) + persona.update!(tools: ["Time"]) responses = [ "timetimeBuenos Aires", @@ -590,6 +590,34 @@ RSpec.describe DiscourseAi::AiBot::Playground do expect(last_post.raw).to include("I found stuff") end + it "supports disabling tool details" do + persona = Fabricate(:ai_persona, tool_details: false, tools: ["Search"]) + bot = DiscourseAi::AiBot::Bot.as(bot_user, persona: persona.class_instance.new) + playground = described_class.new(bot) + + response1 = (<<~TXT).strip + + + search + search + + testing various things + + + + TXT + + response2 = "I found stuff" + + DiscourseAi::Completions::Llm.with_prepared_responses([response1, response2]) do + playground.reply_to(third_post) + end + + last_post = third_post.topic.reload.posts.order(:post_number).last + + expect(last_post.raw).to eq("I found stuff") + end + it "does not include placeholders in conversation context but includes all completions" do response1 = (<<~TXT).strip diff --git a/spec/models/ai_persona_spec.rb b/spec/models/ai_persona_spec.rb index bc9cd9ae..7f661e4d 100644 --- a/spec/models/ai_persona_spec.rb +++ b/spec/models/ai_persona_spec.rb @@ -7,7 +7,7 @@ RSpec.describe AiPersona do name: "test", description: "test", system_prompt: "test", - commands: [], + tools: [], allowed_group_ids: [], ) @@ -30,7 +30,7 @@ RSpec.describe AiPersona do name: "test", description: "test", system_prompt: "test", - commands: [], + tools: [], allowed_group_ids: [], ) @@ -47,7 +47,7 @@ RSpec.describe AiPersona do name: "test", description: "test", system_prompt: "test", - commands: [], + tools: [], allowed_group_ids: [], rag_chunk_tokens: 10, rag_chunk_overlap_tokens: 5, @@ -94,7 +94,7 @@ RSpec.describe AiPersona do name: "test", description: "test", system_prompt: "test", - commands: [], + tools: [], allowed_group_ids: [], default_llm: "anthropic:claude-2", max_context_posts: 3, @@ -135,7 +135,7 @@ RSpec.describe AiPersona do name: "pun_bot", description: "you write puns", system_prompt: "you are pun bot", - commands: ["ImageCommand"], + tools: ["ImageCommand"], allowed_group_ids: [Group::AUTO_GROUPS[:trust_level_0]], ) diff --git a/spec/requests/admin/ai_personas_controller_spec.rb b/spec/requests/admin/ai_personas_controller_spec.rb index 565a44a2..bf1cbfc7 100644 --- a/spec/requests/admin/ai_personas_controller_spec.rb +++ b/spec/requests/admin/ai_personas_controller_spec.rb @@ -17,7 +17,7 @@ RSpec.describe DiscourseAi::Admin::AiPersonasController do expect(response).to be_successful expect(response.parsed_body["ai_personas"].length).to eq(AiPersona.count) - expect(response.parsed_body["meta"]["commands"].length).to eq( + expect(response.parsed_body["meta"]["tools"].length).to eq( DiscourseAi::AiBot::Personas::Persona.all_available_tools.length, ) end @@ -33,13 +33,13 @@ RSpec.describe DiscourseAi::Admin::AiPersonasController do ) end - it "returns commands options with each command" do - persona1 = Fabricate(:ai_persona, name: "search1", commands: ["SearchCommand"]) + it "returns tool options with each tool" do + persona1 = Fabricate(:ai_persona, name: "search1", tools: ["SearchCommand"]) persona2 = Fabricate( :ai_persona, name: "search2", - commands: [["SearchCommand", { base_query: "test" }]], + tools: [["SearchCommand", { base_query: "test" }]], mentionable: true, default_llm: "anthropic:claude-2", ) @@ -56,36 +56,36 @@ RSpec.describe DiscourseAi::Admin::AiPersonasController do expect(serializer_persona2["user_id"]).to eq(persona2.user_id) expect(serializer_persona2["user"]["id"]).to eq(persona2.user_id) - commands = response.parsed_body["meta"]["commands"] - search_command = commands.find { |c| c["id"] == "Search" } + tools = response.parsed_body["meta"]["tools"] + search_tool = tools.find { |c| c["id"] == "Search" } - expect(search_command["help"]).to eq(I18n.t("discourse_ai.ai_bot.command_help.search")) + expect(search_tool["help"]).to eq(I18n.t("discourse_ai.ai_bot.tool_help.search")) - expect(search_command["options"]).to eq( + expect(search_tool["options"]).to eq( { "base_query" => { "type" => "string", - "name" => I18n.t("discourse_ai.ai_bot.command_options.search.base_query.name"), + "name" => I18n.t("discourse_ai.ai_bot.tool_options.search.base_query.name"), "description" => - I18n.t("discourse_ai.ai_bot.command_options.search.base_query.description"), + I18n.t("discourse_ai.ai_bot.tool_options.search.base_query.description"), }, "max_results" => { "type" => "integer", - "name" => I18n.t("discourse_ai.ai_bot.command_options.search.max_results.name"), + "name" => I18n.t("discourse_ai.ai_bot.tool_options.search.max_results.name"), "description" => - I18n.t("discourse_ai.ai_bot.command_options.search.max_results.description"), + I18n.t("discourse_ai.ai_bot.tool_options.search.max_results.description"), }, "search_private" => { "type" => "boolean", - "name" => I18n.t("discourse_ai.ai_bot.command_options.search.search_private.name"), + "name" => I18n.t("discourse_ai.ai_bot.tool_options.search.search_private.name"), "description" => - I18n.t("discourse_ai.ai_bot.command_options.search.search_private.description"), + I18n.t("discourse_ai.ai_bot.tool_options.search.search_private.description"), }, }, ) - expect(serializer_persona1["commands"]).to eq(["SearchCommand"]) - expect(serializer_persona2["commands"]).to eq([["SearchCommand", { "base_query" => "test" }]]) + expect(serializer_persona1["tools"]).to eq(["SearchCommand"]) + expect(serializer_persona2["tools"]).to eq([["SearchCommand", { "base_query" => "test" }]]) end context "with translations" do @@ -160,7 +160,7 @@ RSpec.describe DiscourseAi::Admin::AiPersonasController do name: "superbot", description: "Assists with tasks", system_prompt: "you are a helpful bot", - commands: [["search", { "base_query" => "test" }]], + tools: [["search", { "base_query" => "test" }]], top_p: 0.1, temperature: 0.5, mentionable: true, @@ -186,7 +186,7 @@ RSpec.describe DiscourseAi::Admin::AiPersonasController do persona = AiPersona.find(persona_json["id"]) - expect(persona.commands).to eq([["search", { "base_query" => "test" }]]) + expect(persona.tools).to eq([["search", { "base_query" => "test" }]]) expect(persona.top_p).to eq(0.1) expect(persona.temperature).to eq(0.5) }.to change(AiPersona, :count).by(1) @@ -286,7 +286,7 @@ RSpec.describe DiscourseAi::Admin::AiPersonasController do ai_persona: { name: "SuperBot", enabled: false, - commands: ["search"], + tools: ["search"], }, } @@ -296,7 +296,7 @@ RSpec.describe DiscourseAi::Admin::AiPersonasController do ai_persona.reload expect(ai_persona.name).to eq("SuperBot") expect(ai_persona.enabled).to eq(false) - expect(ai_persona.commands).to eq(["search"]) + expect(ai_persona.tools).to eq(["search"]) end end @@ -314,11 +314,11 @@ RSpec.describe DiscourseAi::Admin::AiPersonasController do expect(response.parsed_body["errors"].join).not_to include("en.discourse") end - it "does not allow editing of commands" do + it "does not allow editing of tools" do put "/admin/plugins/discourse-ai/ai-personas/#{DiscourseAi::AiBot::Personas::Persona.system_personas.values.first}.json", params: { ai_persona: { - commands: %w[SearchCommand ImageCommand], + tools: %w[SearchCommand ImageCommand], }, } diff --git a/spec/system/ai_bot/persona_spec.rb b/spec/system/ai_bot/persona_spec.rb index 5f785f75..94ade514 100644 --- a/spec/system/ai_bot/persona_spec.rb +++ b/spec/system/ai_bot/persona_spec.rb @@ -38,9 +38,9 @@ RSpec.describe "AI personas", type: :system, js: true do find(".ai-persona-editor__description").fill_in(with: "I am a test persona") find(".ai-persona-editor__system_prompt").fill_in(with: "You are a helpful bot") - command_selector = PageObjects::Components::SelectKit.new(".ai-persona-editor__commands") - command_selector.expand - command_selector.select_row_by_value("Read") + tool_selector = PageObjects::Components::SelectKit.new(".ai-persona-editor__tools") + tool_selector.expand + tool_selector.select_row_by_value("Read") find(".ai-persona-editor__save").click() @@ -52,7 +52,7 @@ RSpec.describe "AI personas", type: :system, js: true do expect(persona.name).to eq("Test Persona") expect(persona.description).to eq("I am a test persona") expect(persona.system_prompt).to eq("You are a helpful bot") - expect(persona.commands).to eq(["Read"]) + expect(persona.tools).to eq(["Read"]) end it "will not allow deletion or editing of system personas" do diff --git a/test/javascripts/unit/models/ai-persona-test.js b/test/javascripts/unit/models/ai-persona-test.js index ac1c5530..f785ffba 100644 --- a/test/javascripts/unit/models/ai-persona-test.js +++ b/test/javascripts/unit/models/ai-persona-test.js @@ -4,26 +4,22 @@ import AiPersona from "discourse/plugins/discourse-ai/discourse/admin/models/ai- module("Discourse AI | Unit | Model | ai-persona", function () { test("init properties", function (assert) { const properties = { - commands: [ - ["CommandName", { option1: "value1", option2: "value2" }], - "CommandName2", - "CommandName3", + tools: [ + ["ToolName", { option1: "value1", option2: "value2" }], + "ToolName2", + "ToolName3", ], }; const aiPersona = AiPersona.create(properties); - assert.deepEqual(aiPersona.commands, [ - "CommandName", - "CommandName2", - "CommandName3", - ]); + assert.deepEqual(aiPersona.tools, ["ToolName", "ToolName2", "ToolName3"]); assert.equal( - aiPersona.getCommandOption("CommandName", "option1").value, + aiPersona.getToolOption("ToolName", "option1").value, "value1" ); assert.equal( - aiPersona.getCommandOption("CommandName", "option2").value, + aiPersona.getToolOption("ToolName", "option2").value, "value2" ); }); @@ -32,7 +28,7 @@ module("Discourse AI | Unit | Model | ai-persona", function () { const properties = { id: 1, name: "Test", - commands: ["CommandName"], + tools: ["ToolName"], allowed_group_ids: [12], system: false, enabled: true, @@ -54,16 +50,17 @@ module("Discourse AI | Unit | Model | ai-persona", function () { rag_conversation_chunks: 10, question_consolidator_llm: "Question Consolidator LLM", allow_chat: false, + tool_details: true, }; const aiPersona = AiPersona.create({ ...properties }); - aiPersona.getCommandOption("CommandName", "option1").value = "value1"; + aiPersona.getToolOption("ToolName", "option1").value = "value1"; const updatedProperties = aiPersona.updateProperties(); // perform remapping for save - properties.commands = [["CommandName", { option1: "value1" }]]; + properties.tools = [["ToolName", { option1: "value1" }]]; assert.deepEqual(updatedProperties, properties); }); @@ -72,7 +69,7 @@ module("Discourse AI | Unit | Model | ai-persona", function () { const properties = { id: 1, name: "Test", - commands: ["CommandName"], + tools: ["ToolName"], allowed_group_ids: [12], system: false, enabled: true, @@ -94,15 +91,16 @@ module("Discourse AI | Unit | Model | ai-persona", function () { rag_conversation_chunks: 10, question_consolidator_llm: "Question Consolidator LLM", allow_chat: false, + tool_details: true, }; const aiPersona = AiPersona.create({ ...properties }); - aiPersona.getCommandOption("CommandName", "option1").value = "value1"; + aiPersona.getToolOption("ToolName", "option1").value = "value1"; const createdProperties = aiPersona.createProperties(); - properties.commands = [["CommandName", { option1: "value1" }]]; + properties.tools = [["ToolName", { option1: "value1" }]]; assert.deepEqual(createdProperties, properties); }); @@ -110,18 +108,18 @@ module("Discourse AI | Unit | Model | ai-persona", function () { test("working copy", function (assert) { const aiPersona = AiPersona.create({ name: "Test", - commands: ["CommandName"], + tools: ["ToolName"], }); - aiPersona.getCommandOption("CommandName", "option1").value = "value1"; + aiPersona.getToolOption("ToolName", "option1").value = "value1"; const workingCopy = aiPersona.workingCopy(); assert.equal(workingCopy.name, "Test"); assert.equal( - workingCopy.getCommandOption("CommandName", "option1").value, + workingCopy.getToolOption("ToolName", "option1").value, "value1" ); - assert.deepEqual(workingCopy.commands, ["CommandName"]); + assert.deepEqual(workingCopy.tools, ["ToolName"]); }); });