Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mattlindsey/mythographer
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 381c83ab858ac1faab7a1b231020d13d4a24de10
Choose a base ref
..
head repository: mattlindsey/mythographer
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c05cedb366ef28ce0e0150ed66bb8aede2d36bc4
Choose a head ref
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -25,3 +25,4 @@ REDIS_URL=
COMPOSE_PROJECT_NAME=

OPENAI_API_KEY=
GOOGLE_PALM_API_KEY=
12 changes: 6 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@ GEM
ast (2.4.2)
baran (0.1.10)
base64 (0.2.0)
bigdecimal (3.1.5)
bigdecimal (3.1.6)
bindex (0.8.1)
bootsnap (1.17.1)
msgpack (~> 1.2)
@@ -100,7 +100,7 @@ GEM
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
colorize (0.8.1)
concurrent-ruby (1.2.2)
concurrent-ruby (1.2.3)
connection_pool (2.4.1)
coveralls_reborn (0.28.0)
simplecov (~> 0.22.0)
@@ -139,7 +139,7 @@ GEM
actionpack (>= 6.0.0)
activesupport (>= 6.0.0)
railties (>= 6.0.0)
io-console (0.7.1)
io-console (0.7.2)
irb (1.11.1)
rdoc
reline (>= 0.4.2)
@@ -149,7 +149,7 @@ GEM
json (2.7.1)
json-schema (4.0.0)
addressable (>= 2.8)
langchainrb (0.8.2)
langchainrb (0.9.0)
baran (~> 0.1.9)
colorize (~> 0.8.1)
json-schema (~> 4.0.0)
@@ -171,7 +171,7 @@ GEM
marcel (1.0.2)
matrix (0.4.2)
mini_mime (1.1.5)
minitest (5.21.1)
minitest (5.21.2)
msgpack (1.7.2)
multipart-post (2.3.0)
mutex_m (0.2.0)
@@ -196,7 +196,7 @@ GEM
nokogiri (1.16.0-x86_64-linux)
racc (~> 1.4)
parallel (1.24.0)
parser (3.3.0.3)
parser (3.3.0.4)
ast (~> 2.4.1)
racc
pg (1.5.4)
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -75,10 +75,11 @@ Now you're ready to run the tests:
bundle exec rspec
```

### Step 5: Set your OpenAI key using export or .env file
### Step 5: Set your OpenAI and Google keys using export or .env file

```bash
export OPENAI_API_KEY=sk-key
export GOOGLE_PALM_API_KEY=key
```

### Step 6. Start the server
8 changes: 3 additions & 5 deletions app/controllers/stories_controller.rb
Original file line number Diff line number Diff line change
@@ -13,9 +13,8 @@ def show

def new
@mythologies = Mythology.all
@gods = God.where(mythology_id: @mythologies.first.id)
# @gods = God.where(mythology_id: @mythologies.first.id)
@storygod = StoryGod.new
# @story = Story.new(storygods: [StoryGod.new])
@story = Story.new(storygods: [@storygod])
end

@@ -27,8 +26,7 @@ def create
@story.body = "Generating. Story should appear here. Wait a bit..."

if @story.save
llm_name = LLM_DEFAULTS[:llm] # TODO: get llm_name from params
StoryCreateJob.perform_later(@story.id, llm_name)
StoryCreateJob.perform_later(@story.id)
redirect_to @story
else
@mythologies = Mythology.all
@@ -57,7 +55,7 @@ def set_story
end

def story_params
params.require(:story).permit(:title, :mythology_id, :body, :creativity,
params.require(:story).permit(:title, :mythology_id, :body, :creativity, :llm_name, :instructions,
storygods_attributes: [:id, :god_id, :role, :_destroy])
end
end
6 changes: 3 additions & 3 deletions app/jobs/story_create_job.rb
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ class StoryCreateJob < ApplicationJob
def perform(*args)
story = Story.find(args[0])
mythology_name = story.mythology.name
llm_name = args[1] || LLM_DEFAULTS[:llm]
llm_name = story.llm_name

case llm_name
when "openai"
@@ -15,8 +15,8 @@ def perform(*args)
logger.error "Unknown LLM: #{llm_name}"
end

prompt = Langchain::Prompt::PromptTemplate.new(template: "Tell me a very short story from {mythology_name} mythology that would be appropriately titled {title}.", input_variables: ["mythology_name", "title"])
prompt_text = prompt.format(mythology_name: mythology_name, title: story.title)
template = Langchain::Prompt.load_from_path(file_path: "app/prompts/story_create_template.yaml")
prompt_text = template.format(mythology_name: mythology_name, title: story.title)
story.update(body: llm.complete(prompt: prompt_text).completion)
end
end
2 changes: 2 additions & 0 deletions app/models/story.rb
Original file line number Diff line number Diff line change
@@ -15,6 +15,8 @@ class Story < ApplicationRecord
}.freeze
validates :creativity, presence: true, inclusion: {in: CREATIVITY_TEMPS.keys}

validates :llm_name, presence: true, inclusion: {in: LLMS}

def creativity_temp
CREATIVITY_TEMPS[creativity]
end
7 changes: 7 additions & 0 deletions app/prompts/story_create_template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

_type: prompt
template: |
Tell me a very short story from {mythology_name} mythology that would be appropriately titled {title}.
input_variables:
- mythology_name
- title
12 changes: 5 additions & 7 deletions app/views/stories/_form.html.erb
Original file line number Diff line number Diff line change
@@ -25,14 +25,12 @@
<%= f.input :creativity, collection: Story::CREATIVITY_TEMPS.keys,
default: Story::CREATIVITY_TEMPS.keys.first,
input_html: { class: 'rounded mt-5', style: 'margin-left: 22px;' } %>
<%= f.input :instructions,
input_html: { class: 'rounded mt-5', style: 'margin-left: 7px;' } %>
<%= f.hidden_field :body, input_placeholder: 'AI will generate this' %>

<div>
LLM Name <%= select_tag "llm_name", options_for_select(LLMS),
class: 'rounded mt-5',
style: 'margin-left: 10px;' %>
</div>

<%= f.input :llm_name, collection: LLMS,
default: LLM_DEFAULTS[:llm],
input_html: { class: 'rounded mt-5', style: 'margin-left: 22px;' } %>
<h4>Include these Gods</h4>
<div data-nested-form-target="target"></div>
<div>
1 change: 0 additions & 1 deletion app/views/story_gods/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<%= form.hidden_field :id %>
<div>
<%= form.input :god_id, collection: @gods, label_method: :name, value_method: :id,
default: @gods.first,
input_html: { id: 'god_id', class: 'rounded', style: 'margin-left: 62px;' } %>
<%= form.input :role, collection: StoryGod::ROLES,
default: StoryGod::ROLES.first,
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class AddLlmNameAndInstructionsToStories < ActiveRecord::Migration[7.1]
def change
change_table :stories, bulk: true do |t|
t.string :llm_name
t.string :instructions
end
end
end
4 changes: 3 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion db/seeds.rb
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@
end

m = Mythology.where(name: "Greek").first
Story.create_with(mythology_id: m.id, creativity: "Conservative").find_or_create_by(title: "Sample Story with Zeus", body: "The most powerful god Zeus was having a bad day.")
Story.create_with(mythology_id: m.id, creativity: "Conservative").find_or_create_by(title: "Sample Story with Zeus", body: "The most powerful god Zeus was having a bad day.", llm_name: "openai", instructions: "Zeus is unhappy.")
StoryGod.create_with(role: "Protagonist").find_or_create_by(story_id: 1, god_id: 1)

zeus = God.find_by(name: "Zeus")
2 changes: 2 additions & 0 deletions spec/factories.rb
Original file line number Diff line number Diff line change
@@ -12,5 +12,7 @@
body { "Sample Body" }
mythology
creativity { "Balanced" }
llm_name { "openai" }
instructions { "Additional stuff" }
end
end
24 changes: 12 additions & 12 deletions spec/jobs/story_create_job_spec.rb
Original file line number Diff line number Diff line change
@@ -26,22 +26,22 @@
expect(described_class.new.perform(story.id, "openai")).to be true
end

it "calls the StoryCreateJob with the correct args for google" do
allow(Story).to receive(:find).and_return(story)
llm = instance_double(Langchain::LLM::GooglePalm)
llm_response = instance_double(Langchain::LLM::GooglePalmResponse)
# it "calls the StoryCreateJob with the correct args for google" do
# allow(Story).to receive(:find).and_return(story)
# llm = instance_double(Langchain::LLM::GooglePalm)
# llm_response = instance_double(Langchain::LLM::GooglePalmResponse)

allow(llm_response).to receive(:completion).and_return("Something")
allow(llm).to receive(:complete).and_return(llm_response)
# allow(llm_response).to receive(:completion).and_return("Something")
# allow(llm).to receive(:complete).and_return(llm_response)

prompt_template = instance_double(Langchain::Prompt::PromptTemplate)
allow(prompt_template).to receive(:format)
# prompt_template = instance_double(Langchain::Prompt::PromptTemplate)
# allow(prompt_template).to receive(:format)

allow(Langchain::LLM::GooglePalm).to receive(:new).and_return(llm)
allow(Langchain::Prompt::PromptTemplate).to receive(:new).and_return(prompt_template)
# allow(Langchain::LLM::GooglePalm).to receive(:new).and_return(llm)
# allow(Langchain::Prompt::PromptTemplate).to receive(:new).and_return(prompt_template)

expect(described_class.new.perform(story.id, "google")).to be true
end
# expect(described_class.new.perform(story.id, "google")).to be true
# end

it "uses the default LLM if no llm_name is provided" do
allow(Story).to receive(:find).and_return(story)
13 changes: 5 additions & 8 deletions spec/system/story_tests_spec.rb
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
require "rails_helper"

RSpec.describe "StorySystemTests" do
it "gives error message on empty title and url" do
pending "add some examples to (or delete) #{__FILE__}"

it "gives error message on empty title and url", skip: "TODO" do
visit new_story_path
click_link_or_button "Generate Story"

expect(page).to have_content("Title can't be blank")
# expect(Story.count).to eq(0)
end

it "creates new story" do
pending "add some examples to (or delete) #{__FILE__}"

it "creates new story", skip: "TODO" do
visit stories_path
assert_selector "h1", text: "Story List"

click_link_or_button "New Story"
assert_selector "h1", text: "New Story"

fill_in "Title", with: "Story about Zeus"
select "Greek", from: "story_mythology_id"
fill_in "god_id", with: "Zeus"
# select "Greek", from: "story_mythology_id"
fill_in "god_id", with: 1
# fill_in "llm_name", with: "openai"
click_link_or_button "Generate Story"

assert_selector "h1", text: "Story about Zeus"