Skip to content

defineModel

Define LLM model configurations with typed provider options

Overview

defineModel creates a model configuration that can be referenced by prompts and agents. Models use provider factory functions imported from provider packages for typed configuration.

import { defineModel } from '@standardagents/spec';
import { openai } from '@standardagents/openai';

export default defineModel({
  name: 'heavy-thinking',
  provider: openai,
  model: 'gpt-6.1-sol',
  // Prices change. Check https://developers.openai.com/api/docs/pricing
  // Standard rates apply to prompts up to 272K tokens.
  inputPrice: 2,
  outputPrice: 10,
});

Type Definition

import type { ProviderFactoryWithOptions, ModelCapabilities } from '@standardagents/spec';
import type { ZodTypeAny, z } from 'zod';

function defineModel<
  N extends string,
  P extends ProviderFactoryWithOptions<ZodTypeAny>
>(options: ModelDefinition<N, P>): ModelDefinition<N, P>;

interface ModelDefinition<
  N extends string = string,
  P extends ProviderFactoryWithOptions<ZodTypeAny> = ProviderFactoryWithOptions<ZodTypeAny>
> {
  name: N;
  provider: P;
  model: string;
  inputPrice?: number;
  outputPrice?: number;
  cachedPrice?: number;
  fallbacks?: string[];
  includedProviders?: string[];
  capabilities?: ModelCapabilities;
  providerOptions?: InferProviderOptions<P>;
  providerTools?: string[];
}

interface ModelCapabilities {
  reasoningLevels?: Record<number, string | null>;
  supportsImages?: boolean;
  supportsToolCalls?: boolean;
  supportsStreaming?: boolean;
  supportsJsonMode?: boolean;
  maxContextTokens?: number;
  maxOutputTokens?: number;
}

// Automatically infers the correct type from the provider's schema
type InferProviderOptions<P> = P extends ProviderFactoryWithOptions<infer S>
  ? S extends ZodTypeAny ? z.input<S> : Record<string, unknown>
  : Record<string, unknown>;

Parameters

namestringrequired

Unique identifier for this model configuration. Used to reference the model in prompts and agents.

Best Practice: Name models by use case, not by model ID:

  • heavy-thinking - Complex reasoning tasks
  • fast-response - Quick, simple responses
  • code-generation - Code-focused tasks
providerProviderFactoryrequired

Provider factory function imported from a provider package.

import { anthropic } from '@standardagents/anthropic';
import { cerebras } from '@standardagents/cerebras';
import { cloudflare } from '@standardagents/cloudflare';
import { deepinfra } from '@standardagents/deepinfra';
import { google } from '@standardagents/google';
import { groq } from '@standardagents/groq';
import { novita } from '@standardagents/novita';
import { openai } from '@standardagents/openai';
import { openrouter } from '@standardagents/openrouter';
import { xai } from '@standardagents/xai';

provider: anthropic    // Anthropic Claude via @anthropic-ai/sdk
provider: cerebras     // Cerebras Chat Completions API
provider: cloudflare   // Cloudflare Workers AI OpenAI-compatible API
provider: deepinfra    // DeepInfra OpenAI-compatible Chat Completions API
provider: google       // Google Gemini / Imagen via @google/genai
provider: groq         // Groq chat completions via groq-sdk
provider: novita       // Novita OpenAI-compatible Chat Completions API
provider: openai       // Direct OpenAI API
provider: openrouter   // Multi-provider gateway
provider: xai          // xAI Grok chat / image models

User-defined providers are also provider factories. Put them in agents/providers/ with defineProvider, then import them as a default import:

import darkbloom from '../providers/darkbloom';

provider: darkbloom

See defineProvider for custom endpoints, API keys, icons, and model discovery overrides.

modelstringrequired

The specific model identifier sent to the provider API.

OpenAI examples:

  • gpt-6.1-sol
  • gpt-6-luna
  • gpt-6-astra

Cerebras examples:

  • qwen-3.8-27b
  • gpt-oss-120b

Cloudflare Workers AI examples:

  • @cf/google/gemma-4-26b-a4b-it
  • @cf/openai/gpt-oss-120b
  • @cf/qwen/qwen3-30b-a3b-fp8

OpenRouter format: provider/model-name

  • anthropic/claude-sonnet-5.5
  • google/gemini-3.8-flash
  • meta-llama/llama-3.3-70b-instruct

Google examples:

  • gemini-3.1-pro-preview
  • gemini-3.8-flash
  • imagen-4.0-generate-001

Groq examples:

  • llama-3.1-8b-instant
  • openai/gpt-oss-120b
  • qwen/qwen3-32b

Novita AI examples:

  • zai-org/glm-5.2
  • deepseek/deepseek-v3.2
  • moonshotai/kimi-k2.7-code

