Skip to content

Prompts API Reference

Complete API reference for defining and configuring prompts

Overview

Prompts define the instructions and configuration for LLM interactions in Standard Agents. Each prompt specifies system instructions, model configuration, tools, input validation, and context options.

Key Features
  • File-based: Defined in agents/prompts/ directory
  • Auto-discovered: No manual registration required
  • Type-safe: Full TypeScript support with Zod validation
  • Composable: Prompts can be exposed as tools for other prompts
  • Hot-reloadable: Changes trigger HMR in development

Quick Start

Create a new prompt in agents/prompts/:

agents/prompts/customer_support.ts
import { definePrompt } from '@standardagents/spec';

export default definePrompt({
  name: 'customer_support',
  toolDescription: 'Handle customer support inquiries',
  prompt: `You are a helpful customer support agent.
Always be polite and try to resolve issues quickly.`,
  model: 'gpt-6.1-sol',
  includeChat: true,
});

Reference it in an agent:

agents/agents/support_agent.ts
import { defineAgent } from '@standardagents/spec';

export default defineAgent({
  name: 'support_agent',
  sideA: {
    prompt: 'customer_support',  // References the prompt above
  },
  sideB: { human: true },
});

Configuration Options

namestringrequired

Unique identifier for this prompt. Use snake_case.

name: 'customer_support'
toolDescriptionstringrequired

Description shown when prompt is exposed as a tool. Always required for potential tool use.

toolDescription: 'Search for information and provide relevant results'
promptstring | StructuredPromptrequired

The system instructions sent to the LLM. Supports template variables using {{variableName}} syntax.

prompt: `You are helping {{userName}} with their request.
Current date: {{currentDate}}
Customer tier: {{customerTier}}`
modelstringrequired

Name of the model configuration to use. Must be defined in agents/models/.

model: 'gpt-6.1-sol'
includeChatbooleandefault: false

Include full chat history in LLM context.

includeChat: true
includePastToolsbooleandefault: false

Include earlier tool calls and their results in context, including calls from the current turn. Set this explicitly on each prompt with tools. Use true when a later step needs a result. With false, a tool loop can repeat calls until a step limit stops it.

includePastTools: true
parallelToolCallsboolean

Allow the model to return multiple tool calls. An explicit value controls the provider option. An omitted value uses the provider default. Local tools execute sequentially in returned order.

parallelToolCalls: false
toolChoice'auto' | 'none' | 'required'default: 'auto'

Tool calling strategy:

  • 'auto': LLM decides whether to use tools
  • 'none': Disable tool calling
  • 'required': Force the LLM to call at least one tool
toolChoice: 'required'
requiredSchemaZodSchema

Zod schema for input validation when called as a tool. The side A prompt schema also defines creation arguments when its agent runs as a subagent.

requiredSchema: z.object({
  userId: z.string().describe('The user ID to look up'),
  includeHistory: z.boolean().optional().describe('Include transaction history'),
})
tools(string | SubpromptConfig | PromptToolConfig)[]default: []

Available callable names, subprompt settings, and static tool options.

includePastTools: true,
tools: [
  'search_knowledge_base',
  { name: 'create_ticket', includeErrors: true },
]

An exposed agent referenced in tools performs a handoff in the current thread. Persistent child relationships belong in an owning agent side's subagents array. Subagent relationship configuration in a prompt tool entry is a definition-time error.

hooksstring[]

Hook IDs to run when this prompt is active. References hooks by their unique id property from agents/hooks/. A non-empty array selects the parent base set. An omitted or empty array uses the agent's hooks. Required child hooks run before or after that base set according to their stage.

hooks: ['limit_to_20_messages', 'log_tool_calls']
reasoningReasoningConfig

Extended thinking configuration for models that support it.

reasoning: {
  level: 100,
  maxTokens: 10000,
}
envRecord<string, string>

Default environment values for this prompt. Thread and agent values override them. They override user-account and instance values.

variablesVariableDefinition[]

Environment variable declarations for this prompt. Each declaration sets name, type, required, and description. scoped is optional.

providerOptionsRecord<string, unknown>

Provider options for this prompt. These override model-level options.

historyLimitnumber

A positive integer that bounds loaded top-level history when includeChat is enabled. The window advances in blocks of this size. It contains at least this many messages and fewer than twice this many when enough history exists. Tools, hooks, and execution.messageHistory see this window. Unset loads all eligible history. Stored messages remain intact.

recentImageThresholdnumberdefault: 10

A positive integer that sets how many recent messages retain image content.

Tools in Prompts

Tools are callable capabilities exposed to LLMs. They can be:

Functions

Custom code defined in agents/tools/

Prompts

Other prompts exposed as tools (sub-prompts)

Agents

Entire agents exposed as tools (handoffs)

Adding Tools

definePrompt({
  name: 'support_prompt',
  includePastTools: true,
  tools: [
    'search_knowledge_base',                    // Simple reference
    { name: 'create_ticket' },                  // Object form
    { name: 'sub_prompt', includeErrors: true }, // With options
  ],
  // ...
});

SubpromptConfig options

namestringrequired

