Created
November 7, 2023 05:09
-
-
Save SamSaffron/bfc6fbd51245ebc88ff3bfbac5fb7f11 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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