feat: move prompts to a separat file

This commit is contained in:
2025-01-04 21:14:12 +01:00
parent 2c855e881b
commit 3505a295a9
4 changed files with 107 additions and 122 deletions

View File

@@ -2,70 +2,7 @@ local M = {}
local uv = vim.loop
local ok_yaml, lyaml = pcall(require, "lyaml")
local prompt_blocks = {
["go-development"] = [[
You are a coding assistant specialized in Go development.
You will receive a projects context and user instructions related to Go code,
and you must return the requested modifications or guidance.
When returning modifications, follow the specified YAML structure.
Keep your suggestions aligned with Go best practices and idiomatic Go.
]],
["typo3-development"] = [[
You are a coding assistant specialized in TYPO3 development.
You have access to the projects context and the users instructions.
Your answers should focus on TYPO3 coding guidelines, extension development best practices,
and TSconfig or TypoScript recommendations.
]],
["rust-development"] = [[
You are a coding assistant specialized in Rust development.
You will receive a projects context and user instructions related to Rust code,
and you must return the requested modifications or guidance.
When returning modifications, follow the specified YAML structure.
Keep your suggestions aligned with Rust best practices and idiomatic Rust.
]],
["basic-prompt"] = [[
You are a coding assistant who receives a project's context and user instructions.
The user will provide a prompt, and you will guide them through a workflow:
1. First, you should analyse which files you need to solve the request.
You can see which files are present in the provided project structure.
Additionally if presented you could also ask for files of a library which is provided in for example composer.json.
2. If file contents is needed provide a yaml which asks for the file contents.
For example:
project_name: example_project
files:
- path: "relative/path/to/file"
3. If more information or context is needed, ask the user (outside of the YAML) to provide that.
4. When all necessary information is gathered, provide the final YAML with the
project's name and a list of files to be created or modified.
Also explain the changes you made below the yaml.
The final YAML must have a top-level key named 'project_name' that matches the project's configured name,
and a top-level key named 'files', which is a list of file changes. Each element in 'files' must be a mapping with:
- 'path' for the file path relative to the projects root directory.
- either 'content' with a multiline string for new content, or 'delete: true' if the file should be deleted.
Important: dont use comments in the code to explain which steps you have taken.
Comments should just explain the code and not your thought process.
You can explain your thought process outside of the YAML.
If more context is needed at any point before providing the final YAML, request it outside of the YAML.
Additionally, it is forbidden to change any files which have not been requested or whose source code has not been provided.
]],
["secure-coding"] = [[
You are a coding assistant specialized in secure software development.
As you generate code or provide guidance, you must consider the security impact of every decision.
You will write and review code with a focus on minimizing vulnerabilities and following best security practices,
such as validating all user inputs, avoiding unsafe libraries or functions, and following secure coding standards.
]],
["workflow-prompt"] = [[
You are a coding assistant focusing on making the Neovim ChatGPT workflow straightforward and user-friendly.
Provide a concise set of steps or guidance, reminding the user:
- How to list needed files for further context
- How to request additional information outside of the YAML
- How to finalize changes with a YAML response containing project_name and files
Always ensure that prompts and explanations remain clear and minimal, reducing user errors.
]]
}
local prompts = require("chatgpt_nvim.prompts")
local function get_project_root()
local current_file = vim.fn.expand("%:p")
@@ -104,7 +41,7 @@ function M.load()
directories = { "." },
default_prompt_blocks = {},
-- Changed default from 128000 to 16384 as requested
token_limit = 16384,
prompt_char_limit = 300000,
project_name = "",
debug = false,
initial_files = {},
@@ -134,8 +71,8 @@ function M.load()
if type(result.default_prompt_blocks) == "table" then
config.default_prompt_blocks = result.default_prompt_blocks
end
if type(result.token_limit) == "number" then
config.token_limit = result.token_limit
if type(result.prompt_char_limit) == "number" then
config.prompt_char_limit = result.prompt_char_limit
end
if type(result.project_name) == "string" then
config.project_name = result.project_name
@@ -178,8 +115,8 @@ function M.load()
if type(config.default_prompt_blocks) == "table" and #config.default_prompt_blocks > 0 then
local merged_prompt = {}
for _, block_name in ipairs(config.default_prompt_blocks) do
if prompt_blocks[block_name] then
table.insert(merged_prompt, prompt_blocks[block_name])
if prompts[block_name] then
table.insert(merged_prompt, prompts[block_name])
end
end
if #merged_prompt > 0 then

