Skip to content

API Reference: createArmor

The main entry point for ai-armor. Creates an ArmorInstance with all configured protections.

Import

ts
import { createArmor } from 'ai-armor'

Signature

ts
function createArmor(config: ArmorConfig): ArmorInstance

Parameters

config: ArmorConfig

Every field on ArmorConfig is optional. Only configure the features you need.

ts
interface ArmorConfig {
  rateLimit?: RateLimitConfig
  budget?: BudgetConfig
  fallback?: FallbackConfig
  cache?: CacheConfig
  routing?: RoutingConfig
  safety?: SafetyConfig
  logging?: LoggingConfig
}

rateLimit: RateLimitConfig

FieldTypeRequiredDescription
strategy'sliding-window'YesRate limiting algorithm
rulesRateLimitRule[]YesArray of rate limit rules
store'memory' | 'redis' | StorageAdapterNoStorage backend. Default: in-memory
keyResolver(ctx: ArmorContext, ruleKey: string) => stringNoCustom key resolution
onLimited(ctx: ArmorContext) => voidNoCallback when rate limited

RateLimitRule:

FieldTypeDescription
key'user' | 'ip' | 'apiKey' | stringDimension to rate limit by
limitnumberMaximum requests in the window
windowstringTime window (e.g., '1m', '1h', '30s', '1d')

See Rate Limiting guide for details.


budget: BudgetConfig

FieldTypeRequiredDescription
dailynumberNoMaximum daily spend in USD
monthlynumberNoMaximum monthly spend in USD
perUsernumberNoMaximum daily spend per user in USD
perUserMonthlynumberNoMaximum monthly spend per user in USD
onExceeded'block' | 'warn' | 'downgrade-model'YesAction when budget exceeded
downgradeMapRecord<string, string>NoModel downgrade mapping
store'memory' | 'redis' | StorageAdapterNoStorage backend. Default: in-memory
onWarned(ctx: ArmorContext, budget: { daily: number, monthly: number, perUserDaily?: number, perUserMonthly?: number }) => voidNoCallback when budget warning fires
onUnknownModel(model: string) => voidNoCallback when a model not in the pricing database is encountered

See Cost Tracking guide for details.


fallback: FallbackConfig

FieldTypeRequiredDescription
chainsRecord<string, string[]>YesFallback model chains per primary model
timeoutnumberNoRequest timeout in ms before triggering fallback
retriesnumberNoNumber of retries before moving to next in chain
backoff'exponential' | 'linear'NoBackoff strategy between retries
healthCheckbooleanNoEnable passive health checking

cache: CacheConfig

FieldTypeRequiredDescription
enabledbooleanYesEnable/disable caching
strategy'exact' | 'semantic'YesCache matching strategy
ttlnumberYesTime-to-live in seconds
maxSizenumberNoMaximum entries (LRU eviction)
keyFn(request: ArmorRequest) => stringNoCustom cache key generator

Note: Semantic strategy requires additional fields (embeddingFn, similarityThreshold).

Semantic cache additional fields:

FieldTypeRequiredDescription
embeddingFn(text: string) => Promise<number[]>Yes (semantic)User-provided embedding function
similarityThresholdnumberNoMinimum cosine similarity for cache hit (default: 0.92)

See Caching guide for details.


routing: RoutingConfig

FieldTypeRequiredDescription
aliasesRecord<string, string>YesMap of alias to real model name

See Model Routing guide for details.


safety: SafetyConfig

FieldTypeRequiredDescription
promptInjectionbooleanNoEnable prompt injection detection
piiDetectionbooleanNoEnable PII detection
maxTokensPerRequestnumberNoMaximum tokens per request
blockedPatternsRegExp[]NoPatterns that block matching content
onBlocked(ctx: ArmorContext, reason: string) => voidNoCallback when request is blocked

See Safety guide for details.


logging: LoggingConfig

FieldTypeRequiredDescription
enabledbooleanYesEnable/disable logging
includeArray<'model' | 'tokens' | 'cost' | 'latency' | 'userId' | 'cached' | 'fallback'>YesFields to include
onRequest(log: ArmorLog) => void | Promise<void>NoCallback after each logged request
maxEntriesnumberNoMax entries in memory. Default: 10000

See Logging guide for details.


Return Type: ArmorInstance