xAI examples:

  • grok-4-0709
  • grok-code-fast-1
  • grok-imagine-image
inputPricenumber

Price per 1 million input tokens in USD. Explicit input and output prices take precedence over the runtime's provider pricing tables. OpenAI and Cerebras can use those tables when explicit prices are omitted. OpenRouter responses can supply cost from the provider API.

outputPricenumber

Price per 1 million output tokens in USD. Set this with inputPrice to override runtime pricing.

cachedPricenumber

Price per 1 million cached tokens in USD (if provider supports caching).

fallbacksstring[]

Array of model names to try if the primary model fails. Must reference other models defined with defineModel.

Fallbacks are tried for:

  • Network errors
  • Rate limits (429)
  • Server errors (5xx)
  • Authentication errors (401)
includedProvidersstring[]

OpenRouter only. Providers to try first for this model, in list order. The list is sent as OpenRouter's provider.order, so other providers remain fallbacks unless providerOptions.provider.allow_fallbacks is false. An explicit providerOptions.provider.order takes precedence, and other provider routing options are kept. To use only these providers, set providerOptions.provider.only.

includedProviders: ['anthropic']  // Prefer Anthropic
capabilitiesModelCapabilities

Model capability flags for framework behavior. See Capabilities section.

providerOptionsInferProviderOptions<P>

Provider-specific options. Type is inferred from the provider's schema. Native effort values are valid here. A prompt's reasoning.level replaces a native effort value. Other options remain. Without a level, options apply as provided.

See Provider Options section for available options per provider.

providerToolsstring[]

Enable built-in provider tools by provider-defined name. Available tools depend on the provider and model.

providerTools: ['web_search', 'code_interpreter']

Provider packages translate these names into their native request format and execute them through the provider API. Standard Agents Builder discovers and selects the tools, but does not execute provider tools locally.

Provider Options

OpenAI

import { openai } from '@standardagents/openai';

defineModel({
  name: 'gpt-6.1-sol',
  provider: openai,
  model: 'gpt-6.1-sol',
  providerOptions: {
    service_tier: 'auto', // Also accepts 'default' or 'flex'.
    user: 'user-123',
    seed: 42,
    frequency_penalty: 0.5,  // -2.0 to 2.0
    presence_penalty: 0.5,   // -2.0 to 2.0
    logprobs: true,
    top_logprobs: 5,         // 0-20
    store: true,
    metadata: { key: 'value' },
  },
});

OpenRouter

import { openrouter } from '@standardagents/openrouter';

defineModel({
  name: 'claude-sonnet',
  provider: openrouter,
  model: 'anthropic/claude-sonnet-5.5',
  providerTools: ['web_search', 'web_fetch', 'datetime', 'image_generation'],
  providerOptions: {
    provider: {
      order: ['anthropic', 'openai'],
      allow_fallbacks: true,
      require_parameters: true,
      data_collection: 'deny', // Also accepts 'allow'.
      zdr: true,
      only: ['anthropic'],
      ignore: ['azure'],
      sort: 'price', // Also accepts 'throughput' or 'latency'.
      max_price: {
        prompt: 1,
        completion: 5,
        request: 0.01,
        image: 0.05,
      },
      quantizations: ['fp16', 'bf16'],
      preferred_min_throughput: 100,
      preferred_max_latency: 1,
    },
    serverTools: {
      web_search: { max_results: 5 },
      web_fetch: { max_content_tokens: 50000 },
      datetime: { timezone: 'America/New_York' },
      image_generation: { quality: 'high' },
    },
  },
});

Cerebras

import { cerebras } from '@standardagents/cerebras';

defineModel({
  name: 'cerebras-fast',
  provider: cerebras,
  model: 'qwen-3.8-27b',
  // Prices change. Check https://www.cerebras.ai/pricing
  inputPrice: 0.99,
  outputPrice: 1.49,
  providerOptions: {
    service_tier: 'default',
    reasoning_effort: 'high',
    clear_thinking: false,
    user: 'user-123',
    seed: 42,
  },
});

Cloudflare Workers AI

import { cloudflare } from '@standardagents/cloudflare';

defineModel({
  name: 'workers-fast',
  provider: cloudflare,
  model: '@cf/google/gemma-4-26b-a4b-it',
  // Prices change. Check https://developers.cloudflare.com/workers-ai/platform/pricing/
  inputPrice: 0.1,
  outputPrice: 0.3,
  providerOptions: {
    seed: 42,
    user: 'user-123',
  },
});

Capabilities

