Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions lua/gp/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,16 @@ local config = {
-- system prompt (use this to specify the persona/role of the AI)
system_prompt = require("gp.defaults").chat_system_prompt,
},
{
provider = "anthropic",
name = "ChatClaude-Sonnet-4-Thinking",
chat = true,
command = false,
-- string with model name or table with model name and parameters
model = { model = "claude-sonnet-4-20250514", thinking_budget = 1024 },
-- system prompt (use this to specify the persona/role of the AI)
system_prompt = require("gp.defaults").chat_system_prompt,
},
{
provider = "anthropic",
name = "ChatClaude-3-5-Haiku",
Expand Down
31 changes: 24 additions & 7 deletions lua/gp/dispatcher.lua
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ D.prepare_payload = function(messages, model, provider)
temperature = model.temperature and math.max(0, math.min(2, model.temperature)) or nil,
top_p = model.top_p and math.max(0, math.min(1, model.top_p)) or nil,
}

if model.thinking_budget ~= nil then
payload.thinking = {
type = "enabled",
budget_tokens = model.thinking_budget
}
end

return payload
end

Expand Down Expand Up @@ -230,6 +238,7 @@ local query = function(buf, provider, payload, handler, on_exit, callback)

local out_reader = function()
local buffer = ""
local anthropic_thinking = false -- local state for Anthropic thinking blocks

---@param lines_chunk string
local function process_lines(lines_chunk)
Expand All @@ -252,14 +261,24 @@ local query = function(buf, provider, payload, handler, on_exit, callback)
end
end

if qt.provider == "anthropic" and line:match('"text":') then
if qt.provider == "anthropic" and (line:match('"text":') or line:match('"thinking"')) then
if line:match("content_block_start") or line:match("content_block_delta") then
line = vim.json.decode(line)
if line.delta and line.delta.text then
content = line.delta.text
if line.content_block then
if line.content_block.type == "thinking" then
anthropic_thinking = true
content = "<think>"
elseif line.content_block.type == "text" and anthropic_thinking then
anthropic_thinking = false
content = "</think>\n\n"
end
end
if line.content_block and line.content_block.text then
content = line.content_block.text
if line.delta then
if line.delta.type == "thinking_delta" then
content = line.delta.thinking or ""
elseif line.delta.type == "text_delta" then
content = line.delta.text or ""
end
end
end
end
Expand Down Expand Up @@ -382,8 +401,6 @@ local query = function(buf, provider, payload, handler, on_exit, callback)
"x-api-key: " .. bearer,
"-H",
"anthropic-version: 2023-06-01",
"-H",
"anthropic-beta: messages-2023-12-15",
}
elseif provider == "azure" then
headers = {
Expand Down
12 changes: 9 additions & 3 deletions lua/gp/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1159,11 +1159,17 @@ M.chat_respond = function(params)
local topic_buf = vim.api.nvim_create_buf(false, true)
local topic_handler = M.dispatcher.create_handler(topic_buf, nil, 0, false, "", false)

-- call the model
-- call the model (remove thinking_budget for Anthropic topic generation)
local topic_model = headers.model or agent.model
local provider = headers.provider or agent.provider
if provider == "anthropic" and topic_model.thinking_budget then
topic_model = vim.deepcopy(topic_model)
topic_model.thinking_budget = nil
end
M.dispatcher.query(
nil,
headers.provider or agent.provider,
M.dispatcher.prepare_payload(messages, headers.model or agent.model, headers.provider or agent.provider),
provider,
M.dispatcher.prepare_payload(messages, topic_model, provider),
topic_handler,
vim.schedule_wrap(function()
-- get topic from invisible buffer
Expand Down