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 capabilitiesbindModel– Creates a bound, ready-to-use model with normalized call optionsclassifyModelFamily– 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 searchesUsageExtension– 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:
- Catalog Retrieval – The agent queries
provider.catalog, aModelCatalog<TModel>exposing all available models with basic metadata - Property Discovery – For models needing detailed capabilities, the agent calls
discoverModelProperties(request)and receives aModelDiscoveryOperationId - Model Binding – At inference time,
bindModel(providerModelId, options?)returns aBoundModel<BaseCallOptions>ready for uniform invocation - Family Classification – Optionally,
classifyModelFamilyassigns aModelFamilyIdfor 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.tsstandardizes how Magnitude integrates AI providers discoverModelPropertiesinitiates async capability discovery, returning an operation ID for later retrievalbindModeltransforms provider-specific models into uniformBoundModelinstances with normalizedBaseCallOptionsclassifyModelFamilyenables 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →