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

> Understand Magnitude's provider system. Discover how packages/ai, packages/providers, and packages/sdk collaborate to deliver AI services and expose a unified client API for your applications.

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

---

**`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`](https://github.com/magnitudedev/magnitude/blob/main/packages/sdk/src/index.ts):

```typescript
// 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`](https://github.com/magnitudedev/magnitude/blob/main/packages/providers/AGENTS.md).

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

```typescript
// 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`](https://github.com/magnitudedev/magnitude/blob/main/packages/sdk/src/index.ts):

```typescript
// 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**

```typescript
import { MagnitudeClient, makeInferenceClient } from "@magnitudedev/sdk";

const client = new MagnitudeClient({ endpoint: "http://localhost:3000" });
const inference = makeInferenceClient(client, {
  providerId: "openai",
  modelId: "gpt-4o-mini",
});

```

2. **SDK resolves provider via registry** — looks up `"openai"` in `packages/providers` registry

3. **Provider instantiates concrete model** — returns client adhering to `@magnitudedev/ai` interfaces

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

5. **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`](https://github.com/magnitudedev/magnitude/blob/main/packages/sdk/src/index.ts) lines 37-44 |
| Provider model namespace → SDK | Re-export for client access | [`packages/sdk/src/index.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/sdk/src/index.ts) lines 45-46 |
| Provider registry → SDK | Runtime lookup (conceptual) | [`packages/providers/AGENTS.md`](https://github.com/magnitudedev/magnitude/blob/main/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.