capabilities: {
  // Reasoning support (0-100 scale → model values)
  reasoningLevels: {
    0: null,      // No reasoning
    33: 'low',    // Low effort
    66: 'medium', // Medium effort
    100: 'high',  // High effort
  },

  // Feature support
  supportsImages: true,      // Can process image inputs
  supportsToolCalls: true,   // Supports function calling
  supportsStreaming: true,   // Supports streaming responses
  supportsJsonMode: true,    // Supports structured JSON output

  // Token limits
  maxContextTokens: 1050000,  // Max context window
  maxOutputTokens: 128000,    // Max output tokens
}

Return Value

Returns the same ModelDefinition object passed in, enabling the build system to register it.

Examples

OpenAI Model

import { defineModel } from '@standardagents/spec';
import { openai } from '@standardagents/openai';

export default defineModel({
  name: 'heavy-thinking',
  provider: openai,
  model: 'gpt-6.1-sol',
  // Prices change. Check https://developers.openai.com/api/docs/pricing
  // Standard rates apply to prompts up to 272K tokens.
  inputPrice: 2,
  outputPrice: 10,
  capabilities: {
    supportsImages: true,
    supportsToolCalls: true,
    supportsJsonMode: true,
    maxContextTokens: 1050000,
  },
  providerOptions: {
    service_tier: 'default',
  },
});

OpenRouter Model

import { defineModel } from '@standardagents/spec';
import { openrouter } from '@standardagents/openrouter';

export default defineModel({
  name: 'claude-sonnet',
  provider: openrouter,
  model: 'anthropic/claude-sonnet-5.5',
  capabilities: {
    supportsImages: true,
    supportsToolCalls: true,
    maxContextTokens: 1000000,
  },
  providerOptions: {
    provider: {
      zdr: true,
      only: ['anthropic'],
    },
  },
});

With Fallbacks

import { defineModel } from '@standardagents/spec';
import { openai } from '@standardagents/openai';

// agents/models/fallback_cheap.ts
export default defineModel({
  name: 'fallback-cheap',
  provider: openai,
  model: 'gpt-6-luna',
  // Prices change. Check https://developers.openai.com/api/docs/pricing
  // Standard rates apply to prompts up to 272K tokens.
  inputPrice: 0.1,
  outputPrice: 0.5,
});
agents/models/primary.ts
import { defineModel } from '@standardagents/spec';
import { openai } from '@standardagents/openai';

export default defineModel({
  name: 'primary',
  provider: openai,
  model: 'gpt-6.1-sol',
  fallbacks: ['fallback-cheap'],
  // Prices change. Check https://developers.openai.com/api/docs/pricing
  // Standard rates apply to prompts up to 272K tokens.
  inputPrice: 2,
  outputPrice: 10,
});

With Provider Tools

import { defineModel } from '@standardagents/spec';
import { openai } from '@standardagents/openai';

export default defineModel({
  name: 'gpt-6.1-sol-with-tools',
  provider: openai,
  model: 'gpt-6.1-sol',
  // Prices change. Check https://developers.openai.com/api/docs/pricing
  // Standard rates apply to prompts up to 272K tokens.
  inputPrice: 2,
  outputPrice: 10,
  providerTools: ['web_search', 'code_interpreter', 'file_search'],
});

Reasoning Model

import { defineModel } from '@standardagents/spec';
import { openai } from '@standardagents/openai';

export default defineModel({
  name: 'deep-reasoning',
  provider: openai,
  model: 'gpt-6-astra',
  // Prices change. Check https://developers.openai.com/api/docs/pricing
  // Standard rates apply to prompts up to 272K tokens.
  inputPrice: 10,
  outputPrice: 50,
  capabilities: {
    supportsToolCalls: true,
    reasoningLevels: {
      0: 'low',
      33: 'low',
      66: 'medium',
      100: 'high',
    },
  },
});

File Location

Models are auto-discovered from agents/models/:

agents/
└── models/
    ├── heavy_thinking.ts
    ├── fast_response.ts
    └── budget.ts

Requirements:

  • Use snake_case for file names
  • One model per file
  • Default export required

Generated Types

The dev server populates StandardAgentSpec.ModelRegistry. StandardAgentSpec.Models resolves to its registered names:

// Auto-generated
declare global {
  namespace StandardAgentSpec {
    interface ModelRegistry {
      'heavy-thinking': true;
      'fast-response': true;
      budget: true;
    }
  }
}
export {};

This enables type-safe model references in prompts.

Runtime Validation

defineModel performs runtime validation:

  • name is required and must be a non-empty string
  • provider must be a valid ProviderFactory function
  • model is required and must be a non-empty string
  • Pricing values must be non-negative if provided
  • providerOptions are validated against the provider's schema
// This will throw at runtime:
defineModel({
  name: 'my-model',
  provider: 'openai',  // Error: Must be a ProviderFactory, not a string
  model: 'gpt-6.1-sol',
});