Name of the tool

includeTextResponsebooleandefault: true

Include text response from sub-prompt execution

includeToolCallsbooleandefault: true

Include tool call details from sub-prompt

includeErrorsbooleandefault: true

Include error details from sub-prompt

initUserMessagePropertystring

Property from tool arguments to use as initial user message

initAttachmentsPropertystring

Argument property with an attachment path or an array of attachment paths.

PromptToolConfig options

{
  name: 'web_search',
  env: { SEARCH_CONTEXT: 'documentation' },
  options: { searchContextSize: 'high' },
}

env scopes environment values to the invocation. options contains static tool options. The deprecated tenvs alias remains available for environment values. The admin GET /api/prompts/:name response retains tools[].options unchanged. Prompt list and detail responses include the model display name in model_name. Their model_provider field contains a provider name for icon lookup.

Input Validation

Define input validation with Zod schemas:

import { definePrompt } from '@standardagents/spec';
import { z } from 'zod';

export default definePrompt({
  name: 'user_lookup',
  toolDescription: 'Look up user information',
  prompt: 'You help find user information...',
  model: 'gpt-6.1-sol',
  requiredSchema: z.object({
    userId: z.string().describe('The user ID to look up'),
    includeHistory: z.boolean().optional().describe('Include transaction history'),
  }),
});

Supported Zod Types

Prompt schemas require Zod 4 (zod@^4.0.0). Zod 3 schemas are unsupported.

Complete list of supported types
Zod Type Example Notes
z.string() z.string().min(1) Text values
z.number() z.number().positive() Numeric values
z.boolean() z.boolean() True/false
z.null() z.null() Null value
z.literal() z.literal('active') Exact value
z.enum() z.enum(['a', 'b']) One of values
z.array() z.array(z.string()) Arrays
z.object() z.object({...}) Objects
z.record() z.record(z.string(), z.string()) Dynamic keys
z.union() z.union([...]) Multiple types
z.optional() z.string().optional() Optional field
z.nullable() z.string().nullable() Can be null
z.default() z.number().default(10) Default value

Note: The default recursive schema type depth is 7 levels.

Extended Thinking

Configure extended thinking for models that support it:

definePrompt({
  name: 'complex_analysis',
  toolDescription: 'Analyze a complex problem with extended reasoning',
  prompt: 'You analyze complex problems...',
  model: 'claude-sonnet',
  reasoning: {
    level: 100,          // 0 to 100
    maxTokens: 10000,    // Maximum reasoning tokens
    exclude: false,      // Include reasoning in response
    include: true,       // Send earlier reasoning back on later requests (default)
  },
});

Reasoning Options

levelnumber

A prompt can set reasoning.level from 0 to 100. An unset level uses the model's default. Level 0 requests the least reasoning. A provider disables reasoning when the model supports that setting. Otherwise, it selects the lowest native setting. Each provider maps the level to the nearest option the model declares.

A prompt's reasoning.level replaces a native effort value in providerOptions. Other providerOptions keys remain. Without a level, providerOptions apply as provided. Native effort values in a model's providerOptions remain valid.

Saved prompt input with reasoning.effort fails validation. A published package prompt with reasoning.effort loads with a warning. The runtime ignores that field.

maxTokensnumber

Maximum tokens for reasoning (Anthropic, Google, Qwen)

excludebooleandefault: false

Use reasoning internally but exclude from response

includebooleandefault: true

Send the stored reasoning of earlier assistant messages back to the model on later requests. Set false to stop sending it. The reasoning stays in the message record either way.

Exposing Prompts as Tools

Every prompt is callable as a tool:

// agents/prompts/code_reviewer.ts
definePrompt({
  name: 'code_reviewer',
  toolDescription: 'Review code for bugs and improvements',
  prompt: `You are an expert code reviewer.
Analyze the provided code for:
- Bugs and potential issues
- Performance improvements
- Best practices violations`,
  model: 'gpt-6.1-sol',
  requiredSchema: z.object({
    code: z.string().describe('Code to review'),
    language: z.string().describe('Programming language'),
  }),
});

Use in another prompt:

// agents/prompts/developer_assistant.ts
definePrompt({
  name: 'developer_assistant',
  toolDescription: 'Help developers with coding tasks',
  prompt: 'You are a helpful coding assistant...',
  model: 'gpt-6.1-sol',
  tools: ['code_reviewer'],  // Use the prompt tool
});

Sub-Prompt Execution Flow

When an LLM calls a prompt tool:

  1. Tool call received: Parent prompt receives tool call with arguments
  2. Validation: Arguments validated against requiredSchema
  3. Sub-prompt execution: New execution context created
  4. Message hierarchy: Messages stored with parent_id and depth
  5. Result rollup: Sub-prompt response returned as tool result
  6. Parent continues: Parent LLM receives result and continues

Examples

Basic Conversation

import { definePrompt } from '@standardagents/spec';

export default definePrompt({
  name: 'assistant',
  toolDescription: 'General assistant for conversations',
  prompt: `You are a helpful assistant.
Provide clear, accurate, and friendly responses.`,
  model: 'gpt-6.1-sol',
  includeChat: true,
});