ts
interface ArmorInstance {
  config: ArmorConfig
  checkRateLimit: (ctx: ArmorContext) => Promise<RateLimitResult>
  peekRateLimit: (ctx: ArmorContext) => Promise<{ remaining: number, resetAt: number }>
  trackCost: (model: string, inputTokens: number, outputTokens: number, userId?: string) => Promise<void>
  checkBudget: (model: string, ctx: ArmorContext) => Promise<{ allowed: boolean, action: string, suggestedModel?: string }>
  getDailyCost: (userId?: string) => Promise<number>
  getMonthlyCost: (userId?: string) => Promise<number>
  resolveModel: (model: string) => string
  getCachedResponse: (request: ArmorRequest) => Promise<unknown | undefined>
  setCachedResponse: (request: ArmorRequest, response: unknown) => Promise<void>
  log: (entry: ArmorLog) => Promise<void>
  getLogs: () => ArmorLog[]
  estimateCost: (model: string, inputTokens: number, outputTokens: number) => number
  getProvider: (model: string) => string
  checkSafety: (request: ArmorRequest, ctx: ArmorContext) => SafetyCheckResult
  executeFallback: <T>(request: ArmorRequest, handler: (model: string) => Promise<T>) => Promise<FallbackResult<T>>
}

Methods

checkRateLimit(ctx)

Check all configured rate limit rules for the given context.

ts
const result = await armor.checkRateLimit({
  userId: 'user-123',
  ip: '192.168.1.1',
})

Parameters:

NameTypeDescription
ctxArmorContextRequest context with user/IP/API key info

Returns: Promise<RateLimitResult>

ts
interface RateLimitResult {
  allowed: boolean // true if request can proceed
  remaining: number // requests remaining before limit
  resetAt: number // Unix timestamp (ms) when window resets
}

If no rate limit is configured, returns { allowed: true, remaining: Infinity, resetAt: 0 }.


trackCost(model, inputTokens, outputTokens, userId?)

Record token usage for budget tracking. Looks up the model in the pricing database and stores the calculated cost.

ts
await armor.trackCost('gpt-4o', 500, 200, 'user-123')

Parameters:

NameTypeDescription
modelstringModel name (must match pricing database)
inputTokensnumberNumber of input/prompt tokens
outputTokensnumberNumber of output/completion tokens
userIdstring?Optional user ID for per-user tracking

Returns: Promise<void>

No-op if budget is not configured.


checkBudget(model, ctx)

Check if the current spend is within budget limits.

ts
const result = await armor.checkBudget('gpt-4o', { userId: 'user-123' })
if (!result.allowed) {
  throw new Error(`Budget exceeded: ${result.action}`)
}
const finalModel = result.suggestedModel ?? 'gpt-4o'

Parameters:

NameTypeDescription
modelstringModel to check budget for
ctxArmorContextRequest context (needs userId for per-user checks)

Returns: Promise<{ allowed: boolean, action: string, suggestedModel?: string }>

FieldDescription
allowedtrue if request can proceed
action'pass', 'block', 'warn', or 'downgrade-model'
suggestedModelCheaper model to use (only when action is 'downgrade-model')

If no budget is configured, returns { allowed: true, action: 'pass' }.


resolveModel(model)

Resolve a model alias to its real model name.

ts
const real = armor.resolveModel('fast')
// => 'gpt-4o-mini' (if alias configured)

const passthrough = armor.resolveModel('gpt-4o')
// => 'gpt-4o' (not an alias, returned as-is)

Parameters:

NameTypeDescription
modelstringModel name or alias

Returns: string


getCachedResponse(request)

Look up a cached response for the given request.

ts
const request = {
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'Hello' }],
}
const cached = await armor.getCachedResponse(request)
if (cached) {
  return cached // Skip API call
}

Parameters:

NameTypeDescription
requestArmorRequestRequest to look up

Returns: Promise<unknown | undefined> -- The cached response, or undefined on cache miss.


setCachedResponse(request, response)

Store a response in the cache.

ts
await armor.setCachedResponse(request, response)

Parameters:

NameTypeDescription
requestArmorRequestThe request key
responseunknownThe response to cache

Returns: Promise<void>


log(entry)

Record a log entry.

ts
await armor.log({
  id: crypto.randomUUID(),
  timestamp: Date.now(),
  model: 'gpt-4o',
  provider: 'openai',
  inputTokens: 500,
  outputTokens: 200,
  cost: 0.00325,
  latency: 1234,
  cached: false,
  fallback: false,
  rateLimited: false,
  userId: 'user-123',
})

Parameters:

NameTypeDescription
entryArmorLogFull log entry

Returns: Promise<void>


getLogs()

Retrieve all stored log entries.

ts
const logs = armor.getLogs()
const totalCost = logs.reduce((sum, l) => sum + l.cost, 0)

