The Inkeep Agent Framework provides intelligent, AI-powered status updates that automatically generate contextual progress messages during agent execution. These updates give users ChatGPT-style feedback about what's happening behind the scenes without exposing internal technical details.
You can customize how status updates are generated by providing a custom prompt that gets appended to the base system prompt. Custom prompts are limited to 2000 characters to ensure optimal performance:
export const myAgent = agent({ id: "my-agent", defaultSubAgent: myAgent, subAgents: () => [myAgent], models: { summarizer: { model: "anthropic/claude-sonnet-4-5" }, }, statusUpdates: { numEvents: 3, timeInSeconds: 15, // Custom prompt is appended to the base system prompt prompt: "KEEP ALL STATUS UPDATES SHORT AND CONCISE. Use bullet points and focus only on user-visible progress.", },});
statusUpdates: { prompt: 'Keep responses to 5 words maximum. Use present tense verbs.',}// Results in: "Searching documentation", "Processing data", "Generating report"
Detailed Progress:
statusUpdates: { prompt: 'Provide specific details about what was found or accomplished. Include relevant numbers or names when available.',}// Results in: "Found 12 API endpoints in authentication docs", "Retrieved user profile for john@example.com"
Branded Tone:
statusUpdates: { prompt: 'Use a friendly, helpful tone. Start updates with action words like "Discovering", "Exploring", "Analyzing".',}// Results in: "Discovering relevant documentation...", "Analyzing search results for best matches"
/** * Default status component schemas for AI agent operations */import type { StatusComponent } from '@inkeep/agents-core';/** * Schema for retrieve operations - when agents are looking up, searching, * or researching information in web or downstream services */export const retrieveStatusSchema: StatusComponent = { type: 'retrieve', description: 'Use this when the system found or retrieved specific information from searches, queries, or lookups. ONLY report ACTUAL findings that appear explicitly in the tool results - never make up data, names, numbers, or details. The label must state the SPECIFIC discovery (e.g., "Found 3 authentication methods", "Database contains 500 records", "API supports JSON format") not the act of searching. Every detail must be traceable to actual tool output. NEVER invent placeholder names, fictional data, or information not present in the activities.',};/** * Schema for action operations - when agents are using tools or delegating * tasks with side-effects to update, create, or modify downstream services */export const actionStatusSchema: StatusComponent = { type: 'action', description: 'Use this when the system executed a tool or performed an operation that modified state or had side effects. ONLY report ACTUAL tool executions and their results as they appear in the tool outputs - never make up tool names, parameters, or outcomes. The label must describe what specific action was performed and its concrete result based on actual tool execution data. DO NOT make up examples like "Ran test suite with X passes" unless a test suite was ACTUALLY run and reported X passes. DO NOT say "Executed database query" unless a database query was ACTUALLY executed. Only report what literally happened. NEVER invent tool names, execution results, or details not explicitly present in the tool execution activities. If a tool failed, report the actual failure, not imagined success.',};/** * Default status component schemas collection */export const defaultStatusSchemas: StatusComponent[] = [retrieveStatusSchema, actionStatusSchema];
For complete control over status format, define custom structured status components using Zod schemas with the statusComponent helper:
import { z } from 'zod';import { statusComponent } from '@inkeep/agents-sdk';const toolSummary = statusComponent({ type: 'tool_summary', description: 'Summary of tool calls and their purpose', detailsSchema: z.object({ tool_name: z.string().describe('Name of tool used'), purpose: z.string().describe('Why this tool was called'), outcome: z.string().describe('What was discovered or accomplished'), }),});const progressUpdate = statusComponent({ type: 'progress_update', description: 'Progress information with metrics', detailsSchema: z.object({ current_step: z.string(), items_processed: z.number().optional(), status: z.enum(['in_progress', 'completed', 'pending']), }),});export const myAgent = agent({ id: "my-agent", defaultSubAgent: myAgent, subAgents: () => [myAgent], models: { summarizer: { model: "anthropic/claude-sonnet-4-5" }, }, statusUpdates: { numEvents: 3, timeInSeconds: 15, statusComponents: [ toolSummary.config, progressUpdate.config, ], },});
The statusComponent helper provides type-safe status component definitions with automatic schema validation. Zod schemas are automatically converted to JSON Schema format at runtime.
Status updates arrive as data-summary events with AI-generated labels and contextual details:
// In your message processingmessage.parts.forEach((part) => { if (part.type === "data-summary") { const { type, label, details } = part.data; // Display the user-friendly status label displayStatusUpdate(label); // Handle optional structured details if (details) { // For default status components: contextual operation details // For custom components: your defined schema structure displayStructuredDetails(details); } // The 'type' field indicates the summary category console.log(`Status update type: ${type}`); }});
// Good: Descriptive and actionable"Searching through documentation to find API authentication methods...";"Found OAuth2 setup prompt, now checking for code examples...";// Avoid: Too technical or vague"Agent thinking...";"Processing data-operation with tool_invocation type...";
statusUpdates: { numEvents: 3, timeInSeconds: 15, prompt: `Generate a brief, user-friendly status update that explains what has been accomplished and what is currently happening. Focus on user-visible progress, not internal operations. Be specific about findings, not just actions.`}
Status updates are automatically paused during text streaming to avoid
interrupting the response flow.