← all projects
Multi-Provider SDK

Ajala AI SDK

Unified TypeScript SDK for Claude and OpenAI integration. Smart JSON parsing with auto-fix, schema validation, variable interpolation.

Single API for multiple AI providers with automatic JSON repair, comprehensive schema validation, and 28 error codes for debugging.

TypeScript
Claude
OpenAI

Problem Statement

Every project that touches LLMs reinvents the same plumbing: provider-specific clients (Claude vs OpenAI have different SDKs and response shapes), prompt templating, coaxing models into returning valid JSON (and repairing it when they don't), schema validation, retries, caching, and key management. Swapping providers means rewriting integration code. It's repetitive, error-prone boilerplate.

Proposed Solution

Ajala (Yoruba for "traveler") is a unified JavaScript/TypeScript SDK that moves effortlessly between AI providers behind one consistent API. You initialize once with keys for Claude/OpenAI, then call ai.prompt(template, options, vars) everywhere — with built-in variable interpolation, type-safe JSON responses validated against a declared structure, a smart JSON auto-fix algorithm for malformed model output, retries, caching, and secure (optionally remote-fetched) key management.

Full Solution Details

  • Unified prompt APIai.prompt('Get weather for {{city}}', { expectJson, jsonStructure, validateJSON }, { city }) returns a parsed, validated object.
  • Declared JSON schema — per-field type, minimum/maximum, enum, description; the SDK enforces it and the model is steered toward it.
  • Smart JSON auto-fix — repairs common malformed-JSON failure modes from LLMs before validation.
  • Variable interpolation{{var}} templating with validation that required vars are supplied.
  • Reliability — retry logic and caching middleware.
  • 28 error codes — granular, debuggable failure taxonomy.
  • Secure keys — embedded or remotely-fetched keys; multi-build output (CJS / ESM / UMD); 80%+ test coverage.

Technical Documentation

The SDK is organized into four layers (documented in its ARCHITECTURE.md): API layer (config management, prompt processing, error handling), middleware layer (cache, retry, validation — composable), provider layer (Claude, OpenAI, and a slot for future providers), and utility layer (auth manager, variable interpolator, JSON validator/transformer). Two patterns anchor it: a Provider Pattern (Strategy + Factory)BaseProvider abstract class with authenticate/sendPrompt, and a ProviderFactory that registers and creates providers by name at runtime, so adding a provider is a registration, not a rewrite; and a middleware pipeline so cross-cutting concerns (cache/retry/validate) wrap any provider call uniformly. Ships CJS, ESM, and UMD builds.

Tech Stack

TypeScript; Anthropic Claude + OpenAI provider integrations; Strategy + Factory + Middleware patterns; multi-format builds (CJS/ESM/UMD); Jest (80%+ coverage).

System Design

              Application
                  │  ai.prompt(template, options, vars)
                  ▼
   API layer:  config · prompt processing · error handling (28 codes)
                  │
   Middleware:  Cache → Retry → Validation   (composable pipeline)
                  │
   Provider layer (Strategy + Factory):
        ProviderFactory.create(name) → BaseProvider
            ├── ClaudeProvider     ┐ authenticate() / sendPrompt()
            ├── OpenAIProvider     │
            └── (future providers) ┘
                  │
   Utility layer:  AuthManager · VariableInterpolator · JSON Validator/Transformer (auto-fix)

Smart Architectural Decisions

  • Strategy + Factory for providers. Provider differences are hidden behind BaseProvider, and ProviderFactory resolves them by name at runtime — so switching Claude↔OpenAI (or adding a third) never touches application code. Textbook extensibility, applied correctly.
  • Middleware pipeline for cross-cutting concerns. Cache, retry, and validation are composable middleware wrapping every call, instead of being tangled into each provider — clean separation and uniform behavior.
  • Treat LLM JSON as unreliable by design. The smart auto-fix + declared jsonStructure validation acknowledges that models return broken/partial JSON, and makes structured output dependable — the single biggest pain point of LLM apps.
  • 28 error codes turn opaque failures into a debuggable taxonomy.
  • CJS/ESM/UMD builds make it usable in Node, bundlers, and the browser alike.

Impacts

A reusable foundation that removes AI-integration boilerplate across projects: one API for multiple providers, dependable structured output (auto-fix + schema), and production reliability (retries, caching, granular errors) — 80%+ tested and shipped in three module formats.

Demonstrated Skills

SDK/library architecture (layered design, Strategy/Factory/Middleware patterns); LLM integration depth (structured output, JSON repair, prompt templating); reliability engineering (retry, cache, error taxonomy); multi-target build tooling (CJS/ESM/UMD); secure key management; TypeScript and test discipline (80%+).

Notes

  • Pattern fluency in the wild: a correctly-applied Strategy+Factory provider abstraction plus a middleware pipeline is exactly the kind of design-pattern competence interviewers probe for — and here it's shipped, not whiteboarded.
  • Solves the real LLM pain point: smart JSON auto-fix + declarative schema validation directly addresses the #1 production headache with LLMs (unreliable structured output).
  • Library-grade rigor: 28-code error taxonomy, retries/caching, 80%+ tests, and triple CJS/ESM/UMD builds show packaging maturity.
  • Documented architecture: a real ARCHITECTURE.md with layered diagrams demonstrates strong technical communication.
  • Part of a coherent AI-tooling theme across the portfolio (BuffByte, AskAboutMe, Jago PR Bot).
Ask me anything