View File

@@ -4,6 +4,7 @@ local context = require('chatgpt_nvim.context')
local handler = require('chatgpt_nvim.handler')
local config = require('chatgpt_nvim.config')
local ui = require('chatgpt_nvim.ui')
local prompts = require('chatgpt_nvim.prompts')
local ok_yaml, lyaml = pcall(require, "lyaml")
@@ -53,21 +54,13 @@ local function is_directory(path)
return stat and stat.type == "directory"
end
-- We now simply count characters instead of estimating tokens.
local function handle_step_by_step_if_needed(prompt)
local conf = config.load()
local length = #prompt
if not conf.enable_step_by_step or length <= (conf.prompt_char_limit or 8000) then
return { prompt }
end
local step_prompt = [[
It appears this request might exceed the model's prompt character limit if done all at once.
Please break down the tasks into smaller steps and handle them one by one.
At each step, we'll provide relevant files or context if needed.
Thank you!
]]
return { step_prompt }
return { prompts["step-prompt"] }
end
local function close_existing_buffer_by_name(pattern)
@@ -373,22 +366,7 @@ function M.run_chatgpt_command()
if conf.enable_debug_commands then
table.insert(initial_sections, "\n### Debug Commands Info:\n")
table.insert(initial_sections, [[
If you need debugging commands, include them in your YAML response as follows:
```yaml
commands:
- command: "ls"
dir: "some/directory"
- command: "grep"
pattern: "searchString"
target: "path/to/file/or/directory"
```
The "ls" command uses the system's 'ls' command to list directory contents.
When these commands are present and enable_debug_commands is true, I'll execute them and return the results in the clipboard.
]])
table.insert(initial_sections, prompts["debug-commands-info"])
end
local prompt = table.concat(initial_sections, "\n")
@@ -538,12 +516,8 @@ function M.run_chatgpt_paste_command()
ui.debug_log("Returning requested files. Character count: " .. length)
if length > (conf.prompt_char_limit or 8000) and conf.enable_step_by_step then
local step_message = [[
It appears this requested data is quite large. Please split the task into smaller steps
and continue step by step.
Which files would you need for the first step?
]]
copy_to_clipboard(step_message)
local large_step = prompts["step-prompt"]
copy_to_clipboard(large_step)
print("Step-by-step guidance copied to clipboard!")
return
elseif length > (conf.prompt_char_limit or 8000) then
@@ -630,22 +604,7 @@ function M.run_chatgpt_current_buffer_command()
if conf.enable_debug_commands then
table.insert(initial_sections, "\n### Debug Commands Info:\n")
table.insert(initial_sections, [[
If you need debugging commands, include them in your YAML response as follows:
```yaml
commands:
- command: "list"
dir: "some/directory"
- command: "grep"
pattern: "searchString"
target: "path/to/file/or/directory"
```
The "list" command uses the system's 'ls' command to list directory contents.
When these commands are present and enable_debug_commands is true, I'll execute them and return the results in the clipboard.
]])
table.insert(initial_sections, prompts["debug-commands-info"])
end
local prompt = table.concat(initial_sections, "\n")

View File

