FEATURE: new site setting explorer persona (#178)
Also adds ai_bot_enabled_personas so admins can tweak which stock personas are enabled. The new persona has a full listing of all site settings and is able to get context for each setting. This means you can ask it to search through settings for something relevant. Security wise there is no access to actual configuration of settings just to the names / description and implementation. Previously this was part of the forum helper persona however it just clashes too much with other behaviors, isolating it makes it far more powerful. * sneaking this one in, user_emails is a non obvious table in our structure. usually one would assume users has emails so the clarifies a bit better. plus it is a very common table to hit.
This commit is contained in:
parent
8e4347acba
commit
00d69b463e
|
@ -63,8 +63,9 @@ en:
|
|||
ai_bot_enable_chat_warning: "Display a warning when PM chat is initiated. Can be overriden by editing the translation string: discourse_ai.ai_bot.pm_warning"
|
||||
ai_bot_allowed_groups: "When the GPT Bot has access to the PM, it will reply to members of these groups."
|
||||
ai_bot_enabled_chat_bots: "Available models to act as an AI Bot"
|
||||
ai_bot_enabled_chat_commands: "Available GPT integrations used to provide external functionality to the model."
|
||||
ai_bot_enabled_chat_commands: "Available GPT integrations used to provide external functionality to the Forum Helper bot, keep in mind that certain commands may only be available if appropriate API keys are added."
|
||||
ai_bot_add_to_header: "Display a button in the header to start a PM with a AI Bot"
|
||||
ai_bot_enabled_personas: "List of personas available for the AI Bot"
|
||||
|
||||
ai_stability_api_key: "API key for the stability.ai API"
|
||||
ai_stability_engine: "Image generation engine to use for the stability.ai API"
|
||||
|
@ -103,6 +104,9 @@ en:
|
|||
sql_helper:
|
||||
name: SQL Helper
|
||||
description: "AI Bot specialized in helping craft SQL queries on this Discourse instance"
|
||||
settings_explorer:
|
||||
name: Settings Explorer
|
||||
description: "AI Bot specialized in helping explore Discourse site settings"
|
||||
default_pm_prefix: "[Untitled AI bot PM]"
|
||||
topic_not_found: "Summary unavailable, topic not found!"
|
||||
command_summary:
|
||||
|
|
|
@ -216,7 +216,14 @@ discourse_ai:
|
|||
- read
|
||||
- tags
|
||||
- time
|
||||
- setting_context
|
||||
ai_bot_enabled_personas:
|
||||
type: list
|
||||
default: "general|artist|sql_helper|settings_explorer"
|
||||
choices:
|
||||
- general
|
||||
- artist
|
||||
- sql_helper
|
||||
- settings_explorer
|
||||
ai_bot_add_to_header:
|
||||
default: true
|
||||
client: true
|
||||
|
|
|
@ -44,6 +44,7 @@ module DiscourseAi
|
|||
require_relative "personas/artist"
|
||||
require_relative "personas/general"
|
||||
require_relative "personas/sql_helper"
|
||||
require_relative "personas/settings_explorer"
|
||||
end
|
||||
|
||||
def inject_into(plugin)
|
||||
|
|
|
@ -6,7 +6,10 @@ module DiscourseAi
|
|||
def self.all
|
||||
personas = [Personas::General, Personas::SqlHelper]
|
||||
personas << Personas::Artist if SiteSetting.ai_stability_api_key.present?
|
||||
personas
|
||||
personas << Personas::SettingsExplorer
|
||||
|
||||
personas_allowed = SiteSetting.ai_bot_enabled_personas.split("|")
|
||||
personas.filter { |persona| personas_allowed.include?(persona.to_s.demodulize.underscore) }
|
||||
end
|
||||
|
||||
class Persona
|
||||
|
@ -91,7 +94,6 @@ module DiscourseAi
|
|||
Commands::SearchCommand,
|
||||
Commands::SummarizeCommand,
|
||||
Commands::ReadCommand,
|
||||
Commands::SettingContextCommand,
|
||||
]
|
||||
|
||||
all_commands << Commands::TagsCommand if SiteSetting.tagging_enabled
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#frozen_string_literal: true
|
||||
|
||||
module DiscourseAi
|
||||
module AiBot
|
||||
module Personas
|
||||
class SettingsExplorer < Persona
|
||||
def commands
|
||||
all_available_commands
|
||||
end
|
||||
|
||||
def all_available_commands
|
||||
[DiscourseAi::AiBot::Commands::SettingContextCommand]
|
||||
end
|
||||
|
||||
def system_prompt
|
||||
<<~PROMPT
|
||||
You are Discourse Site settings bot.
|
||||
|
||||
- You know the full list of all the site settings.
|
||||
- You are able to request context for a specific setting.
|
||||
- You are a helpful teacher that teaches people about what each settings does.
|
||||
|
||||
Current time is: {time}
|
||||
|
||||
Full list of all the site settings:
|
||||
{{
|
||||
#{SiteSetting.all_settings.map { |setting| setting[:setting].to_s }.join("\n")}
|
||||
}}
|
||||
|
||||
{commands}
|
||||
|
||||
PROMPT
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,7 +8,7 @@ module DiscourseAi
|
|||
return @schema if defined?(@schema)
|
||||
|
||||
tables = Hash.new
|
||||
priority_tables = %w[posts topics notifications users user_actions]
|
||||
priority_tables = %w[posts topics notifications users user_actions user_emails]
|
||||
|
||||
DB.query(<<~SQL).each { |row| (tables[row.table_name] ||= []) << row.column_name }
|
||||
select table_name, column_name from information_schema.columns
|
||||
|
|
|
@ -22,40 +22,62 @@ class TestPersona < DiscourseAi::AiBot::Personas::Persona
|
|||
end
|
||||
end
|
||||
|
||||
RSpec.describe DiscourseAi::AiBot::Personas::Persona do
|
||||
let :persona do
|
||||
TestPersona.new
|
||||
end
|
||||
module DiscourseAi::AiBot::Personas
|
||||
RSpec.describe Persona do
|
||||
let :persona do
|
||||
TestPersona.new
|
||||
end
|
||||
|
||||
let :topic_with_users do
|
||||
topic = Topic.new
|
||||
topic.allowed_users = [User.new(username: "joe"), User.new(username: "jane")]
|
||||
topic
|
||||
end
|
||||
let :topic_with_users do
|
||||
topic = Topic.new
|
||||
topic.allowed_users = [User.new(username: "joe"), User.new(username: "jane")]
|
||||
topic
|
||||
end
|
||||
|
||||
it "renders the system prompt" do
|
||||
freeze_time
|
||||
it "renders the system prompt" do
|
||||
freeze_time
|
||||
|
||||
SiteSetting.title = "test site title"
|
||||
SiteSetting.site_description = "test site description"
|
||||
SiteSetting.title = "test site title"
|
||||
SiteSetting.site_description = "test site description"
|
||||
|
||||
rendered =
|
||||
persona.render_system_prompt(topic: topic_with_users, render_function_instructions: true)
|
||||
rendered =
|
||||
persona.render_system_prompt(topic: topic_with_users, render_function_instructions: true)
|
||||
|
||||
expect(rendered).to include(Discourse.base_url)
|
||||
expect(rendered).to include("test site title")
|
||||
expect(rendered).to include("test site description")
|
||||
expect(rendered).to include("joe, jane")
|
||||
expect(rendered).to include(Time.zone.now.to_s)
|
||||
expect(rendered).to include("!search")
|
||||
expect(rendered).to include("!tags")
|
||||
# needs to be configured so it is not available
|
||||
expect(rendered).not_to include("!image")
|
||||
expect(rendered).to include(Discourse.base_url)
|
||||
expect(rendered).to include("test site title")
|
||||
expect(rendered).to include("test site description")
|
||||
expect(rendered).to include("joe, jane")
|
||||
expect(rendered).to include(Time.zone.now.to_s)
|
||||
expect(rendered).to include("!search")
|
||||
expect(rendered).to include("!tags")
|
||||
# needs to be configured so it is not available
|
||||
expect(rendered).not_to include("!image")
|
||||
|
||||
rendered =
|
||||
persona.render_system_prompt(topic: topic_with_users, render_function_instructions: false)
|
||||
rendered =
|
||||
persona.render_system_prompt(topic: topic_with_users, render_function_instructions: false)
|
||||
|
||||
expect(rendered).not_to include("!search")
|
||||
expect(rendered).not_to include("!tags")
|
||||
expect(rendered).not_to include("!search")
|
||||
expect(rendered).not_to include("!tags")
|
||||
end
|
||||
|
||||
describe "available personas" do
|
||||
it "includes all personas by default" do
|
||||
# must be enabled to see it
|
||||
SiteSetting.ai_stability_api_key = "abc"
|
||||
|
||||
expect(DiscourseAi::AiBot::Personas.all).to contain_exactly(
|
||||
General,
|
||||
SqlHelper,
|
||||
Artist,
|
||||
SettingsExplorer,
|
||||
)
|
||||
end
|
||||
|
||||
it "can be modified via site settings" do
|
||||
SiteSetting.ai_bot_enabled_personas = "general|sql_helper"
|
||||
|
||||
expect(DiscourseAi::AiBot::Personas.all).to contain_exactly(General, SqlHelper)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe DiscourseAi::AiBot::Personas::SettingsExplorer do
|
||||
let :settings_explorer do
|
||||
subject
|
||||
end
|
||||
|
||||
it "renders schema" do
|
||||
prompt = settings_explorer.render_system_prompt
|
||||
# check we render settings
|
||||
expect(prompt).to include("ai_bot_enabled_personas")
|
||||
|
||||
expect(settings_explorer.available_commands).to eq(
|
||||
[DiscourseAi::AiBot::Commands::SettingContextCommand],
|
||||
)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue