devai 0.5.12

Command Agent runner to accelerate production coding with genai.
# Config

```toml
[genai]
# Here we can override the default model for this agent only 
# This agent works with Claude Sonnet

# model = "claude-3-5-sonnet-20241022"

# e.g.,    OpenAI: "gpt-4o-mini", "gpt-4o", "o1-mini", "o1-preview"
#       Anthropic: "claude-3-5-sonnet-20241022", "claude-3-5-haiku-20241022", "claude-3-haiku-20240307"
#          Ollama: "llama3.1:70b" (or any locally installed Ollama)
```

# Data

```lua

-- == Step 1 == Load the doc files

-- The `list_load` will list the files from the devai parent dir and load each of them
-- so, each item is a FileRecord
local doc_files = utils.file.list_load(".devai/doc/**/*.md")

-- == Step 2 == Create/Load the `ask-devai.md`

local ask_file_path = ".devai/tmp/ask-devai.md"
local placeholder_text = [[
Placeholder: 
   - To ask your question, remove this placeholder section
   - ask your question 
   - and `devai run ask-devai`
   - or **Replay** in the terminal if already running
]]

if not utils.path.exists(ask_file_path) then
    utils.file.save(ask_file_path, placeholder_text)

    -- Open it with VSCode 
    -- Call with pcall to prevent failure if the code is not available
    -- TODO: Enhance this part (should notify the user)
    pcall(utils.cmd.exec,"code", {ask_file_path} )
end

-- Load & split_first markdown
local ask_file_split = utils.file.load_md_split_first(ask_file_path)

-- {before = "", first: MdSection, after: string}
-- For now, before is always empty, first is the MdSection with .content 
--          and .heading_content, and .heading_raw (empty string if no heading and heading content with '\n' if heading)

-- If it starts with placeholder, then we skip
local str = ask_file_split.first.content;
str = utils.text.trim(str) -- Trim leading and trailing spaces
if str:sub(1, 11):lower() == "placeholder" then
    return devai.skip("Question is a placeholder, so skipping for now")
end

-- == Step 3 == Return the data

return {
    doc_files        = doc_files,
    ask_file_path    = ask_file_path,
    ask_file_split   = ask_file_split,
}
```

# System

Your goal is to answer **devai** questions in a concise and precise manner, with some code examples when appropriate. 

**devai** is a command line utility that allows you to write agents in a markdown file, with full control over the prompt, using a multi-stage approach. 

Here are some documentation files, separated with `=== file/path/to/document.md` for you to refer to in your answer. 

{{#each data.doc_files}}

=== {{this.path}}
{{this.content}}

{{/each}}


# System

- When the user asks a question, provide the answer.
- Give me the file path of where the answer was found. 
- Format the answer this way:

```
# QUESTION: _user_question_

_answer_
```

- For the `_user_question_` text, if the question is short, put it there; if it is long or contains special characters, summarize the question and put it there. 
- For the `# Instruction` and `# System`, the content is just normal markdown, not in a markdown code block, except when putting some code, where it is appropriate to put them in the appropriate code block. 
- If it is appropriate, do not hesitate to use bullet points to help clarity and conciseness. 
- When the user asks to generate a stage of a devai file, do not wrap it with a `lua` code block, just `# stage_name` and then put the Lua code in the `lua` code block. 
- When providing the answer, do not surround it in a markdown code block.
- For the `# Instruction`, `# System`, and `# Assistant` sections, do not put the template in markdown codeblock handlebars, as this is not needed by devai. Just the test with the handlebars characters, that will work nice. 
- Remember, a `.devai` file is a markdown file, so when giving devai examples, do not surround the devai stages example with a markdown code block. Just put them in lines.
- When giving the reference to the doc file, prefix it with `../` and then add the full path with the `file/path/to/document.md`, and put them in a markdown link like `[../../file/path/to/document.md](../../file/path/to/document.md#possible_heading_anchor)`


# Instruction

Here is the user question: 

{{data.ask_file_split.first.content}}

# Output

```lua

-- Extract content from AI response
local answer = ai_response.content
-- Sometimes, some models still put the result in a markdown block. 
-- This alleviates some of these issues (when it starts with ```)
local answer = utils.text.trim(answer)
local answer = utils.md.outer_block_content_or_raw(answer)
local answer = utils.text.trim(answer)

-- Build the question content
local first = data.ask_file_split.first
local question = first.heading_raw .. first.content
-- Make sure it ends with only one newline
question = utils.text.ensure_single_ending_newline(question)

-- Concatenate the content from the file
local after = data.ask_file_split.after

local content = question .. "\n" .. answer .. "\n\n---\n\n" .. after

-- Save the new content back to the file
utils.file.save(data.ask_file_path, content)

return "done"

```