All Files
(
83.47%
covered at
0.98
hits/line
)
19 files in total.
121 relevant lines,
101 lines covered and
20 lines missed.
(
83.47%
)
Controllers
(
75.41%
covered at
0.92
hits/line
)
5 files in total.
61 relevant lines,
46 lines covered and
15 lines missed.
(
75.41%
)
Channels
(
100.0%
covered at
1.0
hits/line
)
2 files in total.
4 relevant lines,
4 lines covered and
0 lines missed.
(
100.0%
)
Models
(
93.75%
covered at
1.06
hits/line
)
6 files in total.
32 relevant lines,
30 lines covered and
2 lines missed.
(
93.75%
)
Mailers
(
100.0%
covered at
1.0
hits/line
)
1 files in total.
3 relevant lines,
3 lines covered and
0 lines missed.
(
100.0%
)
Helpers
(
100.0%
covered at
1.0
hits/line
)
3 files in total.
3 relevant lines,
3 lines covered and
0 lines missed.
(
100.0%
)
Jobs
(
83.33%
covered at
1.0
hits/line
)
2 files in total.
18 relevant lines,
15 lines covered and
3 lines missed.
(
83.33%
)
Libraries
(
100.0%
covered at
0.0
hits/line
)
0 files in total.
0 relevant lines,
0 lines covered and
0 lines missed.
(
100.0%
)
File |
% covered |
Lines |
Relevant Lines |
Lines covered |
Lines missed |
Avg. Hits / Line |
-
1
module ApplicationCable
-
1
class Channel < ActionCable::Channel::Base
-
end
-
end
-
1
module ApplicationCable
-
1
class Connection < ActionCable::Connection::Base
-
end
-
end
-
1
class ApplicationController < ActionController::Base
-
end
-
1
class GodsController < ApplicationController
-
1
def index
-
@gods = God.all
-
end
-
end
-
1
class MythologiesController < ApplicationController
-
1
def index
-
@mythologies = Mythology.all
-
end
-
end
-
1
class StoriesController < ApplicationController
-
1
before_action :set_story, only: [:show, :edit, :update, :destroy]
-
-
1
def index
-
3
@stories = Story.all
-
end
-
-
1
def show
-
rescue ActiveRecord::RecordNotFound
-
redirect_to stories_path
-
end
-
-
1
def new
-
2
@mythologies = Mythology.all
-
2
@gods = God.where(mythology_id: @mythologies.first.id)
-
2
@storygod = StoryGod.new
-
2
@story = Story.new(storygods: [@storygod])
-
end
-
-
1
def edit
-
end
-
-
1
def create
-
2
@story = Story.new(story_params)
-
2
@story.content = "Generating. Story should appear here. Wait a bit..."
-
-
2
if @story.save
-
1
StoryCreateJob.perform_later(@story.id)
-
1
redirect_to @story
-
else
-
1
@mythologies = Mythology.all
-
1
@gods = God.where(mythology_id: @mythologies.first.id)
-
1
render :new, status: :unprocessable_entity
-
end
-
end
-
-
1
def update
-
if @story.update(story_params)
-
redirect_to stories_path, notice: "Story was successfully updated."
-
else
-
render :show
-
end
-
end
-
-
1
def destroy
-
@story.destroy
-
redirect_to stories_path, notice: "Story was successfully destroyed."
-
end
-
-
1
private
-
-
1
def set_story
-
1
@story = Story.find(params[:id])
-
end
-
-
1
def story_params
-
2
params.require(:story).permit(:title, :mythology_id, :content, :creativity, :llm_name, :instructions,
-
storygods_attributes: [:id, :_destroy, :god_id, :role])
-
end
-
end
-
1
class StoryGodsController < ApplicationController
-
1
before_action :get_story
-
1
before_action :set_storygod, only: [:show, :edit, :update, :destroy]
-
-
1
def index
-
@storygods = @story.storygods
-
end
-
-
1
def show
-
end
-
-
1
def new
-
@storygod = @story.storygods.build
-
end
-
-
1
def edit
-
end
-
-
1
def create
-
@storygod = @story.storygods.build(storygod_params)
-
end
-
-
1
def update
-
end
-
-
1
def destroy
-
@storygod.destroy
-
end
-
-
1
private
-
-
1
def get_story
-
@story = Story.find(params[:story_id])
-
end
-
-
1
def set_storygod
-
@storygod = @story.storygods.find(params[:id])
-
end
-
-
1
def storygod_params
-
params.require(:storygod).permit(:story_id)
-
end
-
end
-
1
module ApplicationHelper
-
end
-
1
module StoryGodsHelper
-
end
-
1
class ApplicationJob < ActiveJob::Base
-
# Automatically retry jobs that encountered a deadlock
-
# retry_on ActiveRecord::Deadlocked
-
-
# Most jobs are safe to ignore if the underlying records are no longer available
-
# discard_on ActiveJob::DeserializationError
-
end
-
1
class StoryCreateJob < ApplicationJob
-
1
queue_as :default
-
-
1
def perform(*args)
-
2
story = Story.find(args[0])
-
-
2
case story.llm_name
-
when "openai"
-
2
llm = Langchain::LLM::OpenAI.new(api_key: ENV["OPENAI_API_KEY"], llm_options: {temperature: story.creativity_temp})
-
when "google"
-
llm = Langchain::LLM::GooglePalm.new(api_key: ENV["GOOGLE_PALM_API_KEY"], default_options: {temperature: story.creativity_temp})
-
else
-
logger.error "Unknown LLM: #{story.llm_name}"
-
end
-
-
1
story_template = Langchain::Prompt.load_from_path(file_path: "app/prompts/story_create_template.yaml")
-
1
prompt_text = story_template.format(mythology_name: story.mythology.name, title: story.title)
-
-
1
role_template = Langchain::Prompt.load_from_path(file_path: "app/prompts/story_role_template.yaml")
-
1
StoryGod.where(story_id: args[0]).find_each do |g|
-
prompt_text += " " + role_template.format(god: g.god.name, role: g.role)
-
end
-
-
1
instructions = story.instructions
-
1
if instructions
-
1
prompt = prompt_text + " Additional instructions for generating the story are " + instructions
-
end
-
-
1
story.update(content: llm.complete(prompt: prompt).completion)
-
end
-
end
-
1
class ApplicationMailer < ActionMailer::Base
-
1
default from: "from@example.com"
-
1
layout "mailer"
-
end
-
1
class ApplicationRecord < ActiveRecord::Base
-
1
primary_abstract_class
-
end
-
1
class God < ApplicationRecord
-
1
belongs_to :mythology # , dependent: :restrict_with_error <- gives error on db:setup
-
1
belongs_to :pantheon
-
-
1
has_many :storygods, dependent: :destroy
-
end
-
1
class Mythology < ApplicationRecord
-
end
-
1
class Pantheon < ApplicationRecord
-
end
-
1
class Story < ApplicationRecord
-
1
belongs_to :mythology
-
-
1
validates :title, presence: true
-
# validates :body, presence: true
-
1
has_rich_text :content
-
-
1
has_many :storygods, dependent: :destroy, class_name: "StoryGod"
-
1
accepts_nested_attributes_for :storygods, reject_if: :all_blank, allow_destroy: true
-
1
has_many :gods, through: :storygod
-
-
1
CREATIVITY_TEMPS = {
-
"Conservative" => 0.2,
-
"Balanced" => 0.5,
-
"Inventive" => 0.8
-
}.freeze
-
1
validates :creativity, presence: true, inclusion: {in: CREATIVITY_TEMPS.keys}
-
-
1
validates :llm_name, presence: true, inclusion: {in: LLMS}
-
-
1
def creativity_temp
-
3
CREATIVITY_TEMPS[creativity]
-
end
-
-
1
after_update -> {
-
begin
-
3
broadcast_replace_to "stories"
-
rescue => e
-
logger.error "Error occurred during broadcast_replace_to: #{e.message}"
-
end
-
}
-
end
-
1
class StoryGod < ApplicationRecord
-
1
belongs_to :story
-
1
belongs_to :god
-
# validates :story, presence: true
-
# validates :god, presence: true
-
1
validates :story, uniqueness: {scope: :god}
-
1
validates :god, uniqueness: {scope: :story}
-
-
1
def get_name
-
god[:name]
-
end
-
-
ROLES = [
-
1
"Protagonist",
-
"Antagonist",
-
"Deuteragonist",
-
"Love Interest",
-
"Confidant",
-
"Foil",
-
"Mentor",
-
"Sidekick",
-
"Tertiary Character"
-
]
-
1
validates :role, inclusion: {in: ROLES}
-
-
# enum role: {"Protagonist" => 0, "Antagonist" => 1, "Deuteragonist" => 2, "Love Interest" => 3, "Confidant" => 4, "Foil" => 5, "Mentor" => 6, "Sidekick" => 7, "Tertiary Character" => 8}
-
end