# How Magnitude's Provider Contract Enables Model Discovery and Binding

> Magnitude's Provider contract streamlines AI integration with discoverModelProperties, bindModel, and classifyModelFamily methods for automatic model discovery and uniform inference binding.

- Repository: [Magnitude/magnitude](https://github.com/magnitudedev/magnitude)
- Tags: architecture
- Published: 2026-09-06

---

**Magnitude's Provider contract standardizes AI provider integration through three core methods—`discoverModelProperties`, `bindModel`, and `classifyModelFamily`—that enable automatic model discovery and uniform inference binding across any provider.**

The `Provider` interface in Magnitude's AI package creates a plug-and-play architecture for integrating large language models. Located in [`packages/ai/src/provider/contract.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/ai/src/provider/contract.ts), this contract defines how the platform discovers available models, binds them for inference, and classifies their families—allowing agents to treat OpenAI, Anthropic, and custom providers identically.

## The Provider Contract Architecture

Magnitude's provider abstraction sits at the center of the platform's AI capabilities. The contract is designed around **Effect**, a functional programming library for TypeScript that handles async operations, errors, and resources.

The interface requires three primary capabilities that together enable model discovery and binding:

- **`discoverModelProperties`** – Initiates asynchronous discovery of model capabilities
- **`bindModel`** – Creates a bound, ready-to-use model with normalized call options
- **`classifyModelFamily`** – Maps models to known families for UI organization

Each provider implementation returns Effect types, enabling composable, type-safe operations throughout the agent layer.

## Model Discovery with discoverModelProperties

Model discovery starts with the `discoverModelProperties` method defined at lines 26-28 of [`packages/ai/src/provider/contract.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/ai/src/provider/contract.ts).

This method accepts a discovery request containing a model ID and optional property hints, then returns an Effect that yields a `ModelDiscoveryOperationId`. The operation ID represents an in-flight discovery job that the agent layer can poll or await for detailed property information.

```typescript
import { Effect } from "effect"
import type { Provider } from "@magnitudedev/ai/provider/contract"

// Assume `provider` implements the Provider interface
const request = { modelId: "gpt-4", property: "tokenLimit" }

const discoveryEffect = provider.discoverModelProperties(request)

Effect.runPromise(discoveryEffect).then(operationId => {
  // The operationId can be used with the catalog service to fetch details
  console.log("Discovery started, operation ID:", operationId)
})

```

The discovery pattern decouples **initiation** from **retrieval**. Providers with slow or rate-limited metadata APIs can return immediately while background jobs populate the catalog service. The agent layer remains agnostic to these implementation details.

## Model Binding with bindModel

Once discovered, models must be bound before inference. The `bindModel` method (lines 36-40) transforms a provider-specific model ID into a **`BoundModel`** carrying universal `BaseCallOptions`.

```typescript
import type { Provider } from "@magnitudedev/ai/provider/contract"
import type { BaseCallOptions } from "@magnitudedev/ai/provider/call-options"

async function bindAndRun(provider: Provider, modelId: string) {
  const boundModelEffect = provider.bindModel(modelId, {
    defaults: { temperature: 0.7 }
  })

  const boundModel = await Effect.runPromise(boundModelEffect)

  // `boundModel` now contains a `call` method that accepts BaseCallOptions
  const result = await boundModel.call({ prompt: "Hello, world!" })
  console.log(result)
}

```

The binding step serves critical functions:

- **Normalizes call options** – Provider-specific parameters (temperature, stop tokens, top_p) are merged with defaults and validated
- **Encapsulates provider details** – Higher-level code interacts only with `BaseCallOptions`, not OpenAI's or Anthropic's native parameter shapes
- **Returns an Effect** – Setup failures (authentication, invalid model IDs) are handled through Effect's error channel

The `BoundModel` instance becomes a pure interface: any model from any provider exposes the same `call` method with the same options shape.

## Model Family Classification with classifyModelFamily

Not all providers expose family metadata (e.g., "GPT-4", "Claude 3", "Llama 3"). The `classifyModelFamily` method (lines 48-49) allows providers to implement heuristic classification when metadata is missing.

```typescript
import type { Provider } from "@magnitudedev/ai/provider/contract"
import { Option } from "effect"

function getFamily(provider: Provider, modelInfo: any) {
  const family = provider.classifyModelFamily(modelInfo)
  return Option.isSome(family) ? family.value : "unknown"
}

```

The method returns `Option<ModelFamilyId>`—`Option.some(family)` when classification succeeds, `Option.none` when it fails. This design:

- Prevents crashes on unclassifiable models
- Enables UI grouping even for providers with sparse metadata
- Allows platform-level fallbacks when provider classification returns `none`

## Provider Extensions and Optional Capabilities

Beyond the core discovery and binding flow, the Provider contract defines **extensions** that providers can opt into. Common extensions include:

- **`WebSearchExtension`** – Models that can perform live web searches
- **`UsageExtension`** – Models that return token usage statistics

Extensions are typed interfaces checked at runtime through the provider registry. A provider declares supported extensions, and agent code uses Effect's structured concurrency to conditionally enable features.

## How the Discovery and Binding Workflow Executes

The complete lifecycle from discovery to inference follows this sequence:

1. **Catalog Retrieval** – The agent queries `provider.catalog`, a `ModelCatalog<TModel>` exposing all available models with basic metadata
2. **Property Discovery** – For models needing detailed capabilities, the agent calls `discoverModelProperties(request)` and receives a `ModelDiscoveryOperationId`
3. **Model Binding** – At inference time, `bindModel(providerModelId, options?)` returns a `BoundModel<BaseCallOptions>` ready for uniform invocation
4. **Family Classification** – Optionally, `classifyModelFamily` assigns a `ModelFamilyId` for UI organization and feature gating

This workflow executes identically whether the underlying provider is OpenAI, Anthropic, a local Ollama instance, or a custom enterprise deployment.

## Key Implementation Files

| File | Role |
|------|------|
| [`packages/ai/src/provider/contract.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/ai/src/provider/contract.ts) | Defines the `Provider` interface with discovery, binding, and classification methods |
| [`packages/providers/src/provider-client.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/providers/src/provider-client.ts) | Wraps a `Provider` in SDK-friendly APIs with additional error handling |
| [`packages/providers/src/registry.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/providers/src/registry.ts) | Provides `ProviderRegistryService` for runtime provider lookup and instantiation |
| [`packages/ai/src/provider/call-options.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/ai/src/provider/call-options.ts) | Defines `BaseCallOptions` and related types for normalized inference parameters |

## Summary

- The **Provider contract** in [`packages/ai/src/provider/contract.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/ai/src/provider/contract.ts) standardizes how Magnitude integrates AI providers
- **`discoverModelProperties`** initiates async capability discovery, returning an operation ID for later retrieval
- **`bindModel`** transforms provider-specific models into uniform `BoundModel` instances with normalized `BaseCallOptions`
- **`classifyModelFamily`** enables UI grouping through optional heuristic family assignment
- The architecture enables **plug-and-play provider integration**: implement the contract, register with `ProviderRegistryService`, and the platform gains full discovery and binding capabilities automatically

## Frequently Asked Questions

### What makes Magnitude's Provider contract different from other AI SDK abstractions?

Magnitude's Provider contract uses **Effect** for all async operations, providing structured error handling, resource management, and composability that Promise-based SDKs lack. The contract explicitly separates **discovery** (async metadata retrieval) from **binding** (runtime model preparation), enabling providers with slow APIs to integrate without blocking agent operations.

### How does the binding process handle provider-specific parameters?

The `bindModel` method accepts optional defaults that are merged with provider-specific requirements during binding. The resulting `BoundModel` exposes only `BaseCallOptions`, hiding provider quirks—temperature might be `temperature` for OpenAI but `temp` for another provider, but callers always use `temperature`. The binding implementation handles translation internally.

### Can I add a custom provider without modifying Magnitude's source code?

Yes. Implement the `Provider` interface from `@magnitudedev/ai/provider/contract`, then register your implementation with `ProviderRegistryService` at runtime. The platform's discovery, binding, and classification workflows will operate automatically. Reference [`packages/providers/src/provider-client.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/providers/src/provider-client.ts) for patterns on wrapping raw provider APIs.