feat(write): Add basic support for prompts management

This commit is contained in:
Glenn Y. Rolland 2023-04-27 09:51:17 +02:00
parent 0832e4c877
commit 5689929c83
6 changed files with 183 additions and 45 deletions

View 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 }}".

View file

@ -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.

View file

@ -1,5 +1,9 @@
version: 2.0
shards:
baked_file_system:
git: https://github.com/schovi/baked_file_system.git
version: 0.10.0
cor:
git: https://github.com/watzon/cor.git
version: 0.1.0+git.commit.9c9e51ac6168f3bd4fdc51d679b65de09ef76cac

View file

@ -17,6 +17,9 @@ dependencies:
github: crystal-term/prompt
crinja:
github: straight-shoota/crinja
baked_file_system:
github: schovi/baked_file_system
version: 0.10.0
# FIXME: for prompts rendering

View file

@ -0,0 +1,7 @@
require "baked_file_system"
class FileStorage
extend BakedFileSystem
bake_folder "../../data/prompts"
end

View file

@ -1,60 +1,178 @@
# Core
require "file_utils"
require "path"
# Internal
require "./config"
require "./nodes/root_node"
# Shards
require "term-prompt"
require "crinja"
module DocMachine::Write
class Run
private property config : DocMachine::Write::Config
property root = Nodes::RootNode.new
def initialize(@config)
end
# Verify parameters
def prepare()
def validate_build_dir()
if ! File.directory? @config.target_directory
Log.error { "Target must be a directory" }
exit 1
end
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
def start()
Log.info { "== Writeing #{@config.target_directory}" }
p = Path.new(@config.target_directory)
cwd = Dir.current
["docs", "slides", "images"].each do |dir|
p_sub = p.join(dir)
Log.info { "-- creating #{p_sub}" }
FileUtils.mkdir_p(p_sub)
def ask_confirmation
# if !@config.force
# prompt = Term::Prompt.new
# confirm = prompt.no?("Are you sure you want to proceed?")
# exit 1 if !confirm
# end
end
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
["docs", "slides"].each do |dir|
p_sub = p.join(dir)
FileUtils.cd(p_sub)
Log.info { "-- creating link to images in #{p_sub}" }
if File.symlink? "images"
FileUtils.rm "images"
end
FileUtils.ln_sf(Path.new("..","images"), Path.new("images"))
FileUtils.cd(cwd)
@root.context = File.read(context_file)
audience_file = Path[@config.target_directory] / "AUDIENCE.tpl"
if ! File.exists? audience_file
raise "Audience file #{audience_file} is missing"
end
Log.info { "-- creating README.md" }
FileUtils.touch("README.md")
@root.audience = File.read(audience_file)
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
# 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()
end
end