Connecting to other LLMs

An adapter is what connects Search2o to an LLM. Three adapters are bundled, and they already cover every endpoint that speaks the OpenAI, Anthropic or Gemini protocol. An LLM with an interface of its own needs an adapter class, written in Python and registered through the allowlist.

First, try a bundled adapter

Many LLMs are reachable with the adapters that are already there. A private deployment, a gateway, or a vendor that offers an OpenAI-compatible API needs no code at all: create an LLM profile under Profiles › LLM, pick the adapter that matches the protocol (openai, anthropic or gemini), and set the URL, the headers and the model. See LLM vendors.

Each bundled adapter says so itself. The GUI shows the adapter's description when a profile is created — the OpenAI one reads “Adapter for OpenAI ChatGPT responses API or any vendor that is compatible with it”.

When you need an adapter of your own

An adapter turns the request that Search2o builds — prompt, tools, model and limits — into the vendor's request body, and turns the vendor's response back into Search2o's form. Write one only when the vendor's protocol matches none of the three.

BaseLlmAdapter, for most APIs

search2o.llm.basellmadapter.BaseLlmAdapter does the assembly and the control flow. It builds the request in a fixed order, merges the profile's additionalParams over the result, and reads the response in a fixed order. You supply only the vendor-specific pieces, as these methods:

MethodWhat it does
namefrom LlmAdapterThe adapter's name, as it appears in a profile's adapter field.
descriptionfrom LlmAdapterOne line, shown in the GUI when a profile is created.
set_modelPut the profile's model into the request parameters.
set_max_tokensPut the token ceiling into the request parameters.
set_toolsExpress the agent's tools in the vendor's schema.
set_system_promptPlace the system prompt where the vendor expects it, in the parameters or as a message.
set_messages_user_entryAppend one user message.
set_messages_assistant_response_content_outputAppend an earlier assistant answer.
set_messages_assistant_response_tool_callsAppend the assistant's earlier tool calls.
set_messages_tool_resultsAppend the results of those tool calls.
set_response_flagsRead success or failure from the response.
set_token_countsRead the token counts, which the cost report is computed from.
set_assistant_vendorRead the answer: either tool calls or content. A response with neither is an error.

BaseLlmAdapter walks the prompt for you and calls the four message methods in the order the conversation happened, so an adapter never has to sort the history itself. get_error has a working implementation that reads the response's error field; override it when the vendor reports errors differently.

LlmAdapter, for anything else

search2o.llm.llmadapter.LlmAdapter is the bare interface, for a protocol so different that the assembly above does not help. Five methods, and nothing is done for you: name, description, process_request (an LlmRequestModel in, the request body out), process_response (the response in, an LlmResponseModel out), and get_error.

The bundled adapters in search2o.llmopenaiadapter.py, anthropicadapter.py and geminiadapter.py — are the reference implementations, and each is a short file.

Registering it

  1. The class belongs in the Python environment that the agent server runs in.
  2. Add the class to the allowlist as mypackage.myadapter.MyAdapter and save.
  3. The agent server instantiates every allowlisted subclass of LlmAdapter when the server loads the allowlist, and lists those adapters under Adapters when a new LLM profile is created. An adapter whose constructor fails is written to the server's log.

The class needs a constructor that takes no arguments. Reports group spend under the profile's vendor field, so set that field to the vendor's name, whatever the adapter is called.