Configuration Data Structures in Continue: A Deep Dive into `core/config/types.ts`

Continue uses a four-layer hierarchy of TypeScript interfaces—from SerializedContinueConfig for raw JSON parsing to ContinueConfig for runtime execution—to manage IDE settings in continue.json files.

Continue, the open-source AI coding assistant, organizes its settings through strictly-typed configuration data structures defined in core/config/types.ts. These interfaces transform user-edited continue.json files into runtime-ready objects that power LLM interactions, context providers, and embeddings across VS Code and JetBrains IDEs.

The Four-Layer Configuration Hierarchy

The codebase maintains distinct interfaces for each stage of the configuration lifecycle, ensuring type safety from file system to execution.

SerializedContinueConfig represents the direct mapping of the JSON file a user edits. Located at core/config/types.ts#L1150, this interface defines all fields as optional to accommodate partial configurations while preserving the exact shape supplied by the user.

Config serves as a user-friendly wrapper that exposes the most common options—including models, slash commands, and context providers—at core/config/types.ts#L1175. This simplified view abstracts away implementation details while maintaining full TypeScript intellisense.

ContinueConfig constitutes the concrete configuration actually used by the inference engine. Defined at core/config/types.ts#L1220, this structure contains all optional fields filled with defaults and instantiated helper objects such as ILLM instances for model communication.

BrowserSerializedContinueConfig handles UI-specific serialization at core/config/types.ts#L1245. This shape mirrors the raw config but drops runtime-only objects before transmission to the web-based interface.

ConfigMergeType and ContinueRcJson control merge semantics at core/config/types.ts#L1265, determining whether a continue.rc.json file merges with or overwrites the base configuration.

Key Configuration Sub-Structures

Nested within the main hierarchy, specialized interfaces define specific functional areas:

  • ModelDescription – Configures LLM connections with title, provider, model, and optional apiKey fields for provider authentication.
  • ContextProviderDescription – Defines data sources such as codebase, gitlab-mr, and search with metadata including title, description, and type parameters.
  • EmbeddingsProviderDescription – Specifies vector-store configurations for semantic code search and retrieval.
  • RerankerDescription – Configures ranking algorithms that prioritize relevant context chunks.
  • ExperimentalConfig – Houses optional features including custom quick actions, text-to-speech (TTS), and Chromium crawling capabilities.

How Configuration Is Loaded and Resolved

The transformation from raw JSON to executable configuration occurs in extensions/cli/src/configLoader.ts. This module orchestrates the resolution pipeline:

  1. Read the base continue.json file into a Config object
  2. Locate and parse the optional continue.rc.json file
  3. Merge configurations according to the ConfigMergeType behavior ("merge" vs "overwrite")
  4. Resolve the final ContinueConfig by instantiating LLM classes, embeddings providers, and other service objects
// Conceptual flow based on extensions/cli/src/configLoader.ts
import { Config, ContinueConfig } from "../../core/config/types";

async function loadContinueConfig(): Promise<ContinueConfig> {
  const raw: Config = await readUserConfigFile();          // reads continue.json
  const rc: Partial<Config> = await readRcFile();          // optional .rc merge
  const merged = mergeConfig(raw, rc);                     // respects ConfigMergeType
  return resolveRuntimeConfig(merged);                     // creates ILLM instances, etc.
}

The resolveRuntimeConfig helper performs the critical transformation from static descriptions to live service instances, enabling the rest of the codebase to interact with configured providers through uniform interfaces.

Practical Configuration Examples

Defining a Simple continue.json

All fields map directly to the SerializedContinueConfig interface:

{
  "models": [
    {
      "title": "OpenAI GPT-4",
      "provider": "openai",
      "model": "gpt-4",
      "apiKey": "YOUR_API_KEY"
    }
  ],
  "slashCommands": [
    { "name": "explain", "description": "Explain selected code" }
  ],
  "contextProviders": [
    { "name": "codebase", "params": {} }
  ]
}

Accessing Resolved Configuration in a Plugin

Plugins receive the fully-resolved ContinueConfig through the SDK:

import type { ContinueConfig } from "core/config/types";

export function myPlugin(sdk: ContinueSDK) {
  const cfg: ContinueConfig = sdk.config;   // fully-resolved config
  console.log("LLM model:", cfg.models[0].model);
  console.log("Embedding provider:", cfg.embeddingsProvider.provider);
}

Extending with a Custom LLM

The Config interface supports mixing standard ModelDescription objects with CustomLLM implementations:

import type { CustomLLM } from "core/config/types";

const myCustomLLM: CustomLLM = {
  options: { model: "my-llm", streamChat: async* () => {} },
  streamChat: async function* (messages, signal, opts, fetch) {
    // custom call logic …
    yield "partial answer";
  }
};

export const config: Config = {
  models: [myCustomLLM],
  // …other fields…
};

Summary

  • Configuration data structures in continuedev/continue follow a strict hierarchy from SerializedContinueConfig (raw JSON) to ContinueConfig (runtime objects).
  • Core definitions live in core/config/types.ts, with line-specific interfaces at L1150, L1175, L1220, and L1245.
  • Resolution logic resides in extensions/cli/src/configLoader.ts, handling deep-merging of .rc files and instantiation of service objects.
  • UI state management occurs in gui/src/redux/slices/configSlice.ts, bridging the gap between runtime configuration and the web interface.
  • Merge behavior is controlled by ConfigMergeType, allowing granular control over configuration inheritance.

Frequently Asked Questions

What is the difference between SerializedContinueConfig and ContinueConfig?

SerializedContinueConfig represents the raw, user-edited JSON with all fields optional, while ContinueConfig is the fully-resolved runtime version with defaults applied and actual class instances (like ILLM objects) instantiated. The transformation occurs in extensions/cli/src/configLoader.ts through the resolveRuntimeConfig function.

How does Continue handle merging of continue.rc.json files?

Continue reads the base continue.json and optional continue.rc.json, then applies the ConfigMergeType behavior defined in core/config/types.ts#L1265. If set to "merge", configurations are deeply combined; if "overwrite", the RC file replaces the base configuration entirely.

Where are the configuration TypeScript interfaces defined?

All configuration interfaces—including SerializedContinueConfig, Config, ContinueConfig, and BrowserSerializedContinueConfig—are centrally defined in core/config/types.ts. This single source of truth ensures consistency across the CLI, GUI, and extension layers.

Can I mix standard ModelDescription objects with custom LLM implementations?

Yes. The Config interface explicitly permits mixing native ModelDescription objects with CustomLLM implementations in the models array. This allows users to combine standard providers (OpenAI, Anthropic) with custom streaming implementations within the same configuration file.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →