feat: move prompts to a separat file
This commit is contained in:
@@ -2,70 +2,7 @@ local M = {}
|
|||||||
local uv = vim.loop
|
local uv = vim.loop
|
||||||
|
|
||||||
local ok_yaml, lyaml = pcall(require, "lyaml")
|
local ok_yaml, lyaml = pcall(require, "lyaml")
|
||||||
|
local prompts = require("chatgpt_nvim.prompts")
|
||||||
local prompt_blocks = {
|
|
||||||
["go-development"] = [[
|
|
||||||
You are a coding assistant specialized in Go development.
|
|
||||||
You will receive a project’s 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 project’s context and the user’s 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 project’s 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 project’s 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 function get_project_root()
|
local function get_project_root()
|
||||||
local current_file = vim.fn.expand("%:p")
|
local current_file = vim.fn.expand("%:p")
|
||||||
@@ -104,7 +41,7 @@ function M.load()
|
|||||||
directories = { "." },
|
directories = { "." },
|
||||||
default_prompt_blocks = {},
|
default_prompt_blocks = {},
|
||||||
-- Changed default from 128000 to 16384 as requested
|
-- Changed default from 128000 to 16384 as requested
|
||||||
token_limit = 16384,
|
prompt_char_limit = 300000,
|
||||||
project_name = "",
|
project_name = "",
|
||||||
debug = false,
|
debug = false,
|
||||||
initial_files = {},
|
initial_files = {},
|
||||||
@@ -134,8 +71,8 @@ function M.load()
|
|||||||
if type(result.default_prompt_blocks) == "table" then
|
if type(result.default_prompt_blocks) == "table" then
|
||||||
config.default_prompt_blocks = result.default_prompt_blocks
|
config.default_prompt_blocks = result.default_prompt_blocks
|
||||||
end
|
end
|
||||||
if type(result.token_limit) == "number" then
|
if type(result.prompt_char_limit) == "number" then
|
||||||
config.token_limit = result.token_limit
|
config.prompt_char_limit = result.prompt_char_limit
|
||||||
end
|
end
|
||||||
if type(result.project_name) == "string" then
|
if type(result.project_name) == "string" then
|
||||||
config.project_name = result.project_name
|
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
|
if type(config.default_prompt_blocks) == "table" and #config.default_prompt_blocks > 0 then
|
||||||
local merged_prompt = {}
|
local merged_prompt = {}
|
||||||
for _, block_name in ipairs(config.default_prompt_blocks) do
|
for _, block_name in ipairs(config.default_prompt_blocks) do
|
||||||
if prompt_blocks[block_name] then
|
if prompts[block_name] then
|
||||||
table.insert(merged_prompt, prompt_blocks[block_name])
|
table.insert(merged_prompt, prompts[block_name])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if #merged_prompt > 0 then
|
if #merged_prompt > 0 then
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ local context = require('chatgpt_nvim.context')
|
|||||||
local handler = require('chatgpt_nvim.handler')
|
local handler = require('chatgpt_nvim.handler')
|
||||||
local config = require('chatgpt_nvim.config')
|
local config = require('chatgpt_nvim.config')
|
||||||
local ui = require('chatgpt_nvim.ui')
|
local ui = require('chatgpt_nvim.ui')
|
||||||
|
local prompts = require('chatgpt_nvim.prompts')
|
||||||
|
|
||||||
local ok_yaml, lyaml = pcall(require, "lyaml")
|
local ok_yaml, lyaml = pcall(require, "lyaml")
|
||||||
|
|
||||||
@@ -53,21 +54,13 @@ local function is_directory(path)
|
|||||||
return stat and stat.type == "directory"
|
return stat and stat.type == "directory"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- We now simply count characters instead of estimating tokens.
|
|
||||||
local function handle_step_by_step_if_needed(prompt)
|
local function handle_step_by_step_if_needed(prompt)
|
||||||
local conf = config.load()
|
local conf = config.load()
|
||||||
local length = #prompt
|
local length = #prompt
|
||||||
if not conf.enable_step_by_step or length <= (conf.prompt_char_limit or 8000) then
|
if not conf.enable_step_by_step or length <= (conf.prompt_char_limit or 8000) then
|
||||||
return { prompt }
|
return { prompt }
|
||||||
end
|
end
|
||||||
|
return { prompts["step-prompt"] }
|
||||||
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 }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function close_existing_buffer_by_name(pattern)
|
local function close_existing_buffer_by_name(pattern)
|
||||||
@@ -373,22 +366,7 @@ function M.run_chatgpt_command()
|
|||||||
|
|
||||||
if conf.enable_debug_commands then
|
if conf.enable_debug_commands then
|
||||||
table.insert(initial_sections, "\n### Debug Commands Info:\n")
|
table.insert(initial_sections, "\n### Debug Commands Info:\n")
|
||||||
table.insert(initial_sections, [[
|
table.insert(initial_sections, prompts["debug-commands-info"])
|
||||||
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.
|
|
||||||
]])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local prompt = table.concat(initial_sections, "\n")
|
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)
|
ui.debug_log("Returning requested files. Character count: " .. length)
|
||||||
|
|
||||||
if length > (conf.prompt_char_limit or 8000) and conf.enable_step_by_step then
|
if length > (conf.prompt_char_limit or 8000) and conf.enable_step_by_step then
|
||||||
local step_message = [[
|
local large_step = prompts["step-prompt"]
|
||||||
It appears this requested data is quite large. Please split the task into smaller steps
|
copy_to_clipboard(large_step)
|
||||||
and continue step by step.
|
|
||||||
Which files would you need for the first step?
|
|
||||||
]]
|
|
||||||
copy_to_clipboard(step_message)
|
|
||||||
print("Step-by-step guidance copied to clipboard!")
|
print("Step-by-step guidance copied to clipboard!")
|
||||||
return
|
return
|
||||||
elseif length > (conf.prompt_char_limit or 8000) then
|
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
|
if conf.enable_debug_commands then
|
||||||
table.insert(initial_sections, "\n### Debug Commands Info:\n")
|
table.insert(initial_sections, "\n### Debug Commands Info:\n")
|
||||||
table.insert(initial_sections, [[
|
table.insert(initial_sections, prompts["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 "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.
|
|
||||||
]])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local prompt = table.concat(initial_sections, "\n")
|
local prompt = table.concat(initial_sections, "\n")
|
||||||
|
|||||||
90
lua/chatgpt_nvim/prompts.lua
Normal file
90
lua/chatgpt_nvim/prompts.lua
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
local M = {
|
||||||
|
["go-development"] = [[
|
||||||
|
You are a coding assistant specialized in Go development.
|
||||||
|
You will receive a project’s 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 project’s context and the user’s 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 project’s 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 project’s 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
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
local M = {}
|
local M = {}
|
||||||
local config = require('chatgpt_nvim.config')
|
local config = require('chatgpt_nvim.config')
|
||||||
local conf = config.load()
|
local conf = config.load()
|
||||||
|
local prompts = require('chatgpt_nvim.prompts')
|
||||||
|
|
||||||
local debug_bufnr = nil
|
local debug_bufnr = nil
|
||||||
if conf.improved_debug then
|
if conf.improved_debug then
|
||||||
@@ -29,7 +30,9 @@ end
|
|||||||
|
|
||||||
function M.pick_directories(dirs)
|
function M.pick_directories(dirs)
|
||||||
local selected_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
|
for _, d in ipairs(dirs) do
|
||||||
table.insert(lines, d)
|
table.insert(lines, d)
|
||||||
end
|
end
|
||||||
@@ -88,8 +91,4 @@ function M.pick_directories(dirs)
|
|||||||
return selected_dirs
|
return selected_dirs
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- The old chunkify method has been removed, since we now rely on step-by-step
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
return M
|
return M
|
||||||
Reference in New Issue
Block a user