Customer Support with Tools

import { definePrompt } from '@standardagents/spec';
import { z } from 'zod';

export default definePrompt({
  name: 'customer_support',
  toolDescription: 'Handle customer support inquiries',
  prompt: `You are a customer support agent for Acme Corp.

Your responsibilities:
- Answer questions about products and services
- Help resolve issues on first contact
- Create support tickets when needed
- Escalate to specialists for complex issues

Always be professional and empathetic.`,
  model: 'gpt-6.1-sol',
  includeChat: true,
  includePastTools: true,
  tools: [
    'search_knowledge_base',
    'lookup_customer',
    { name: 'create_ticket', includeErrors: true },
  ],
});

Data Analysis with Reasoning

import { definePrompt } from '@standardagents/spec';
import { z } from 'zod';

export default definePrompt({
  name: 'data_analyst',
  toolDescription: 'Analyze data and generate insights',
  prompt: `You are a data analyst expert.
Analyze the provided data and return actionable insights.
Use statistical analysis when appropriate.`,
  model: 'gpt-6.1-sol',
  reasoning: {
    level: 66,
    exclude: false,
  },
  requiredSchema: z.object({
    data: z.string().describe('Data to analyze (JSON format)'),
    question: z.string().describe('Analysis question'),
    format: z.enum(['summary', 'detailed', 'json']).default('summary'),
  }),
  includePastTools: true,
  tools: [
    'calculate_statistics',
    'generate_chart',
  ],
});

Orchestrator

import { definePrompt } from '@standardagents/spec';

export default definePrompt({
  name: 'orchestrator',
  toolDescription: 'Coordinate complex multi-step tasks',
  prompt: `You are a task orchestrator.
Break down complex requests into steps and coordinate execution.
Use specialized prompts for specific tasks.`,
  model: 'gpt-6.1-sol',
  includeChat: true,
  includePastTools: true,
  tools: [
    'data_analyst',      // Sub-prompt
    'code_reviewer',     // Sub-prompt
    'research_agent',    // Agent tool
    'search_web',        // Function tool
  ],
});

Type Definitions

Canonical prompt types

Import the current types from the package:

import type {
  PromptDefinition,
  PromptToolConfig,
  SubpromptConfig,
  PromptInput,
} from '@standardagents/spec';

A prompt's tools array accepts callable names, SubpromptConfig, and PromptToolConfig. SubpromptConfig controls result filters and initial message mappings. PromptToolConfig supplies scoped environment values and static options.

ReasoningConfig

interface ReasoningConfig {
  /** Reasoning level from 0 to 100 */
  level?: number;

  /** Maximum tokens for reasoning */
  maxTokens?: number;

  /** Use reasoning internally but exclude from response */
  exclude?: boolean;

  /** Send earlier reasoning back on later requests (default true) */
  include?: boolean;
}

PromptInput Type Helper

Extract the input type from a prompt definition:

import type { PromptInput } from '@standardagents/spec';
import myPrompt from './my_prompt';

type MyPromptInput = PromptInput<typeof myPrompt>;
// { userId: string; options?: { format: 'json' | 'text' } }

Best Practices

Write Clear System Prompts
// Good - clear structure and expectations
definePrompt({
  name: 'support_agent',
  prompt: `You are a customer support agent for Acme Corp.

## Your Role
- Answer questions about products and services
- Help resolve issues on first contact
- Create tickets for complex issues

## Guidelines
- Be professional and empathetic
- Ask clarifying questions when needed
- Never share internal information

## Available Tools
Use these tools to help customers:
- search_knowledge_base: Find product information
- create_ticket: Create support tickets`,
  // ...
});

// Avoid - vague instructions
definePrompt({
  name: 'support_agent',
  prompt: 'Help customers.',
  // ...
});
Use Descriptive Tool Descriptions
// Good - specific and actionable
definePrompt({
  name: 'search_prompt',
  toolDescription: 'Search the knowledge base for product information, FAQs, and troubleshooting guides. Returns relevant articles.',
  // ...
});

// Avoid - too vague
definePrompt({
  name: 'search_prompt',
  toolDescription: 'Search stuff',
  // ...
});
Validate Inputs with Zod
// Good - detailed schema with descriptions
requiredSchema: z.object({
  customerId: z.string().min(1).describe('Customer ID from CRM'),
  issue: z.string().min(10).describe('Description of the issue'),
  priority: z.enum(['low', 'medium', 'high']).default('medium'),
}).strict()

// Avoid - no validation
requiredSchema: z.object({
  data: z.any(),
})
Enable includeChat for Conversations
// For conversational prompts
definePrompt({
  name: 'chat_assistant',
  includeChat: true,  // Needed for context
  // ...
});

// For single-shot tasks
definePrompt({
  name: 'code_formatter',
  includeChat: false,  // No history needed
  // ...
});

File Structure

agents/
└── prompts/
    ├── customer_support.ts   # export default definePrompt({...})
    ├── data_analyst.ts       # export default definePrompt({...})
    └── orchestrator.ts       # export default definePrompt({...})

Requirements:

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