@@ -0,0 +1,90 @@
local M = {
["go-development"] = [[
You are a coding assistant specialized in Go development.
You will receive a projects context and user instructions related to Go code,
and you must return the requested modifications or guidance.
When returning modifications, follow the specified YAML structure.
Keep your suggestions aligned with Go best practices and idiomatic Go.
]],
["typo3-development"] = [[
You are a coding assistant specialized in TYPO3 development.
You have access to the projects context and the users instructions.
Your answers should focus on TYPO3 coding guidelines, extension development best practices,
and TSconfig or TypoScript recommendations.
]],
["rust-development"] = [[
You are a coding assistant specialized in Rust development.
You will receive a projects context and user instructions related to Rust code,
and you must return the requested modifications or guidance.
When returning modifications, follow the specified YAML structure.
Keep your suggestions aligned with Rust best practices and idiomatic Rust.
]],
["basic-prompt"] = [[
You are a coding assistant who receives a project's context and user instructions.
The user will provide a prompt, and you will guide them through a workflow:
1. First, you should analyse which files you need to solve the request.
You can see which files are present in the provided project structure.
Additionally if presented you could also ask for files of a library which is provided in for example composer.json.
2. If file contents is needed provide a yaml which asks for the file contents.
For example:
project_name: example_project
files:
- path: "relative/path/to/file"
3. If more information or context is needed, ask the user (outside of the YAML) to provide that.
4. When all necessary information is gathered, provide the final YAML with the
project's name and a list of files to be created or modified.
Also explain the changes you made below the yaml.
The final YAML must have a top-level key named 'project_name' that matches the project's configured name,
and a top-level key named 'files', which is a list of file changes. Each element in 'files' must be a mapping with:
- 'path' for the file path relative to the projects root directory.
- either 'content' with a multiline string for new content, or 'delete: true' if the file should be deleted.
Important: dont use comments in the code to explain which steps you have taken.
Comments should just explain the code and not your thought process.
You can explain your thought process outside of the YAML.
If more context is needed at any point before providing the final YAML, request it outside of the YAML.
Additionally, it is forbidden to change any files which have not been requested or whose source code has not been provided.
]],
["secure-coding"] = [[
You are a coding assistant specialized in secure software development.
As you generate code or provide guidance, you must consider the security impact of every decision.
You will write and review code with a focus on minimizing vulnerabilities and following best security practices,
such as validating all user inputs, avoiding unsafe libraries or functions, and following secure coding standards.
]],
["workflow-prompt"] = [[
You are a coding assistant focusing on making the Neovim ChatGPT workflow straightforward and user-friendly.
Provide a concise set of steps or guidance, reminding the user:
- How to list needed files for further context
- How to request additional information outside of the YAML
- How to finalize changes with a YAML response containing project_name and files
Always ensure that prompts and explanations remain clear and minimal, reducing user errors.
]],
["step-prompt"] = [[
It appears this request might exceed the model's prompt character limit if done all at once.
Please break down the tasks into smaller steps and handle them one by one.
At each step, we'll provide relevant files or context if needed.
Thank you!
]],
["file-selection-instructions"] = [[
Delete lines for directories you do NOT want, then save & close (e.g. :wq, :x, or :bd)
]],
["debug-commands-info"] = [[
If you need debugging commands, include them in your YAML response as follows:
```yaml
commands:
- command: "list"
dir: "some/directory"
- command: "grep"
pattern: "searchString"
target: "path/to/file/or/directory"
```
The "ls" command uses the system's 'ls' command to list directory contents.
When these commands are present and enable_debug_commands is true, I'll execute them and return the results in the clipboard.
]]
}
return M

View File

@@ -1,6 +1,7 @@
local M = {}
local config = require('chatgpt_nvim.config')
local conf = config.load()
local prompts = require('chatgpt_nvim.prompts')
local debug_bufnr = nil
if conf.improved_debug then
@@ -29,7 +30,9 @@ end
function M.pick_directories(dirs)
local selected_dirs = {}
local lines = { "Delete lines for directories you do NOT want, then save & close (e.g. :wq, :x, or :bd)" }
local selection_instructions = prompts["file-selection-instructions"]
local lines = { selection_instructions }
for _, d in ipairs(dirs) do
table.insert(lines, d)
end
@@ -88,8 +91,4 @@ function M.pick_directories(dirs)
return selected_dirs
end
--------------------------------------------------------------------------------
-- The old chunkify method has been removed, since we now rely on step-by-step
--------------------------------------------------------------------------------
return M