summaryrefslogtreecommitdiff
path: root/lua/99/request/init.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/99/request/init.lua')
-rw-r--r--lua/99/request/init.lua117
1 files changed, 31 insertions, 86 deletions
diff --git a/lua/99/request/init.lua b/lua/99/request/init.lua
index dd69b6c..a758912 100644
--- a/lua/99/request/init.lua
+++ b/lua/99/request/init.lua
@@ -1,15 +1,4 @@
local Logger = require("99.logger.logger")
-local editor = require("99.editor")
-local geo = require("99.geo")
-local Point = geo.Point
-
---- TODO: some people change their current working directory as they open new
---- directories. if this is still the case in neovim land, then we will need
---- to make the _99_state have the project directory.
---- @return string
-local function random_file()
- return string.format("%s/tmp/99-%d", vim.uv.cwd(), math.floor(math.random() * 10000))
-end
--- no, i am not going to use a uuid, in case of collision, call the police
--- @return string
@@ -17,117 +6,76 @@ local function get_id()
return tostring(math.floor(math.random() * 100000000))
end
+--- @param opts _99.Request.Opts
+local function validate_opts(opts)
+ assert(opts.model, "you must provide a model for hange requests to work")
+ assert(type(opts.on_complete) == "function", "on_complete must be provided")
+ assert(opts.context, "you must provide context")
+end
+
--- @alias _99.Request.State "ready" | "calling-model" | "parsing-result" | "updating-file"
--- @class _99.Request.Opts
--- @field model string
---- @field md_files string[]
+--- @field on_complete fun(req: _99.Request, success: boolean, res: string): nil
+--- @field context _99.Context
--- @class _99.Request
---- @field query string
---- @field tmp_name string
---- @field state _99.Request.State
---- @field buffer number
---- @field model string
+--- @field config _99.Request.Opts
--- @field id string
---- @field mark string
---- @field scopes Scope
---- @field system_prompt string
+--- @field state _99.Request.State
+--- @field _content string[]
local Request = {}
Request.__index = Request
--- @param opts _99.Request.Opts
function Request.new(opts)
- assert(opts.model, "you must provide a model for hange requests to work")
-
- local ts = editor.treesitter
- local cursor = Point:from_cursor()
- local scopes = ts.function_scopes(cursor)
- local buffer = vim.api.nvim_get_current_buf()
-
+ validate_opts(opts)
return setmetatable({
- cursor = cursor,
- scopes = scopes,
- buffer = buffer,
- model = opts.model,
- tmp_name = random_file(),
+ config = opts,
id = get_id(),
state = "ready",
- mark = "",
+ _content = {},
}, Request)
end
-function Request:has_scopes()
- return self.scopes ~= nil and #self.scopes.range > 0
-end
-
-function Request:get_inner_scope()
- assert(self:has_scopes(), "you cannot get inner scope if you dont have scopes")
- return self.scopes.range[#self.scopes.range]
-end
-
---- @param prompt string
-function Request:set_system_prompt(prompt)
- self.system_prompt = prompt
-end
-
function Request:_retrieve_response()
+ local tmp = self.config.context.tmp_file
local success, result = pcall(function()
- return vim.fn.readfile(self.tmp_name)
+ return vim.fn.readfile(tmp)
end)
if not success then
- Logger:error("retrieve_results: failed to read file", "tmp_name", self.tmp_name, "error", result)
+ Logger:error("retrieve_results: failed to read file", "tmp_name", tmp, "error", result)
return false, ""
end
return true, table.concat(result, "\n")
end
---- @param res string
-function Request:_update_file_with_changes(res)
- local mark_pos = vim.api.nvim_buf_get_mark(self.buffer, self.mark)
- local mark_point = Point:new(mark_pos[1], mark_pos[2] + 1)
-
- local ts = editor.treesitter
- local scopes = ts.function_scopes(mark_point, self.buffer)
- print("update_file_with_changes buffer", self.buffer)
-
- if not scopes or not scopes:has_scope() then
- Logger:error("update_file_with_changes: unable to find function at mark location")
- error("update_file_with_changes: funable to find function at mark location")
- return
- end
-
- local range = scopes.range[#scopes.range]
-
- local function_start_row, _ = range.start:to_vim()
- local function_end_row, _ = range.end_:to_vim()
-
- local lines = vim.split(res, "\n")
- vim.api.nvim_buf_set_lines(self.buffer, function_start_row, function_end_row + 1, false, lines)
-
- local stuff = {
- buffer = self.buffer,
- f_start = function_start_row,
- f_end = function_end_row,
- res = res
- }
- print("setting lines in buffer", vim.inspect(stuff))
+--- @param content string
+--- @return self
+function Request:add_prompt_content(content)
+ table.insert(self._content, content)
+ return self
end
function Request:start()
- local query = self.system_prompt
+ local query = table.concat(self._content, "\n")
Logger:debug("99#make_query", "id", self.id, "query", query)
vim.system({ "opencode", "run", "-m", "anthropic/claude-sonnet-4-5", query }, {
text = true,
stdout = vim.schedule_wrap(function(err, data)
Logger:debug("STDOUT#data", "id", self.id, "data", data)
- Logger:debug("STDOUT#error", "id", self.id, "err", err)
+ if err and err ~= "" then
+ Logger:debug("STDOUT#error", "id", self.id, "err", err)
+ end
end),
stderr = vim.schedule_wrap(function(err, data)
Logger:debug("STDERR#data", "id", self.id, "data", data)
- Logger:debug("STDERR#error", "id", self.id, "err", err)
+ if err and err ~= "" then
+ Logger:debug("STDERR#error", "id", self.id, "err", err)
+ end
end),
}, function(obj)
if obj.code ~= 0 then
@@ -136,10 +84,7 @@ function Request:start()
end
vim.schedule(function()
local ok, res = self:_retrieve_response()
- if ok then
- self:_update_file_with_changes(res)
- end
- print("finished")
+ self.config.on_complete(self, ok, res)
end)
end)
end