guard() API

guard() is the core API. It wraps any function with runtime safety.

TypeScript

import { guard } from 'fuze-ai'

// Basic — all defaults from fuze.toml
const search = guard(async (query: string) => {
  return await vectorDb.search(query)
})

// With options
const search = guard(
  async (query: string) => {
    return await vectorDb.search(query)
  },
  {
    maxRetries: 5,
    timeout: 10_000,
    maxCost: 0.50,
  }
)

// Side-effect with compensation
const sendEmail = guard(
  async (to: string, body: string) => {
    return await ses.sendEmail(to, body)
  },
  {
    sideEffect: true,
    compensate: async (result) => {
      await ses.recallEmail(result.messageId)
    },
  }
)

Python

from fuze_ai import guard

# Basic
@guard
def search(query: str):
    return vector_db.search(query)

# With options
@guard(max_retries=5, timeout=10_000, max_cost=0.50)
def search(query: str):
    return vector_db.search(query)

# Side-effect with compensation
@guard(side_effect=True, compensate=recall_email)
def send_email(to: str, body: str):
    return ses.send_email(to, body)

Options

All options are optional. Defaults come from fuze.toml.

OptionTypeDefaultDescription
maxRetriesnumber3Max retry attempts for this function
timeoutnumber30000Timeout in milliseconds
maxCostnumber1.00Max cost in USD for this call
maxTokensnumberundefinedMax tokens for this call
maxIterationsnumber25Hard iteration cap for this call
onLoop'kill' | 'warn' | 'skip''kill'Behavior when a loop is detected
modelstringundefinedModel identifier for cost estimation
estimatedTokensInnumberundefinedEstimated input tokens (used for pre-flight cost checks)
estimatedTokensOutnumberundefinedEstimated output tokens (used for pre-flight cost checks)
sideEffectbooleanfalseWhether this call has real-world consequences
compensateFunctionundefinedRollback function called on failure

Return value

guard() returns a new function with the same signature. Call it exactly as you would the original.

const guardedSearch = guard(originalSearch)

// Same signature, same return type
const results = await guardedSearch('my query')

Guard events

When Fuze intervenes, it throws typed errors:

import { BudgetExceeded, LoopDetected, GuardTimeout } from 'fuze-ai'

try {
  await guardedSearch('query')
} catch (err) {
  if (err instanceof BudgetExceeded) {
    // Budget ceiling hit
  }
  if (err instanceof LoopDetected) {
    // Loop pattern detected
  }
  if (err instanceof GuardTimeout) {
    // Per-call timeout exceeded
  }
}
ErrorThrown when
BudgetExceededCost ceiling reached for the call or run
LoopDetectedRepeated output pattern detected
GuardTimeoutThe guarded function exceeded its timeout

createRun() API

createRun() creates a scoped run context that shares budget and loop state across multiple steps. Use it when a single logical task spans several guarded calls and you want aggregate limits to apply.

import { createRun, guard } from 'fuze-ai'

const run = createRun({ maxCost: 2.00, maxIterations: 50 })

const search = guard(async (q: string) => vectorDb.search(q), { run })
const summarize = guard(async (docs: string[]) => llm.summarize(docs), { run })

// Both steps share the same budget and loop state
const docs = await search('climate policy')
const summary = await summarize(docs)

Each call within the run draws from the shared maxCost and maxIterations budgets. If any step pushes the run over its ceiling, a BudgetExceeded error is thrown.

Timer cleanup

Fuze properly cleans up internal setTimeout timers on successful execution using a .finally(() => clearTimeout(timer)) pattern. This means:

  • No resource leaks -- timers are cleared whether the guarded function resolves or rejects.
  • Safe for long-running processes -- you can wrap thousands of calls without accumulating dangling timers.
  • No manual cleanup is required on the caller's side.