Skip to content

Adding a new backend (VeniceAI) - Content-Type Header Issue #41

@plague-doctor

Description

@plague-doctor

Issue Description:
I am working on adding a new backend (VeniceAI), but I am encountering an issue when trying to use it. The error message 'Content-Type' must be 'application/json' indicates that the request is not being properly formatted as JSON. Despite ensuring that the Content-Type header is correctly added in requests.lua, the issue persists.

Steps to Reproduce:

  1. Attempt to use the VeniceAI backend in your project.
  2. Observe the error message 'Content-Type' must be 'application/json'.

Expected Behavior:
The request should be formatted as JSON with the Content-Type header set to application/json.

Actual Behavior:
The Content-Type header is set to application/json, but the issue persists.

Additional Information:

  • The code snippet provided is for Lua and is intended to be used with the Neovim environment.
  • The error message suggests that the issue might be related to how the headers are being handled or the request is being constructed.

Code Snippet for Reference:

local requests = require('cmp_ai.requests')

VeniceAI = requests:new(nil)
BASE_URL = 'https://api.venice.ai/api/v1/chat/completions'

-- Function to stringify a table
function stringify_table(tbl)
  local str = ""
  for k, v in pairs(tbl) do
    if type(k) == "string" then
      k = '"' .. k .. '"'
    end
    if type(v) == "table" then
      v = stringify_table(v)
    end
    if type(v) == "string" then
      v = '"' .. v .. '"'
    end
    str = str .. k .. " = " .. v .. ",\n"
  end
  return "{\n" .. str .. "}"
end

-- Function to initialize VeniceAI
function VeniceAI:new(o, params)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  self.params = vim.tbl_deep_extend('keep', params or {}, {
    model = 'deepseek-coder-v2-lite',
    temperature = 0.1,
    n = 1,
  })

  self.api_key = os.getenv('OPENAI_API_KEY')
  if not self.api_key then
    vim.schedule(function()
      vim.notify('OPENAI_API_KEY environment variable not set', vim.log.levels.ERROR)
    end)
    self.api_key = 'NO_KEY'
  end
  self.headers = {
    'Authorization: Bearer ' .. self.api_key,
  }
  return o
end

-- Function to complete code
function VeniceAI:complete(lines_before, lines_after, cb)
  if not self.api_key then
    vim.schedule(function()
      vim.notify('OPENAI_API_KEY environment variable not set', vim.log.levels.ERROR)
    end)
    return
  end
  local data = {
    messages = {
      {
        role = 'system',
        content = [=[You are a coding companion.
You need to suggest code for the language ]=] .. vim.o.filetype .. [=[
Given some code prefix and suffix for context, output code which should follow the prefix code.
You should only output valid code in the language ]=] .. vim.o.filetype .. [=[
. to clearly define a code block, including white space, we will wrap the code block
with tags.
Make sure to respect the white space and indentation rules of the language.
Do not output anything in plain language, make sure you only use the relevant programming language verbatim.
For example, consider the following request:
<begin_code_prefix>def print_hello():<end_code_prefix><begin_code_suffix>\n    return<end_code_suffix><begin_code_middle>
Your answer should be:

    print("Hello")<end_code_middle>
]=],
      },
      {
        role = 'user',
        content = '<begin_code_prefix>' ..
        lines_before ..
        '<end_code_prefix>' .. '<begin_code_suffix>' .. lines_after .. '<end_code_suffix><begin_code_middle>',
      },
    },
  }
  data = vim.tbl_deep_extend('keep', data, self.params)
  self:Get(BASE_URL, self.headers, data, function(answer)
    vim.notify(stringify_table(answer))   --  <---------------------- this is where the error is thrown.
    local new_data = {}
    if answer.choices then
      for _, response in ipairs(answer.choices) do
        local entry = response.message.content:gsub('<end_code_middle>', '')
        entry = entry:gsub('```', '')
        table.insert(new_data, entry)
      end
    end
    cb(new_data)
  end)
end

function VeniceAI:test()
  self:complete('def factorial(n)\n    if', '    return ans\n', function(data)
    dump(data)
  end)
end

return VeniceAI

Any idea what I am doing wrong?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions