# How ModLens Uses extraBody Configuration to Pass Provider-Specific Options

> Discover how ModLens extraBody configuration passes provider-specific options to OpenAI, Gemini, and Anthropic. Deep-merge JSON payloads securely without altering core code.

- Repository: [liustack/modlens](https://github.com/liustack/modlens)
- Tags: deep-dive
- Published: 2026-08-25

---

**ModLens exposes an `extraBody` configuration that deep-merges user-provided JSON into API request payloads while protecting reserved fields, enabling vendor-specific options for OpenAI, Gemini, and Anthropic without modifying core code.**

The `extraBody` configuration in ModLens provides a flexible mechanism for injecting provider-specific parameters into vision API requests. This system allows users to leverage proprietary features and future API options without waiting for explicit SDK support. By treating provider payloads as extensible JSON objects, ModLens maintains a stable core contract while offering unlimited customization for advanced use cases.

## Parsing and Validating extraBody Input

When users supply parameters through the `--extra-body` CLI flag or the `<provider>.extraBody` configuration entry, the system must ensure data integrity before merging.

### Command-Line and Configuration File Parsing

The string supplied via CLI or read from `~/.modlens/config.json` is processed by `parseExtraBody` in [`src/util/extraBody.ts`](https://github.com/liustack/modlens/blob/main/src/util/extraBody.ts). This function enforces strict JSON validation, throwing clear error messages if the input cannot be parsed as a valid JSON object. This ensures type safety before any merging occurs.

### Deep Merging Strategy

The `mergeExtraBody` function (also in [`src/util/extraBody.ts`](https://github.com/liustack/modlens/blob/main/src/util/extraBody.ts)) handles the integration of user-defined parameters into the base request payload. The implementation follows specific structural rules:

- **Objects are merged recursively**, allowing users to add or override nested configuration keys without replacing entire blocks.
- **Arrays and scalar values are replaced outright**, ensuring that user intent for specific fields like `temperature` or `max_tokens` takes precedence.

## Protecting the Core Contract with Reserved Fields

ModLens maintains a strict contract with vision providers regarding essential request components. The `mergeExtraBody` function accepts a `reserved` array parameter that guards critical fields including `model`, `messages`, `stream`, and the JSON schema validation structure. If `extraBody` contains any reserved keys, the function immediately throws an error, preventing accidental corruption of image data, prompts, or response formatting requirements.

## Provider-Specific Implementation Patterns

Each provider implementation in ModLens utilizes `extraBody` to support vendor-exclusive features while maintaining consistent merging logic.

### OpenAI-Compatible Providers

In [`src/providers/openaiCompat.ts`](https://github.com/liustack/modlens/blob/main/src/providers/openaiCompat.ts), the base payload construction includes the model identifier, message array with image data, and optional response formatting. The `mergeExtraBody` call combines this foundation with user settings:

```typescript
const payload = mergeExtraBody(
  {
    model,
    ...(derivedSchemaSent(options.settings) ? { response_format: visionResponseFormat() } : {}),
    messages: [/* image & prompt */],
  },
  options.settings?.extraBody,
  ['model', 'messages', 'stream'],
  'openai'
);

```

This pattern allows users to pass standard OpenAI parameters like `max_tokens`, `temperature`, or `top_p` through the `extraBody` configuration without code changes.

### Google Gemini API

For Gemini-specific capabilities, [`src/providers/geminiApi.ts`](https://github.com/liustack/modlens/blob/main/src/providers/geminiApi.ts) utilizes `extraBody` to inject `generationConfig` parameters including the experimental `thinkingConfig` object. Users can enable advanced reasoning features by configuring:

```json
{
  "providers": {
    "gemini-api": {
      "extraBody": {
        "generationConfig": {
          "thinkingConfig": { "thinkingLevel": "HIGH" }
        }
      }
    }
  }
}

```

### Anthropic Claude Integration

The [`src/providers/anthropicApi.ts`](https://github.com/liustack/modlens/blob/main/src/providers/anthropicApi.ts) implementation supports Anthropic-specific fields such as custom tool definitions, metadata tags, and streaming toggles. Through `extraBody`, users can access beta features and enterprise parameters that extend beyond ModLens's standard abstraction layer.

## Runtime Execution Flow

The complete data flow from user input to API transmission follows this pipeline:

1. **CLI Parsing**: The `--extra-body` flag is captured in `options.extraBody` by the command-line parser.
2. **Base Construction**: [`src/analyzer.ts`](https://github.com/liustack/modlens/blob/main/src/analyzer.ts) assembles the provider-specific request foundation including authentication headers and endpoint URLs.
3. **Merging**: The analyzer invokes `mergeExtraBody` with the base payload, user configuration, reserved field list, and provider name for contextual error reporting.
4. **Transmission**: The merged payload is serialized and transmitted via `apiFetch` to the provider's endpoint.

## Configuration Methods

### Command-Line Interface

For ad-hoc parameter adjustment, use the `--extra-body` flag with a JSON string:

```bash
modlens -i img.png -p openai --extra-body '{"max_tokens":4096,"temperature":0.2}'

```

This overrides any `extraBody` values defined in configuration files for that specific execution.

### Persistent Configuration

For repeated use, define `extraBody` within provider blocks in `~/.modlens/config.json` as processed by [`src/config.ts`](https://github.com/liustack/modlens/blob/main/src/config.ts):

```json
{
  "providers": {
    "openai": {
      "apiKey": "sk-...",
      "extraBody": {
        "max_tokens": 4096,
        "temperature": 0.2
      }
    }
  }
}

```

## Summary

- The `extraBody` configuration in [`src/util/extraBody.ts`](https://github.com/liustack/modlens/blob/main/src/util/extraBody.ts) enables deep-merging of user JSON into provider requests while protecting reserved fields like `model` and `messages`.
- Users can inject vendor-specific parameters for OpenAI, Gemini, and Anthropic without modifying ModLens source code.
- Reserved field validation prevents corruption of essential request components including image data, prompts, and response schemas.
- Configuration is supported via both the `--extra-body` CLI flag and persistent JSON configuration files processed by [`src/config.ts`](https://github.com/liustack/modlens/blob/main/src/config.ts).

## Frequently Asked Questions

### What happens if I try to override a reserved field in extraBody?

Attempting to include reserved keys such as `model`, `messages`, or `stream` in your `extraBody` JSON triggers an immediate error from `mergeExtraBody` in [`src/util/extraBody.ts`](https://github.com/liustack/modlens/blob/main/src/util/extraBody.ts). This protection ensures that ModLens maintains control over critical request components required for proper image analysis and response parsing, preventing API failures.

### Can I use extraBody to enable beta features from vision providers?

Yes. The `extraBody` configuration passes through any valid JSON, allowing immediate access to beta parameters like Gemini's `thinkingConfig` or Anthropic's extended thinking modes without waiting for ModLens updates. Simply structure the JSON according to the provider's API documentation and include it in your configuration or CLI command.

### Does extraBody support nested configuration objects?

Yes. The `mergeExtraBody` function implements deep merging for objects, meaning you can partially override nested structures like `generationConfig.thinkingConfig` without replacing the entire `generationConfig` block. However, arrays and primitive values are replaced entirely rather than merged, ensuring predictable behavior for fields like `stop_sequences`.

### How do I troubleshoot invalid extraBody errors?

If `parseExtraBody` throws a validation error, verify that your JSON is properly formatted and represents a single object (not an array or primitive). For CLI usage, ensure the JSON string is properly quoted for your shell environment. The error messages from [`src/util/extraBody.ts`](https://github.com/liustack/modlens/blob/main/src/util/extraBody.ts) specify the exact parsing failure and provider context, making debugging straightforward.