Switching to a different system_prompt
after input
#1235
-
I know it's possible to set a default I know that with |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 3 replies
-
You can't and I'm not sure what the use case for this would be in practice. You can edit historical messages with |
Beta Was this translation helpful? Give feedback.
-
I have a custom setup for this: It does exactly what you asked for. The prompt given is not at all tested. But the system works. You can dynamically replace the system prompt of the current chat open. local M = {}
-- Store the default prompt from codecompanion config
M.default_prompt = require("codecompanion.config").opts.system_prompt
-- Table to store registered modes and prompts
M.modes = {}
-- Register a new mode
function M.register_mode(name, module)
M.modes[name] = module
end
-- Resolve prompt for a mode
function M.resolve_prompt(mode_name, opts)
if mode_name == "default" then
if type(M.default_prompt) == "function" then
return M.default_prompt(opts)
end
return M.default_prompt or ""
end
--mode can be a function or a string or a table with prompt function
local mode = M.modes[mode_name]
if mode then
if mode.prompt then
return type(mode.prompt) == "function" and mode.prompt(opts) or mode.prompt
else
return type(mode) == "function" and mode(opts) or mode
end
end
end
-- Update system prompt for an existing chat
function M.update_chat_prompt(chat, mode_name)
if not chat then
return
end
-- Remove existing system prompts with "from_config" tag
chat.messages = vim.tbl_filter(function(msg)
return not (msg.role == "system" and msg.opts and msg.opts.tag == "from_config")
end, chat.messages)
-- Add new system prompt
local prompt = M.resolve_prompt(mode_name, {
adapter = chat.adapter,
language = vim.g.codecompanion_language,
})
if prompt ~= "" then
chat:add_system_prompt(prompt)
end
end
-- Switch to a new mode
function M.switch_mode(mode_name)
vim.g.cc_mode = mode_name
-- Update existing chat if present
local chat = require("codecompanion.strategies.chat").last_chat()
if chat then
M.update_chat_prompt(chat, mode_name)
vim.notify("Switched to " .. mode_name .. " mode")
end
end
-- Get all available modes
function M.get_modes()
local mode_list = {}
-- Add built-in modes
for name, _ in pairs(M.modes) do
table.insert(mode_list, {
name = name,
prompt = M.resolve_prompt(name, {}),
})
end
return mode_list
end
-- Browse available modes using telescope
function M.browse()
require("user.codecompanion.modes.telescope").browse(M)
end
-- Initialize modes
function M.setup()
-- add built-in mode to switch to default prompt
M.register_mode("default", function()
return M.default_prompt
end)
-- add user defined modes
M.register_mode("edit", require("user.codecompanion.modes.edit"))
M.register_mode("architect", require("user.codecompanion.modes.architect"))
end
return M telescope.lua local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
local conf = require("telescope.config").values
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local previewers = require("telescope.previewers")
local M = {}
-- Custom previewer with line wrapping
M.prompt_previewer = previewers.new_buffer_previewer({
title = "System Prompt Preview",
define_preview = function(self, entry, status)
local preview = entry.preview
if type(preview) == "string" then
-- Split the preview into lines
local lines = vim.split(preview, "\n")
-- Clean up empty lines at start and end
while lines[1] and lines[1]:match("^%s*$") do
table.remove(lines, 1)
end
while lines[#lines] and lines[#lines]:match("^%s*$") do
table.remove(lines)
end
-- Set buffer options for better rendering
vim.api.nvim_buf_set_option(self.state.bufnr, "filetype", "markdown")
vim.api.nvim_win_set_option(self.state.winid, "wrap", true)
vim.api.nvim_win_set_option(self.state.winid, "linebreak", true)
-- Insert the lines
vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, lines)
end
end
})
function M.browse(modes)
local available_modes = modes.get_modes()
-- Sort modes to put built-in modes at the top
table.sort(available_modes, function(a, b)
local a_builtin = modes.modes[a.name] ~= nil
local b_builtin = modes.modes[b.name] ~= nil
if a_builtin ~= b_builtin then
return a_builtin
end
return a.name < b.name
end)
-- Add user icon to built-in modes and * for current mode
local current_mode = vim.g.cc_mode or "default"
for _, mode in ipairs(available_modes) do
local display = mode.name:gsub("^%l", string.upper)
if modes.modes[mode.name] then
display = ' ' .. display
end
if mode.name == current_mode then
display = display .. ' *'
end
mode.display = display
end
pickers.new({}, {
prompt_title = "Select Chat Mode",
finder = finders.new_table({
results = available_modes,
entry_maker = function(entry)
return {
value = entry,
display = entry.display,
ordinal = entry.name,
preview = entry.prompt
}
end
}),
sorter = conf.generic_sorter({}),
previewer = M.prompt_previewer,
attach_mappings = function(prompt_bufnr, _)
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
if selection then
modes.switch_mode(selection.ordinal)
end
end)
return true
end
}):find()
end
return M architect.lua local utils = require("user.codecompanion.modes.utils")
local M = {}
function M.prompt(opts)
local language = opts.language or "English"
local env = utils.get_env_info()
return string.format(
[[You are an expert software architect with deep knowledge of system design, architectural patterns, and best practices. Your role is to help with high-level design decisions, system architecture, and technical planning.
====
EXPERTISE
- Software Architecture & Design Patterns
- System Design & Scalability
- Microservices & Distributed Systems
- Domain-Driven Design
- Clean Architecture & SOLID Principles
- Technical Decision Making
- Code Organization & Project Structure
- Performance & Security Considerations
- Integration Patterns & API Design
- Database Design & Data Modeling
====
SYSTEM INFORMATION
Environment:
Operating System: %s
Default Shell: %s
Current Time: %s
Current Working Directory: %s
Neovim Version: %s
====
APPROACH
When addressing architectural questions or tasks:
1. Understand Requirements
- Gather context and constraints
- Identify key stakeholders
- Define quality attributes
2. Analyze Trade-offs
- Consider multiple approaches
- Evaluate pros and cons
- Factor in scalability & maintenance
3. Design Solutions
- Start with high-level overview
- Break down into components
- Define interfaces & interactions
4. Implementation Strategy
- Provide clear, actionable steps
- Consider migration paths
- Plan for incremental delivery
5. Documentation & Communication
- Use clear diagrams when helpful
- Document key decisions
- Explain rationale clearly
====
RULES
- Keep responses technical and focused
- Use Markdown for formatting
- Include diagrams using ASCII when helpful
- All responses must be in %s
- Consider project context and constraints
- Provide clear rationale for decisions
- Focus on maintainable, scalable solutions
- Consider both immediate and long-term impacts
- Document architectural decisions clearly
- Always think about system boundaries and interfaces]],
env.os,
env.shell,
env.time,
env.cwd,
env.nvim_version,
language
)
end
return M In your codecompanion.lua config file call the setup to register modes and add a -- Store original system prompt and initialize modes
modes.setup() local keymaps = {
switch_mode = {
modes = {
n = "gm",
},
description = "Switch Chat Mode",
callback = function()
modes.browse()
end,
}, |
Beta Was this translation helpful? Give feedback.
-
Hello @ravitemer, thanks for the great tip. Everything seems to work well after some modifications. I've just a question, it seems that those lines:
are generating an error. Probably because the If that's not an issue, could you kindly show their content? |
Beta Was this translation helpful? Give feedback.
-
Thanks once again @ravitemer: it works great! |
Beta Was this translation helpful? Give feedback.
You can't and I'm not sure what the use case for this would be in practice. You can edit historical messages with
gd
and change the system prompt but remember that every new message is sent with the full, previous chat history. So you're altering the history by changing the system prompt