Prompts
[TK]
1. Prompt Definition
A prompt defines how each request to an LLM is crafted. Each prompt specifies system instructions, a model reference, and optional configuration for tools, input validation, and response behavior.
1.1 Required Properties
A prompt definition MUST include the following properties:
| Property | Type | Description |
|---|---|---|
name | string | Unique identifier for this prompt |
toolDescription | string | Description shown when prompt is exposed as a tool |
prompt | PromptContent | System prompt content (string or structured) |
model | string | Model reference to use for this prompt |
1.2 Optional Properties
A prompt definition MAY include the following properties:
| Property | Type | Default | Description |
|---|---|---|---|
includeChat | boolean | false | Include full chat history |
includePastTools | boolean | false | Include past tool results |
parallelToolCalls | boolean | false | Allow parallel tool execution |
toolChoice | 'auto' | 'none' | 'required' | 'auto' | Tool calling strategy |
requiredSchema | ZodSchema | - | Input validation schema |
tools | (string | ToolConfig)[] | - | Available tools (include ai_human agent names for handoffs) |
reasoning | ReasoningConfig | - | Extended thinking config |
recentImageThreshold | number | 10 | Messages to keep images |
2. Prompt Content
2.1 String Prompts
The simplest form is a plain string containing the system instructions:
prompt: 'You are a helpful assistant. Be concise and accurate.'
System prompts SHOULD NOT contain secrets or sensitive credentials. Implementations SHOULD sanitize prompt content to prevent injection.
2.2 Structured Prompts
For composition and reuse, prompts can be structured arrays of parts:
prompt: [
{ type: 'text', content: 'You are a helpful assistant.\n\n' },
{ type: 'include', prompt: 'common_rules' },
{ type: 'text', content: '\n\nBe concise.' },
]
2.3 Prompt Parts
2.3.1 Text Parts
Text parts contain static content:
| Property | Type | Description |
|---|---|---|
type | 'text' | Discriminator |
content | string | Text content |
2.3.2 Include Parts
Include parts reference other prompts:
| Property | Type | Description |
|---|---|---|
type | 'include' | Discriminator |
prompt | string | Name of prompt to include |
2.4 Include Resolution
When a prompt includes another prompt:
- Implementations MUST recursively resolve all includes
- Implementations MUST detect and reject circular includes
- The included prompt’s content is inserted at the include location
- Only the
promptfield is included (not tools, model, etc.)
3. Tool Configuration
3.1 Simple Tool References
Tools can be referenced by name:
tools: ['search_docs', 'create_ticket', 'send_email']
3.2 Tool Configuration with Tenvs
Tools can be configured with thread environment variable (tenv) values. This allows prompts to provide default or required values for tools that need runtime configuration:
tools: [
'search_docs', // Simple reference
{
name: 'file_search', // Tool with tenv configuration
tenvs: {
vectorStoreId: 'vs_abc123', // Required by file_search
},
},
]
| Property | Type | Description |
|---|---|---|
name | string | Name of the tool |
tenvs | Record<string, unknown> | Thread environment variable values for this tool |
options | Record<string, unknown> | Static tool options |
Tenv values set in prompts serve as defaults. They can be overridden by agent-level tenvs or thread-level tenvs at creation time. See the Tools specification for details on tenv merging.
3.3 Sub-Prompt Tool Configuration
When a prompt is used as a tool by another prompt, the caller can configure how results are returned. These options only apply to sub-prompts, not to regular function tools.
Since sub-prompts return their results as tool call responses, all output must be serialized into a single text string. The configuration options control what gets included in that string.
tools: [
'search_docs', // Simple reference (function tool)
{
name: 'summarize_document', // Sub-prompt with configuration
includeTextResponse: true,
includeToolCalls: false,
includeErrors: true,
initUserMessageProperty: 'document',
},
]
| Property | Type | Default | Description |
|---|---|---|---|
name | string | Required | Name of the sub-prompt to call |
includeTextResponse | boolean | true | Include the sub-prompt’s text response in the result string |
includeToolCalls | boolean | true | Serialize tool calls made by the sub-prompt (and their results) into the result string |
includeErrors | boolean | true | Serialize any errors from the sub-prompt into the result string |
initUserMessageProperty | string | - | Use this argument property as the initial user message when invoking the sub-prompt |
The initUserMessageProperty is useful when the sub-prompt expects conversational input. For example, if initUserMessageProperty: 'query' is set and the caller passes { query: 'What is X?' }, the sub-prompt receives “What is X?” as its initial user message.
💡 Tip: Combine
initUserMessagePropertywithincludeChat: falseon the sub-prompt. The sub-prompt will only receive its own system prompt and the initial user message—allowing it to operate on a smaller, focused context with reduced token usage.
4. Tool Choice Strategy
4.1 Strategy Values
The toolChoice property controls how the LLM calls tools:
| Value | Behavior |
|---|---|
'auto' | Model decides when to call tools (default) |
'none' | Disable tool calling entirely |
'required' | Force the model to call at least one tool |
4.2 Tool Choice Behavior
When toolChoice is 'required':
- The LLM MUST include at least one tool call in its response
- Implementations SHOULD retry if the LLM fails to call a tool
When toolChoice is 'none':
- Tool definitions are not sent to the LLM
- The
toolsarray is ignored for that request
5. Input Validation
5.1 Required Schema
The requiredSchema property defines inputs when the prompt is called as a tool:
requiredSchema: z.object({
query: z.string().describe('Search query'),
limit: z.number().optional().default(10).describe('Max results'),
})
5.2 Schema Usage
When a required schema is provided:
- Implementations MUST validate inputs against the schema
- Implementations MUST generate JSON Schema for LLM tool definitions
- Field descriptions from
.describe()SHOULD be included
User inputs MUST be validated before inclusion in prompts.
💡 Tip: TypeScript implementations can use the
PromptInput<T>helper type to extract the inferred input type from a prompt’s schema:type SearchInput = PromptInput<typeof searchPrompt>.
6. Reasoning Configuration
6.1 Reasoning Properties
For models with extended thinking capabilities:
| Property | Type | Description |
|---|---|---|
effort | 'low' | 'medium' | 'high' | Reasoning effort level |
maxTokens | number | Max tokens for reasoning |
exclude | boolean | Exclude reasoning from response |
include | boolean | Include reasoning in history |
6.2 Effort Levels
| Level | Behavior |
|---|---|
'low' | Minimal reasoning, faster responses |
'medium' | Balanced reasoning and speed |
'high' | Maximum reasoning, slower but thorough |
6.3 Reasoning Visibility
- When
excludeistrue, reasoning is used internally but not returned - When
includeistrue, reasoning is preserved in message history - These can be combined for different use cases
7. Image Context Management
The recentImageThreshold property controls how images are handled in conversation context:
- Images in the most recent N messages are kept as full image content
- Older images are replaced with text descriptions
- Helps manage context window usage in long conversations
8. Validation
8.1 Required Field Validation
Implementations MUST validate that:
nameis a non-empty stringtoolDescriptionis a non-empty stringmodelreferences a defined modelpromptis either a string or valid structured array
8.2 Optional Field Validation
Implementations MUST validate that:
toolChoiceis one of:'auto','none','required'reasoning.effortis one of:'low','medium','high'recentImageThresholdis a positive integer
9. TypeScript Reference
/**
* Text part of a structured prompt.
*/
interface PromptTextPart {
type: 'text';
content: string;
}
/**
* Include part referencing another prompt.
*/
interface PromptIncludePart {
type: 'include';
prompt: string;
}
/**
* Union of prompt part types.
*/
type PromptPart = PromptTextPart | PromptIncludePart;
/**
* Structured prompt array.
*/
type StructuredPrompt = PromptPart[];
/**
* Prompt content (string or structured).
*/
type PromptContent = string | StructuredPrompt;
/**
* Configuration for tools with tenv values.
*/
interface ToolConfig<T extends string = string> {
name: T;
tenvs?: Record<string, unknown>;
options?: Record<string, unknown>;
}
/**
* Configuration for sub-prompts used as tools.
* These options control how results from sub-prompts are returned to the caller.
*/
interface SubpromptConfig<T extends string = string> {
name: T;
includeTextResponse?: boolean;
includeToolCalls?: boolean;
includeErrors?: boolean;
initUserMessageProperty?: string;
}
/**
* Reasoning configuration.
*/
interface ReasoningConfig {
effort?: 'low' | 'medium' | 'high';
maxTokens?: number;
exclude?: boolean;
include?: boolean;
}
/**
* Prompt definition configuration.
*/
interface PromptDefinition<
N extends string = string,
S extends ToolArgs = ToolArgs,
> {
name: N;
toolDescription: string;
prompt: PromptContent;
model: string;
includeChat?: boolean;
includePastTools?: boolean;
parallelToolCalls?: boolean;
toolChoice?: 'auto' | 'none' | 'required';
requiredSchema?: S;
tools?: (string | ToolConfig | SubpromptConfig)[];
tenvs?: Record<string, unknown>;
reasoning?: ReasoningConfig;
recentImageThreshold?: number;
}
/**
* Helper type for input inference.
*/
type PromptInput<T extends PromptDefinition> =
T['requiredSchema'] extends ToolArgs
? z.infer<T['requiredSchema']>
: never;
/**
* Define a prompt configuration.
*/
function definePrompt<N extends string, S extends ToolArgs = never>(
options: PromptDefinition<N, S>
): PromptDefinition<N, S>;
10. Examples
10.1 Basic Prompt
import { definePrompt } from '@standardagents/spec';
export default definePrompt({
name: 'assistant',
toolDescription: 'General purpose assistant',
model: 'conversational',
prompt: 'You are a helpful assistant. Be concise and accurate.',
});
10.2 Prompt with Tools
import { definePrompt } from '@standardagents/spec';
import { z } from 'zod';
export default definePrompt({
name: 'customer_support',
toolDescription: 'Handle customer support inquiries',
model: 'conversational',
prompt: `You are a customer support agent.
Always be polite and try to resolve issues quickly.
If you cannot help, offer to escalate.`,
tools: ['search_knowledge_base', 'create_ticket'],
includeChat: true,
requiredSchema: z.object({
query: z.string().describe('The customer inquiry'),
}),
});
10.3 Structured Prompt with Includes
import { definePrompt } from '@standardagents/spec';
export default definePrompt({
name: 'sales_agent',
toolDescription: 'Handle sales inquiries',
model: 'conversational',
prompt: [
{ type: 'text', content: 'You are a sales representative.\n\n' },
{ type: 'include', prompt: 'company_info' },
{ type: 'include', prompt: 'product_catalog' },
{ type: 'text', content: '\n\nBe helpful and persuasive.' },
],
tools: ['get_pricing', 'schedule_demo'],
});
10.4 Prompt with Reasoning
import { definePrompt } from '@standardagents/spec';
export default definePrompt({
name: 'code_reviewer',
toolDescription: 'Review code for issues and improvements',
model: 'heavy',
prompt: 'You are an expert code reviewer. Analyze code thoroughly.',
reasoning: {
effort: 'high',
maxTokens: 4096,
exclude: false,
},
});