Returns: ArmorLog[] -- A copy of all stored log entries.


estimateCost(model, inputTokens, outputTokens)

Calculate the estimated cost for a request without tracking it.

ts
const cost = armor.estimateCost('gpt-4o', 1000, 500)
// eslint-disable-next-line no-console
console.log(`Estimated: $${cost.toFixed(6)}`)

Parameters:

NameTypeDescription
modelstringModel name
inputTokensnumberNumber of input tokens
outputTokensnumberNumber of output tokens

Returns: number -- Cost in USD. Returns 0 if model is not in the pricing database.


peekRateLimit(ctx)

Check rate limit status without recording a request. Useful for UI indicators.

ts
const status = await armor.peekRateLimit({ userId: 'user-123' })
if (status.remaining < 5) {
  showWarning('Approaching rate limit')
}

Parameters:

NameTypeDescription
ctxArmorContextRequest context

Returns: Promise<{ remaining: number, resetAt: number }>


getDailyCost(userId?)

Get current daily spend.

ts
const daily = await armor.getDailyCost('user-123')

Parameters:

NameTypeDescription
userIdstring?Optional user ID for per-user cost

Returns: Promise<number> -- Cost in USD.


getMonthlyCost(userId?)

Get current monthly spend.

ts
const monthly = await armor.getMonthlyCost('user-123')

Parameters:

NameTypeDescription
userIdstring?Optional user ID for per-user cost

Returns: Promise<number> -- Cost in USD.


getProvider(model)

Get the provider name for a model from the pricing database.

ts
const provider = armor.getProvider('gpt-4o')
// => 'openai'

Parameters:

NameTypeDescription
modelstringModel name

Returns: string -- Provider name, or 'unknown' if model not found.


checkSafety(request, ctx)

Run safety checks on a request without going through the full pipeline.

ts
const result = armor.checkSafety(
  { model: 'gpt-4o', messages: [{ role: 'user', content: userInput }] },
  { userId: 'user-123' }
)
if (result.blocked) {
  throw new Error(`Blocked: ${result.reason}`)
}

Parameters:

NameTypeDescription
requestArmorRequestRequest to check
ctxArmorContextRequest context

Returns: SafetyCheckResult

ts
interface SafetyCheckResult {
  allowed: boolean
  blocked: boolean
  reason: string | null
  details: string[]
}

executeFallback(request, handler)

Execute a request through the fallback chain.

ts
const result = await armor.executeFallback(
  { model: 'gpt-4o', messages: [{ role: 'user', content: 'Hello' }] },
  async (model) => {
    return await callAI(model, messages)
  }
)
if (result.fallbackUsed) {
  console.warn(`Used fallback model: ${result.model}`)
}

Parameters:

NameTypeDescription
requestArmorRequestRequest with primary model
handler(model: string) => Promise<T>Function that calls the AI provider

Returns: Promise<FallbackResult<T>>

ts
interface FallbackResult<T> {
  result: T
  model: string
  attempts: number
  fallbackUsed: boolean
}

Additional Exports

The ai-armor package also exports these pricing utilities:

ts
import {
  addModel,
  calculateCost,
  cosineSimilarity,
  createPricingRegistry,
  createRedisAdapter,
  createSemanticCache,
  getAllModels,
  getModelPricing,
  getProvider,
  pricingDatabase,
  registerModels,
  removeModel,
  resetPricing,
  updateModel,
} from 'ai-armor'
FunctionDescription
calculateCost(model, inputTokens, outputTokens)Calculate cost in USD
getModelPricing(model)Get pricing info for a model
getAllModels()List all models in the pricing database
getProvider(model)Get the provider name for a model
addModel(pricing)Add a custom model to the pricing registry
updateModel(model, updates)Update pricing for an existing model
removeModel(model)Remove a model from the registry
resetPricing()Reset all custom models, restore defaults
registerModels(models)Bulk add multiple models
createPricingRegistry(initialModels?)Create an isolated pricing instance
createRedisAdapter(client, options?)Built-in Redis storage adapter for rate limiting and cost tracking
createSemanticCache(config)Create a standalone semantic cache instance
cosineSimilarity(a, b)Compute cosine similarity between two vectors
pricingDatabaseBuilt-in model pricing dataset (ModelPricing[])

Type Exports

TypeDescription
RedisAdapterOptionsOptions for createRedisAdapter (prefix, ttl)
RedisLikeInterface for Redis client compatibility
PricingRegistryPricing registry type

Released under the MIT License.