How `packages/ai`, `packages/providers`, and `packages/sdk` Work Together in Magnitude's Provider System

packages/ai defines the core AI contract, packages/providers implements concrete AI services, and packages/sdk exposes the unified client API that bridges UI applications to underlying models.

Magnitude's architecture separates concerns into three distinct packages that collectively implement a flexible, provider-agnostic AI system. This layered design enables seamless swapping between OpenAI, Anthropic, local LLMs, and custom providers without changing client code. This article examines how packages/ai, packages/providers, and packages/sdk interact to deliver this abstraction.


The Three-Layer Architecture

Package Responsibility Position in Stack
packages/ai Core AI contract — types, schemas, and utility definitions for generic AI interactions Provider-agnostic foundation
packages/providers Concrete implementations — actual provider clients plus a runtime registry Implementation layer
packages/sdk Public client API — RPC bindings, connection handling, and convenience functions Consumer-facing interface

packages/ai: The Provider-Agnostic Contract

The @magnitudedev/ai package establishes the foundational types that decouple all other components from specific model implementations.

This package defines schemas for:

  • Prompt — standardized message structures
  • ToolCallId and ToolDefinition — function-calling primitives
  • Streaming response chunks — incremental generation handling

All downstream packages import from @magnitudedev/ai to maintain type safety without vendor lock-in. The SDK specifically re-exports these core types in packages/sdk/src/index.ts:

// packages/sdk/src/index.ts — AI type re-exports
export * from "@magnitudedev/ai/provider/model";
export type {
  ToolCallId,
  Prompt,
  ToolDefinition,
  // ... additional AI primitives
} from "@magnitudedev/ai";

By centralizing these definitions, Magnitude ensures that adding a new provider requires zero changes to client-facing code.


packages/providers: Concrete Implementations and Registry

The @magnitudedev/providers package contains actual provider integrations — OpenAI, Anthropic, local LLMs, and extensible custom adapters.

Each provider exports a factory object satisfying the ProviderModel interface defined in @magnitudedev/ai. The package also maintains a runtime registry that maps provider identifiers to these factories, as documented in packages/providers/AGENTS.md.

When implementing a new provider, you conform to the AI contract:

// Example provider implementation inside packages/providers
import { ProviderModel } from "@magnitudedev/ai/provider/model";

export const myCoolProvider: ProviderModel = {
  id: "mycool",
  createClient: (config) => new MyCoolClient(config.apiKey),
  // Must implement RPC shape from @magnitudedev/ai
};

The registry enables dynamic provider discovery — the SDK requests a provider by string ID, and the registry returns the appropriate factory without hardcoded imports.


packages/sdk: The Unified Client Interface

The @magnitudedev/sdk package is what applications actually import. It consumes both layers beneath it — AI types for safety, providers for execution — and exposes a clean surface for UI clients (cli, web, desktop).

Key responsibilities include:

  • Re-exporting AI types so consumers need only one dependency
  • RPC binding management via the ACN protocol (@magnitudedev/acn-protocol)
  • Connection state handling for the daemon
  • Convenience factories like makeInferenceClient

From packages/sdk/src/index.ts:

// Central export hub pattern
export { MagnitudeClient } from "./client";
export { makeInferenceClient } from "./inference";

// Re-export provider model namespace for direct access
export * from "@magnitudedev/ai/provider/model";

Architectural Flow: From Client Call to Model Execution

The complete request path demonstrates how the three packages cooperate:

  1. Client imports from SDK
import { MagnitudeClient, makeInferenceClient } from "@magnitudedev/sdk";

const client = new MagnitudeClient({ endpoint: "http://localhost:3000" });
const inference = makeInferenceClient(client, {
  providerId: "openai",
  modelId: "gpt-4o-mini",
});
  1. SDK resolves provider via registry — looks up "openai" in packages/providers registry

  2. Provider instantiates concrete model — returns client adhering to @magnitudedev/ai interfaces

  3. SDK transmits RPC via ACN protocol — @magnitudedev/acn-protocol handles wire format

  4. Daemon executes provider's inference logic — actual API call to OpenAI, Anthropic, etc.


Key Inter-Package Dependencies

Link Mechanism Source Location
AI types → SDK Direct re-export packages/sdk/src/index.ts lines 37-44
Provider model namespace → SDK Re-export for client access packages/sdk/src/index.ts lines 45-46
Provider registry → SDK Runtime lookup (conceptual) packages/providers/AGENTS.md
ACN protocol → SDK RPC implementation packages/acn-protocol/

Summary

  • packages/ai provides provider-agnostic types and schemas — the contract that makes interchangeability possible
  • packages/providers supplies concrete implementations plus runtime registration — the realization layer
  • packages/sdk delivers the unified client API — the single dependency for application developers, bridging to providers via ACN RPCs

This separation enables Magnitude to support new AI services by adding implementation packages without touching SDK or client code.


Frequently Asked Questions

How do I add a custom provider to Magnitude?

Implement the ProviderModel interface from @magnitudedev/ai in a new file under packages/providers, then register it in the provider registry. Your implementation must return a client that handles the RPC shapes defined in packages/acn-protocol. No changes to packages/sdk are required.

Can I use Magnitude's AI types without the full SDK?

Yes — import directly from @magnitudedev/ai. This is useful for building tooling that operates on Magnitude's data structures without needing RPC capabilities or provider connectivity.

Why does the SDK re-export @magnitudedev/ai/provider/model separately?

This namespace contains low-level model descriptors that client code may need to reference when specifying exact model variants. By re-exporting it, the SDK prevents consumers from adding a direct dependency on the providers package while preserving full type access.

What protocol do providers use to communicate with the daemon?

All provider communication flows through ACN (Agent Communication Network) protocol, defined in packages/acn-protocol/. The SDK serializes requests into this wire format; the daemon deserializes and routes to the appropriate provider implementation.

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 →