How Magnitude's Provider Contract Enables Model Discovery and Binding

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, 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.

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.

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.

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.

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 Defines the Provider interface with discovery, binding, and classification methods
packages/providers/src/provider-client.ts Wraps a Provider in SDK-friendly APIs with additional error handling
packages/providers/src/registry.ts Provides ProviderRegistryService for runtime provider lookup and instantiation
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 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 for patterns on wrapping raw provider APIs.

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 →