Build/Agents

Schema Libraries

Choose from built-in, Zod, Valibot, or ArkType for validation

Agentuity uses the StandardSchema interface for validation, which means you can use any compatible library.

Choosing a Library

LibrarySyntaxBest For
@agentuity/schemas.object({ name: s.string() })Zero dependencies, basic validation
Zodz.object({ name: z.string() })AI SDK integration (.describe() support)
Valibotv.object({ name: v.string() })Smallest bundle size
ArkTypetype({ name: 'string' })TypeScript-native syntax, fast runtime

Recommendation: Start with @agentuity/schema for simple cases. Use other libraries depending on your needs. For example, Zod is recommended when working with generateObject() (its .describe() helps guide LLM output).

Using @agentuity/schema

The built-in schema library provides simple validation with zero external dependencies.

Basic Schema

import { createAgent, type AgentContext } from '@agentuity/runtime';
import { s } from '@agentuity/schema';
 
const agent = createAgent('UserProcessor', {
  schema: {
    input: s.object({
      email: s.string(),
      age: s.number(),
      role: s.string(),
    }),
    output: s.object({
      success: s.boolean(),
      userId: s.string(),
    }),
  },
  handler: async (ctx: AgentContext, input) => {
    ctx.logger.info('Processing user', { email: input.email });
    return {
      success: true,
      userId: crypto.randomUUID(),
    };
  },
});
 
export default agent;

Common Patterns

import { s } from '@agentuity/schema';
 
// Primitives
s.string()                    // Any string
s.number()                    // Any number
s.boolean()                   // Boolean
s.null()                      // Null value
 
// Objects and arrays
s.object({ name: s.string() })    // Object shape
s.array(s.string())               // Array of strings
 
// Optional and nullable
s.optional(s.string())            // string | undefined
s.nullable(s.string())            // string | null
 
// Unions and literals
s.union(s.string(), s.number())   // string | number
s.literal('active')               // Exact value

When to Use

Use @agentuity/schema for simple validation needs. For advanced features like email validation, string length constraints, or complex transformations, consider Zod or Valibot.

Using Valibot

Installation

bun add valibot

Basic Schema

import { createAgent, type AgentContext } from '@agentuity/runtime';
import * as v from 'valibot';
 
const InputSchema = v.object({
  email: v.pipe(v.string(), v.email()),
  age: v.pipe(v.number(), v.minValue(0), v.maxValue(120)),
  role: v.picklist(['admin', 'user', 'guest']),
});
 
const OutputSchema = v.object({
  success: v.boolean(),
  userId: v.string(),
});
 
const agent = createAgent('UserProcessor', {
  schema: {
    input: InputSchema,
    output: OutputSchema,
  },
  handler: async (ctx: AgentContext, input) => {
    ctx.logger.info('Processing user', { email: input.email, role: input.role });
    return {
      success: true,
      userId: crypto.randomUUID(),
    };
  },
});
 
export default agent;

Common Patterns

import * as v from 'valibot';
 
// Strings
v.string()                              // Any string
v.pipe(v.string(), v.minLength(5))      // Minimum length
v.pipe(v.string(), v.maxLength(100))    // Maximum length
v.pipe(v.string(), v.email())           // Email format
v.pipe(v.string(), v.url())             // URL format
 
// Numbers
v.number()                              // Any number
v.pipe(v.number(), v.minValue(0))       // Minimum value
v.pipe(v.number(), v.maxValue(100))     // Maximum value
v.pipe(v.number(), v.integer())         // Integer only
 
// Arrays and objects
v.array(v.string())                     // Array of strings
v.object({ name: v.string() })          // Object shape
 
// Optional and nullable
v.optional(v.string())                  // string | undefined
v.nullable(v.string())                  // string | null
v.nullish(v.string())                   // string | null | undefined
 
// Enums
v.picklist(['a', 'b', 'c'])             // One of these values
v.literal('exact')                      // Exact value
 
// Defaults
v.optional(v.string(), 'default')       // With default value

Using ArkType

Installation

bun add arktype

Basic Schema

import { createAgent, type AgentContext } from '@agentuity/runtime';
import { type } from 'arktype';
 
const InputSchema = type({
  email: 'string.email',
  age: 'number>=0&<=120',
  role: '"admin"|"user"|"guest"',
});
 
const OutputSchema = type({
  success: 'boolean',
  userId: 'string',
});
 
const agent = createAgent('UserProcessor', {
  schema: {
    input: InputSchema,
    output: OutputSchema,
  },
  handler: async (ctx: AgentContext, input) => {
    ctx.logger.info('Processing user', { email: input.email, role: input.role });
    return {
      success: true,
      userId: crypto.randomUUID(),
    };
  },
});
 
export default agent;

Common Patterns

import { type } from 'arktype';
 
// Strings
type('string')                    // Any string
type('string>5')                  // Minimum length (greater than 5 chars)
type('string<100')                // Maximum length
type('string.email')              // Email format
type('string.url')                // URL format
 
// Numbers
type('number')                    // Any number
type('number>0')                  // Greater than 0
type('number<=100')               // Less than or equal to 100
type('integer')                   // Integer only
type('number>=0&<=120')           // Range (0 to 120)
 
// Arrays and objects
type('string[]')                  // Array of strings
type({ name: 'string' })          // Object shape
 
// Optional and union
type('string?')                   // string | undefined
type('string|null')               // string | null
 
// Enums and literals
type('"a"|"b"|"c"')               // One of these values
type('"exact"')                   // Exact value
 
// Nested objects
type({
  user: {
    name: 'string',
    email: 'string.email',
  },
  tags: 'string[]?',
})

Migrating Between Libraries

Schemas are interchangeable in createAgent(). The same agent structure works with any StandardSchema library:

// With @agentuity/schema (built-in)
import { s } from '@agentuity/schema';
const schema = { input: s.object({ name: s.string() }) };
 
// With Zod
import { z } from 'zod';
const schema = { input: z.object({ name: z.string() }) };
 
// With Valibot
import * as v from 'valibot';
const schema = { input: v.object({ name: v.string() }) };
 
// With ArkType
import { type } from 'arktype';
const schema = { input: type({ name: 'string' }) };
 
// All work the same way in createAgent()
createAgent('MyAgent', { schema, handler: async (ctx, input) => { ... } });

Next Steps

Need Help?

Join our DiscordCommunity for assistance or just to hang with other humans building agents.

Send us an email at hi@agentuity.com if you'd like to get in touch.

Please Follow us on

If you haven't already, please Signup for your free account now and start building your first agent!