Skip to content

Provider Interface ​

Adding a new LLM provider to GodeX means declaring a ProviderSpec with capabilities, response/stream accessors, optional hooks, and wiring up an HTTP client. The bridge kernel handles routing, session management, compatibility planning, and SSE encoding — providers only deal with protocol differences and HTTP calls.

Core Interfaces ​

ProviderCapabilities ​

Capabilities are declared as immutable sets and flags. They tell the bridge kernel what the provider supports so it can plan compatibility decisions.

ts
const capabilities: ProviderCapabilities = {
  parameters: {
    supported: new Set([
      "stream", "temperature", "top_p", "max_output_tokens",
      "reasoning", "safety_identifier", "user",
      "text.format",
    ]),
  },
  tools: {
    supported: new Set(["function"]),
    degraded: new Map([["local_shell", "function"]]),
    maxTools: 128,
  },
  toolChoice: {
    supported: new Set(["auto", "none", "required", "function"]),
  },
  responseFormats: {
    supported: new Set(["text", "json_object"]),
  },
  reasoning: { effort: "native" },
  streaming: { usage: true },
};

Capability Fields ​

FieldTypeDescription
parameters.supportedSet<string>Request parameters the provider accepts
tools.supportedSet<string>Tool types the provider can handle
tools.degradedMap<string, string>Tool types that degrade to another type
tools.maxToolsnumberMaximum number of tools per request
toolChoice.supportedSet<string>tool_choice modes the provider supports
responseFormats.supportedSet<string>Response format types (text, json_object, json_schema)
reasoning.effort"none" | "boolean" | "native"How the provider handles reasoning effort
streaming.usagebooleanWhether the provider returns usage in stream chunks

Response Accessors ​

The spec declares typed accessors so the bridge can read provider responses without knowing the concrete type:

ts
interface ChatCompletionResponseAccessor<TResponse> {
  firstChoice(response: TResponse): unknown | undefined;
  finishReason(response: TResponse): string | undefined;
  outputText(response: TResponse): string;
  usage(response: TResponse): ResponseUsage | null;
}

Stream Accessors ​

ts
interface ChatCompletionStreamAccessor<TChunk> {
  deltas(chunk: TChunk): ProviderSpecStreamDelta[];
}

Each stream chunk may produce zero or more typed deltas (text, reasoning, tool calls, usage, finish reason).

Provider Hooks ​

Hooks allow provider-specific behavior without polluting the bridge kernel:

HookWhen CalledPurpose
patchRequestAfter bridge builds the Chat Completions requestTransform the request for provider-specific quirks
normalizeResponseAfter receiving a sync responseNormalize provider response shape
normalizeChunkAfter receiving a stream chunkNormalize provider chunk shape

Registration ​

Register a provider definition in src/providers/builtin.ts:

ts
const MY_PROVIDER_DEFINITION = createProviderDefinition(
  "myprovider",
  createMyProviderEdge,
);

export const BUILTIN_PROVIDER_DEFINITIONS = [
  DEEPSEEK_PROVIDER_DEFINITION,
  ZHIPU_PROVIDER_DEFINITION,
  MINIMAX_PROVIDER_DEFINITION,
  MY_PROVIDER_DEFINITION,
] as const satisfies readonly ProviderDefinition[];

The Registrar iterates all configured providers in godex.yaml, matches by the spec field to the factory, and builds ProviderEdge instances. Providers without a matching factory are listed as unsupported.

DeepSeek Reference