feat(write): Add basic support for prompts management
This commit is contained in:
parent
0832e4c877
commit
5689929c83
6 changed files with 183 additions and 45 deletions
24
data/prompts/01-each-chapter--build-toc.tpl
Normal file
24
data/prompts/01-each-chapter--build-toc.tpl
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{# GOAL: Build sections object containing subsections #}
|
||||||
|
|
||||||
|
Merci.
|
||||||
|
|
||||||
|
Suit la structure du PROGRAMME DE FORMATION.
|
||||||
|
|
||||||
|
Concentre toi sur le chapitre « {{chapter.title}} ».
|
||||||
|
|
||||||
|
Commence par écrire "boundary: {{ delimiter }}".
|
||||||
|
Ensuite rédige la table des matière détaillée de ce chapitre en respectant la structure suivante:
|
||||||
|
|
||||||
|
«
|
||||||
|
{
|
||||||
|
"type": "section",
|
||||||
|
"title": ""
|
||||||
|
"subsections": [
|
||||||
|
{ "type": "subsection", "title": "...", "keywords": ["...", "..."] },
|
||||||
|
{ "type": "subsection", "title": "...", "keywords": ["...", "..."] },
|
||||||
|
{ "type": "subsection", "title": "...", "keywords": ["...", "..."] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
»
|
||||||
|
|
||||||
|
Termine en écrivant "boundary: {{ delimiter }}".
|
|
@ -1,18 +0,0 @@
|
||||||
GOAL: Build sections object containing subsections
|
|
||||||
|
|
||||||
PROMPT:
|
|
||||||
|
|
||||||
Merci.
|
|
||||||
|
|
||||||
Suit la structure du PROGRAMME DE FORMATION.
|
|
||||||
|
|
||||||
Concentre toi sur le chapitre « {{this.title}} ».
|
|
||||||
|
|
||||||
Focalise toi plus spécifiquement sur les sections suivantes «
|
|
||||||
{% for child in this.children %}
|
|
||||||
* {{ child }}
|
|
||||||
{% endfor %}
|
|
||||||
» de ce chapitre sur lequel on se concentre.
|
|
||||||
|
|
||||||
Rédige la table des matière détaillée de ces différentes sections.
|
|
||||||
Ajoute également à la fin les différents travaux pratiques possibles pour chaque section.
|
|
|
@ -1,5 +1,9 @@
|
||||||
version: 2.0
|
version: 2.0
|
||||||
shards:
|
shards:
|
||||||
|
baked_file_system:
|
||||||
|
git: https://github.com/schovi/baked_file_system.git
|
||||||
|
version: 0.10.0
|
||||||
|
|
||||||
cor:
|
cor:
|
||||||
git: https://github.com/watzon/cor.git
|
git: https://github.com/watzon/cor.git
|
||||||
version: 0.1.0+git.commit.9c9e51ac6168f3bd4fdc51d679b65de09ef76cac
|
version: 0.1.0+git.commit.9c9e51ac6168f3bd4fdc51d679b65de09ef76cac
|
||||||
|
|
|
@ -17,6 +17,9 @@ dependencies:
|
||||||
github: crystal-term/prompt
|
github: crystal-term/prompt
|
||||||
crinja:
|
crinja:
|
||||||
github: straight-shoota/crinja
|
github: straight-shoota/crinja
|
||||||
|
baked_file_system:
|
||||||
|
github: schovi/baked_file_system
|
||||||
|
version: 0.10.0
|
||||||
|
|
||||||
# FIXME: for prompts rendering
|
# FIXME: for prompts rendering
|
||||||
|
|
||||||
|
|
7
src/write/file_storage.cr
Normal file
7
src/write/file_storage.cr
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
require "baked_file_system"
|
||||||
|
|
||||||
|
class FileStorage
|
||||||
|
extend BakedFileSystem
|
||||||
|
|
||||||
|
bake_folder "../../data/prompts"
|
||||||
|
end
|
172
src/write/run.cr
172
src/write/run.cr
|
@ -1,60 +1,178 @@
|
||||||
|
|
||||||
# Core
|
# Core
|
||||||
require "file_utils"
|
require "file_utils"
|
||||||
|
require "path"
|
||||||
|
|
||||||
# Internal
|
# Internal
|
||||||
require "./config"
|
require "./config"
|
||||||
|
require "./nodes/root_node"
|
||||||
|
|
||||||
# Shards
|
# Shards
|
||||||
require "term-prompt"
|
require "term-prompt"
|
||||||
|
require "crinja"
|
||||||
|
|
||||||
module DocMachine::Write
|
module DocMachine::Write
|
||||||
class Run
|
class Run
|
||||||
private property config : DocMachine::Write::Config
|
private property config : DocMachine::Write::Config
|
||||||
|
property root = Nodes::RootNode.new
|
||||||
|
|
||||||
def initialize(@config)
|
def initialize(@config)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Verify parameters
|
def validate_build_dir()
|
||||||
def prepare()
|
|
||||||
if ! File.directory? @config.target_directory
|
if ! File.directory? @config.target_directory
|
||||||
Log.error { "Target must be a directory" }
|
Log.error { "Target must be a directory" }
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
Log.info { "Target directory: #{@config.target_directory}" }
|
Log.info { "Target directory: #{@config.target_directory}" }
|
||||||
|
|
||||||
if !@config.force
|
|
||||||
prompt = Term::Prompt.new
|
|
||||||
confirm = prompt.no?("Are you sure you want to proceed?")
|
|
||||||
exit 1 if !confirm
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def start()
|
def ask_confirmation
|
||||||
Log.info { "== Writeing #{@config.target_directory}" }
|
# if !@config.force
|
||||||
p = Path.new(@config.target_directory)
|
# prompt = Term::Prompt.new
|
||||||
cwd = Dir.current
|
# confirm = prompt.no?("Are you sure you want to proceed?")
|
||||||
["docs", "slides", "images"].each do |dir|
|
# exit 1 if !confirm
|
||||||
p_sub = p.join(dir)
|
# end
|
||||||
Log.info { "-- creating #{p_sub}" }
|
end
|
||||||
FileUtils.mkdir_p(p_sub)
|
|
||||||
|
def load_templates
|
||||||
|
pp @config
|
||||||
|
|
||||||
|
context_file = Path[@config.target_directory] / "CONTEXT.tpl"
|
||||||
|
if ! File.exists? context_file
|
||||||
|
raise "Context file #{context_file} is missing"
|
||||||
end
|
end
|
||||||
["docs", "slides"].each do |dir|
|
@root.context = File.read(context_file)
|
||||||
p_sub = p.join(dir)
|
|
||||||
FileUtils.cd(p_sub)
|
audience_file = Path[@config.target_directory] / "AUDIENCE.tpl"
|
||||||
Log.info { "-- creating link to images in #{p_sub}" }
|
if ! File.exists? audience_file
|
||||||
if File.symlink? "images"
|
raise "Audience file #{audience_file} is missing"
|
||||||
FileUtils.rm "images"
|
|
||||||
end
|
|
||||||
FileUtils.ln_sf(Path.new("..","images"), Path.new("images"))
|
|
||||||
FileUtils.cd(cwd)
|
|
||||||
end
|
end
|
||||||
Log.info { "-- creating README.md" }
|
@root.audience = File.read(audience_file)
|
||||||
FileUtils.touch("README.md")
|
|
||||||
|
goals_file = Path[@config.target_directory] / "GOALS.tpl"
|
||||||
|
if ! File.exists? goals_file
|
||||||
|
raise "Audience file #{goals_file} is missing"
|
||||||
|
end
|
||||||
|
@root.goals = File.read(goals_file)
|
||||||
|
|
||||||
|
constraints_file = Path[@config.target_directory] / "CONSTRAINTS.tpl"
|
||||||
|
if ! File.exists? constraints_file
|
||||||
|
raise "Audience file #{constraints_file} is missing"
|
||||||
|
end
|
||||||
|
@root.constraints = File.read(constraints_file)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Verify parameters
|
# Verify parameters
|
||||||
|
def prepare()
|
||||||
|
validate_build_dir()
|
||||||
|
ask_confirmation()
|
||||||
|
load_templates()
|
||||||
|
Log.debug { "done" }
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
## ContentNode
|
||||||
|
## type: ...
|
||||||
|
## title: ...
|
||||||
|
## keywords: ...
|
||||||
|
## content: ...
|
||||||
|
##
|
||||||
|
|
||||||
|
def start()
|
||||||
|
@root.chapters = root.build_chapters()
|
||||||
|
|
||||||
|
@root.chapters.each do |chapter|
|
||||||
|
chapter.sections = chapter.build_sections()
|
||||||
|
|
||||||
|
chapter.sections.each do |section|
|
||||||
|
section.subsections = section.build_subsections()
|
||||||
|
# FIXME(later): section.exercises = section.build_exercises()
|
||||||
|
|
||||||
|
section.subsections.each do |subsection|
|
||||||
|
subsection.content = subsection.build_content()
|
||||||
|
subsection.content = subsection.fix_content()
|
||||||
|
# FIXME(later): subsection.exercises = subsection.build_exercises()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
## Level 0 - each topic : build TOC (chapter list)
|
||||||
|
def from_topic_build_chapters
|
||||||
|
chapter_build_toc_template = FileStorage.get("./../data/prompts/01-each-chapter--build-toc.tpl")
|
||||||
|
chapters = [{ "title": "Terraform on Azure" }]
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
## Level 1 - each chapter : build TOC (section list)
|
||||||
|
# 1. build chat
|
||||||
|
# - (system) quality & style guidance
|
||||||
|
# - (user) context
|
||||||
|
# - (user) audience
|
||||||
|
# - (user) objectives
|
||||||
|
# - (user) main toc (chapters)
|
||||||
|
def from_chapter_build_sections()
|
||||||
|
delimiter = "34e127df" # FIXME: random 8 bytes hex string
|
||||||
|
chapters.each do |chapter|
|
||||||
|
template_vars = {
|
||||||
|
delimiter: delimiter,
|
||||||
|
chapter: chapter
|
||||||
|
}
|
||||||
|
render = Crinja.render(chapter_build_toc_template, template_vars)
|
||||||
|
puts render
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
## Level 2 - each section : build TOC (subsection list)
|
||||||
|
# 1. build chat
|
||||||
|
# - (system) quality & style guidance
|
||||||
|
# - (user) context
|
||||||
|
# - (user) audience
|
||||||
|
# - (user) objectives
|
||||||
|
# - (user) main toc (chapters)
|
||||||
|
# - (user) chapter toc (sections)
|
||||||
|
# 2. make openai request
|
||||||
|
# 3. validate result structure
|
||||||
|
# 4. create section objects in memory
|
||||||
|
def from_section_build_subsections()
|
||||||
|
section_build_toc_tpl = File.read(DOCMACHINE_DATA_PATH / "prompts" / "02-each-section--build-toc.tpl")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
## Level 2 - each section : build EXERCISES
|
||||||
|
# 1. build chat
|
||||||
|
# - (system) quality & style guidance
|
||||||
|
# - (user) context
|
||||||
|
# - (user) audience
|
||||||
|
# - (user) objectives
|
||||||
|
# - (user) main toc (chapters)
|
||||||
|
# - (user) chapter toc (sections)
|
||||||
|
# 2. make openai request
|
||||||
|
# 3. validate result structure
|
||||||
|
# 4. create exercises objects in memory
|
||||||
|
def from_section_build_exercises()
|
||||||
|
section_build_toc_tpl = File.read(DOCMACHINE_DATA_PATH / "prompts" / "02-each-section--build-exercises.tpl")
|
||||||
|
end
|
||||||
|
|
||||||
|
def from_subsection_build_content()
|
||||||
|
## Level 3 - each subsection : build CONTENT
|
||||||
|
section_build_toc_tpl = File.read(DOCMACHINE_DATA_PATH / "prompts" / "02-each-subsection--build-content.tpl")
|
||||||
|
end
|
||||||
|
|
||||||
|
def from_subsection_fix_content()
|
||||||
|
## Level 4 - each subsection : build FIXED CONTENT
|
||||||
|
section_build_toc_tpl = File.read(DOCMACHINE_DATA_PATH / "prompts" / "02-each-subsection--fix-content.tpl")
|
||||||
|
end
|
||||||
|
|
||||||
|
def from_subsection_build_exercises()
|
||||||
|
## Level 1 - each subsection EXERCICES
|
||||||
|
section_build_toc_tpl = File.read(DOCMACHINE_DATA_PATH / "prompts" / "02-each-subsection--build-exercises.tpl")
|
||||||
|
end
|
||||||
|
|
||||||
def wait()
|
def wait()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue