Skip to content

Instantly share code, notes, and snippets.

@SamSaffron
Created November 7, 2023 05:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SamSaffron/bfc6fbd51245ebc88ff3bfbac5fb7f11 to your computer and use it in GitHub Desktop.
Save SamSaffron/bfc6fbd51245ebc88ff3bfbac5fb7f11 to your computer and use it in GitHub Desktop.
require "net/http"
require "uri"
require "json"
require "yaml"
require "open3"
DISCOURSE_ROOT = "/home/sam/Source/discourse"
API_KEY = ENV["OPENAI_API_KEY"]
def openai_chat_completion(system_prompt, prompt)
# Define the endpoint URL for the OpenAI API
uri = URI.parse("https://api.openai.com/v1/chat/completions")
# Create a new HTTP request
request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer #{API_KEY}"
# Set the request body with your parameters
request.body =
JSON.dump(
{
"model" => "gpt-4",
#"model" => "gpt-4-1106-preview",
"messages" => [
{ role: "system", content: system_prompt },
{ role: "user", content: prompt }
]
}
)
# Create an HTTP session
response =
Net::HTTP.start(
uri.hostname,
uri.port,
use_ssl: uri.scheme == "https"
) do |http|
# Make the request
http.request(request)
end
# Check if the request was successful
if response.is_a?(Net::HTTPSuccess)
# Parse the JSON response
JSON.parse(response.body)
else
p response
p response.body
# Handle errors
raise "Error: #{response.code} - #{response.message}"
end
end
def get_context(setting_name, narrow_search: true)
result = +""
search = (narrow_search ? "ettings?.#{setting_name}" : setting_name)
%w[lib app plugins].each do |dir|
path = DISCOURSE_ROOT + "/#{dir}"
context, _, _ =
Open3.capture3(
"rg",
search,
path,
"-g",
"!**/spec/**",
"-g",
"!**/dist/**",
"-g",
"*.{rb,js,gjs,hbs}",
"-C",
"10",
"--color",
"never",
"--heading",
"--no-ignore",
chdir: path
)
result << context
end
result.gsub!(/^#{Regexp.escape(DISCOURSE_ROOT)}/, "")
if narrow_search && result.length < 10
return get_context(setting_name, narrow_search: false)
end
result
end
def each_setting
# Load the settings from the YAML file
settings = YAML.load_file(DISCOURSE_ROOT + "/config/site_settings.yml")
descriptions_yaml =
File.read(DISCOURSE_ROOT + "/config/locales/server.en.yml")
descriptions = YAML.safe_load(descriptions_yaml, aliases: true)
settings.each do |name, section|
section.each do |setting, value|
next if value.is_a?(Hash) && value["hidden"]
context = get_context(setting)
yield setting, descriptions.dig("en", "site_settings", setting), context
end
end
end
system_prompt = <<~PROMPT
You are a Discourse Site Setting Describer.
You are tasked with improving the descriptions of the site settings.
User will provide with a setting name, existing description and code context.
You will then return a refined description of the setting, improving copy, grammer, clarity and more.
Rules:
- If it is only one sentence, avoid a trailing period.
- Always capitalize first letter.
- Try to be as clear as possible.
- Try to be as truthful as possible.
- Always strive to return a single paragraph, if you need multiple sentences then use a trailing period.
- Don't be too wordy, but don't be too terse either. Try to find a balance.
- Avoid similies and metaphors, aim for clarity and use simple language.
- the form <a href...> is used to denote links, this is supported, try to maintain them from original descriptions.
- Never use the word "thread" to describe a topic, use the terms topic, category and so on.
- Never prefix a description with "This setting determines..." it is wasting words
PROMPT
results = +""
results =
begin
File.read("results.txt")
rescue StandardError
""
end
last_setting = nil
results.split("------")[-2]
.split("\n")
.each do |line|
last_setting = line.split(":").first.strip if line.include?(":")
end
each_setting do |name, description, context|
next if last_setting && last_setting != name
if last_setting == name
last_setting = nil
next
end
# till GPT4 125k
context = context[0..10_000] + "..." if context.length > 10_000
prompt = <<~PROMPT
#{name}
Existing description: #{description}
Context:
#{context}
Suggest a better description
PROMPT
result =
begin
openai_chat_completion(system_prompt, prompt)
rescue => e
# rate limiter, likely
p e
sleep 5
retry
end
new_description = result.dig("choices", 0, "message", "content")
puts name
puts "Old: #{description}"
puts "New: #{new_description}"
results << <<~DESC
#{name}:
#{description}
------
#{new_description}
DESC
File.write("results.txt", results)
end
exit
begin
# Call the method
result = openai_chat_completion(prompt)
p result
rescue => e
puts e.message
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment