Skip to content
/ exo Public

The Exoskeleton for AI Agents. Type-safe tool definitions with built-in Risk Management, Observability, and Universal Adapters (OpenAI, Vercel, LangChain)

Notifications You must be signed in to change notification settings

fozooni/exo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

6 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@fozooni/exo

The Exoskeleton for your AI Agents.

npm version license build status


Why Exo?

AI Agents are unpredictable. They hallucinate arguments, ignore safety rails, and make it difficult to understand what went wrong.

Exo provides a strictly typed, deterministic security layer for your AI tools. Every input is validated, every high-risk action requires permission, and every execution is observableβ€”regardless of which SDK you use.

Features

  • πŸ›‘οΈ Deterministic Safety β€” Role-based access control with HIGH/MEDIUM/LOW risk levels and human-in-the-loop confirmation flows.
  • πŸ”Œ Universal Adapters β€” Works seamlessly with OpenAI SDK, Vercel AI SDK, and LangChain.
  • πŸ‘οΈ Observability β€” Zero-dependency lifecycle hooks for logging latency, errors, and custom telemetry.
  • πŸ”’ Type-Safe β€” Built on Zod with full TypeScript inference for both inputs and outputs.
  • ⚑ Lightweight β€” No external runtime dependencies beyond Zod.

Quick Start

npm install @fozooni/exo zod
import { z } from "zod";
import { createExoTool, RiskLevel } from "@fozooni/exo";

const weatherTool = createExoTool({
  name: "get_weather",
  description: "Gets the current weather for a city.",
  schema: z.object({
    city: z.string().describe("The city name"),
  }),
  executor: async ({ city }) => {
    return { city, temperature: 22, conditions: "sunny" };
  },
  config: {
    riskLevel: RiskLevel.LOW,
  },
});

// Execute directly
const result = await weatherTool.execute({ city: "Istanbul" });
console.log(result.data); // { city: 'Istanbul', temperature: 22, conditions: 'sunny' }

// Or get OpenAI-compatible spec
const spec = weatherTool.getOpenAISpec();
// Use with: openai.chat.completions.create({ tools: [spec] })

Advanced Usage

High-Risk Tools with Role-Based Access

const deleteDatabase = createExoTool({
  name: "delete_database",
  description: "Permanently deletes a database. DANGEROUS.",
  schema: z.object({ confirm: z.literal(true) }),
  executor: async () => ({ deleted: true }),
  config: {
    riskLevel: RiskLevel.HIGH, // Requires admin role
  },
});

// ❌ Throws RiskViolationError
await deleteDatabase.execute(
  { confirm: true },
  { user: { id: "1", role: "guest" } },
);

// βœ… Works
await deleteDatabase.execute(
  { confirm: true },
  { user: { id: "1", role: "admin" } },
);

Vercel AI SDK Integration

import { Exo, toVercelTool } from "@fozooni/exo";
import { streamText } from "ai";

const exo = new Exo([weatherTool, searchTool]);

// Get all tools as Vercel-compatible object
const tools = exo.getVercelTools();

const result = await streamText({
  model: openai("gpt-4o"),
  tools,
  messages,
});

Instant Debugging with Console Logger

import { createExoTool, createConsoleLogger } from "@fozooni/exo";

const tool = createExoTool({
  name: "my_tool",
  schema: z.object({}),
  executor: async () => ({ ok: true }),
  config: {
    hooks: createConsoleLogger(),
  },
});

await tool.execute({});
// [EXO] β–Ά START my_tool {}
// [EXO] βœ“ SUCCESS my_tool (0.42ms)

OpenAI Structured Outputs (Strict Mode)

// Generate schema with additionalProperties: false
const strictSpec = weatherTool.getOpenAISpec({ strict: true });

Middleware Pipeline

Intercept and modify execution flow. Useful for logging, caching, or altering arguments.

const loggingMiddleware: ExoMiddleware = async ({ toolName, args, next }) => {
  console.log(`Extensions: Running ${toolName}`);
  const result = await next();
  console.log(`Extensions: Finished ${toolName}`);
  return result;
};

const tool = createExoTool({
  // ... other options
  config: {
    middleware: [loggingMiddleware],
  },
});

Built-in Rate Limiting

Protect your tools from overuse with zero extra infrastructure.

import { createExoTool, createRateLimiter } from "@fozooni/exo";

// Limit to 10 requests per minute
const limiter = createRateLimiter({
  windowMs: 60 * 1000,
  limit: 10,
  // Optional: Custom key generator (defaults to toolName:userId)
  keyGenerator: (context) => context.userId,
});

const searchTool = createExoTool({
  name: "search",
  // ...
  config: {
    middleware: [limiter],
  },
});

API Reference

Core Classes

Export Description
ExoTool Main tool class with validation, execution, and spec generation
Exo Registry for managing multiple tools
createExoTool() Factory function with better type inference

Adapters

Export Description
toVercelTool() Convert to Vercel AI SDK format
toLangChainTool() Convert to LangChain DynamicStructuredTool format

Errors

Export Description
ValidationError Thrown when arguments fail Zod validation
RiskViolationError Thrown when a HIGH risk tool is called without permission
ConfirmationRequiredError Thrown when confirmation is needed

Roadmap

  • Middleware pipeline for pre/post processing
  • Built-in rate limiting
  • Telemetry integrations (OpenTelemetry, Datadog)
  • Tool versioning and deprecation support

Contributing

Contributions are welcome! Please read our contributing guidelines and submit a PR.

git clone https://github.com/fozooni/exo.git
cd exo
npm install
npm test

License

MIT Β© Fozooni

About

The Exoskeleton for AI Agents. Type-safe tool definitions with built-in Risk Management, Observability, and Universal Adapters (OpenAI, Vercel, LangChain)

Topics

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors