Skip to main content

Editors & Clients

Neovim with Verdictan

Point a Neovim AI plugin at your Verdictan gateway, and the requests it sends for the model you choose go through your policies. This page shows CodeCompanion and gp.nvim. Both send OpenAI-style Chat Completions requests. Get chat working first, then check each other feature you use.

Before you start​

  • A gateway on http://127.0.0.1:41002 with at least one provider target. See Gateway Setup for IDEs.
  • A client API token. See API Tokens for IDEs.
  • One model ID from the gateway's authenticated GET /v1/models response.
  • CodeCompanion or gp.nvim installed in Neovim.

Both plugins read the token from the environment that starts Neovim. Export it there:

export VERDICTAN_CLIENT_TOKEN="<client-api-token>"

Configure CodeCompanion​

  1. Add a verdictan HTTP adapter and assign it to chat and inline edits. Keep your other plugin settings:

    init.lua
    require("codecompanion").setup({
      adapters = {
        http = {
          verdictan = function()
            return require("codecompanion.adapters").extend("openai_compatible", {
              env = {
                url = "http://127.0.0.1:41002",
                chat_url = "/v1/chat/completions",
                api_key = "VERDICTAN_CLIENT_TOKEN",
              },
              schema = {
                model = {
                  default = "your-model-id",
                },
              },
            })
          end,
        },
      },
      interactions = {
        chat = { adapter = "verdictan" },
        inline = { adapter = "verdictan" },
      },
    })
  2. Replace your-model-id with an id from GET /v1/models.

  3. Start Neovim from the shell that exports VERDICTAN_CLIENT_TOKEN.

The adapter sends requests to url plus chat_url, with Authorization: Bearer and the token. api_key holds the name of the environment variable, not the token. The adapter also reads url plus /v1/models to fill its model picker. Without schema.model.default, it picks the last model in that list, so set the default.

Only the interactions you assign to verdictan use the gateway. An inline prompt with adapter=<name> overrides the assignment for that prompt. The cmd interaction and background tasks have their own settings: interactions.cmd.adapter and interactions.background.adapter. ACP adapters connect to agents, and preset adapters such as copilot call their own services. None of them pass through Verdictan.

CodeCompanion ships openai_compatible as an example adapter that it does not officially support. See CodeCompanion HTTP adapters for the other env value types, such as cmd: and file:.

Configure gp.nvim​

  1. Add a verdictan provider and an agent that uses it. Keep your other settings:

    init.lua
    require("gp").setup({
      providers = {
        verdictan = {
          endpoint = "http://127.0.0.1:41002/v1/chat/completions",
          secret = os.getenv("VERDICTAN_CLIENT_TOKEN"),
        },
      },
      agents = {
        {
          name = "Verdictan",
          provider = "verdictan",
          chat = true,
          command = true,
          model = { model = "your-model-id" },
          system_prompt = "You are a careful coding assistant.",
        },
      },
    })
  2. Replace your-model-id with an id from GET /v1/models.

  3. Start Neovim from the shell that exports VERDICTAN_CLIENT_TOKEN, then run :GpAgent Verdictan.

endpoint is the complete Chat Completions URL, not a base URL. For a provider name that gp.nvim does not know, such as verdictan, it sends the token as Authorization: Bearer. gp.nvim drops an agent that has no model or system_prompt, and drops a provider that has no endpoint.

Only agents with provider = "verdictan" use the gateway. Other agents, and the image agents you pick with :GpImageAgent, keep their own providers. See the gp.nvim README for agent and command options.

Verify​

  1. Check the token and the model list:

    curl -fsS \
      -H "Authorization: Bearer $VERDICTAN_CLIENT_TOKEN" \
      http://127.0.0.1:41002/v1/models
  2. Send Reply with Hello. from a chat: :CodeCompanionChat in CodeCompanion, or :GpChatNew in gp.nvim. Check that the reply shows.

  3. In a second shell, read the recent events:

    verdictan events tail --since 10m --json

    The newest event in the events array has a timestamp from the moment you sent the chat. Event delivery can take a few seconds, so run the command again if the event is not there yet.

  4. Open a scratch file and ask for a small edit: :CodeCompanion <prompt> in CodeCompanion, or :GpRewrite in gp.nvim. Run the same command again, and check that this request also has an event.

An event proves that a request went through the gateway. Count a feature as governed only after you see its event.

Other Neovim plugins​

Another plugin can use the gateway if you can set all of these:

  • The gateway's base URL http://127.0.0.1:41002/v1, or the complete URL http://127.0.0.1:41002/v1/chat/completions
  • A token that the plugin sends as Authorization: Bearer <token>
  • A model ID from GET /v1/models

The gateway reads the client token only from the Authorization header. A plugin that sends its key in another header, such as x-api-key, gets 401. Check the plugin's own documentation for the option names, and confirm each feature with verdictan events tail.

Troubleshooting​

SymptomCauseFix
Connection refusedThe gateway is not running on port 41002Start it, and check /healthz with curl.
401 with missing_api_keyNeovim did not inherit VERDICTAN_CLIENT_TOKEN, or the value is not a vdt_ tokenStart Neovim from a shell that exports the variable. Don't use the gateway runtime token.
401 with invalid_api_token or tokens.expiredThe token is revoked or expiredCheck the token on the Console API Tokens page.
422 with no_matching_providerThe model ID does not match anything the gateway servesUse an id from GET /v1/models.
404 from the gatewayThe URL has the wrong shape, for example a base URL in gp.nvim's endpointUse the complete Chat Completions URL in gp.nvim, and url plus chat_url in CodeCompanion.
Chat produces events but inline edits do notThe inline interaction uses another adapter or agentSet interactions.inline.adapter in CodeCompanion, or select the Verdictan agent in gp.nvim.
A reply but no eventThe plugin used another adapter, agent, or providerCheck which one is active. Then see IDE Integration Troubleshooting.

Next steps​