Skip to main content

Prompt System

AgentFlow standardizes model-visible context around four names:
NameWhat it isExamples
prompt_blocksReusable prompt/context definitions, plus inline request-time blocksrole, tool_guidance, crm_context, available_skills, selected_account
system_contextHidden model-only context attached to the current user turnresolved mentions, KB snippets, attachments, page/selection context, inline turn blocks
system_remindersHidden current-turn reminders supplied by the systemautomatic archival memory recall, bounded current-run reminders
system_eventsDurable system-authored facts/actions between turnsartifact actions, artifact summaries, conversation compaction notices
Everything still ends up in the model prompt. The names describe how it is authored, stored, and replayed.

Assembly Diagram

Recommended assembly order:
  1. Cached system conversation prompt blocks
  2. Conversation history, including prior hidden context and system events
  3. Active user text plus hidden current-turn system_context and system_reminders
Volatile turn context stays out of the cached system prefix so provider prompt caching remains useful.

Prompt Blocks

A prompt block is the developer-facing primitive for reusable prompt text.
name
description
message        # system | user
type           # static | dynamic
mode           # cached | real_time
scope          # conversation | turn
tags
order
ttl
agents
body           # static and inline only
enabled
Static blocks have a stored editable body. Dynamic blocks are local AgentFlow functions that return body text at runtime. Inline blocks are request-time bodies supplied by an SDK/client. AgentFlow validates, wraps, caches, orders, and injects the rendered body:
renewal risk: high
next step: schedule executive follow-up
becomes:
<account_guidance>
renewal risk: high
next step: schedule executive follow-up
</account_guidance>
Use body for prompt text. Do not use content, template, source, kind, remote renderer URLs, or uploaded code bundles.

Placement

message controls where the block is injected:
messagePlacement
systemSystem message
userActive user-message envelope
scope controls cadence:
scopeCadence
conversationStable conversation/session context
turnCurrent model request
mode controls freshness:
modeBehavior
cachedCache when eligible
real_timeBuild for the current request
Most behavioral instructions are message="system", scope="conversation", mode="cached". Most current-screen or selected-record context is message="user", scope="turn", mode="real_time".

System Context

system_context is hidden context for the model, attached to a user turn. It is not the user’s visible message. Examples:
<system_context>
  <resolved_mention>Acme Corp account details...</resolved_mention>
  <retrieval_result>Relevant renewal policy excerpt...</retrieval_result>
  <selected_account>Acme Corp, ARR $120k, renewal in 31 days</selected_account>
</system_context>
This is where AgentFlow places resolved context_refs, KB retrieval snippets, attachments, page/selection context, and inline turn prompt blocks. It persists with the turn for replay, but normal chat UIs should render conversation_parts.content, not the hidden model input.

System Reminders

The system_reminders envelope holds hidden current-turn context that should read like reminders from the system rather than evidence or source material. Example:
<system_reminders>
  <archival_memory>Past Acme renewal notes that matched this request...</archival_memory>
</system_reminders>
The first built-in use is automatic archival memory recall from memory_policy.archival_mode="auto". Core memory remains a cached conversation prompt block; explicit memory-tool results remain tool results.

System Events

system_events are durable system-authored facts that happened between user turns. They are part of conversation history and should replay on future turns. Examples:
<system_events>
  <artifact_action>email sent to Sarah at 2026-04-28T14:03:00Z</artifact_action>
</system_events>
<system_events>
  <conversation_summary>Earlier discussion focused on Acme renewal risk...</conversation_summary>
</system_events>
Use system events for artifact actions/summaries, conversation compaction notices, and other system-owned updates that must persist independently of a specific visible user message. Conversation summary text is tracked in the conversation memory checkpoint; the durable event alerts the agent that earlier history was compacted.

Progressive Disclosure

Catalog prompt blocks should introduce what is available without loading full content:
CatalogPrompt block
Knowledge basesavailable_knowledge_bases
Skillsavailable_skills
Artifactsavailable_artifacts
Future assets/filesavailable_assets or available_files
Future memorymemory index/catalog block
Catalog items should stay small and consistent:
name: revenue_playbook
description: Renewal and expansion workflow guidance.
when_to_use: Use when planning account next steps.
how_to_use: Search the knowledge base before answering policy-specific questions.
The catalog tells the agent what exists and how to load more detail. The full file, skill, KB result, or asset content should only be fetched when useful.

Authoring

Static registered block:
await client.prompt_blocks.create(
    name="account_guidance",
    description="Guidance for account analysis.",
    message="system",
    type="static",
    mode="cached",
    scope="conversation",
    tags=["crm", "guidance"],
    body="When analyzing accounts, prioritize renewal risk and expansion signals.",
)
Dynamic local block:
from framework.prompts.block_registry import PromptContext, prompt_block


@prompt_block(scope="conversation", tags=["crm", "context"], ttl=1800)
async def crm_context(ctx: PromptContext) -> str | None:
    """Relevant CRM context for this conversation."""
    account = await get_account_context(ctx)
    if not account:
        return None
    return format_account_context(account)
Inline request block:
from agentflow import InlinePromptBlock, RunOptions

result = await client.agents.run(
    agent_id=agent_id,
    message="What should I do next?",
    options=RunOptions(
        prompt_blocks=[
            InlinePromptBlock(
                name="selected_account",
                body="Acme Corp, ARR $120k, renewal in 31 days",
                tags=["selection", "context"],
            )
        ]
    ),
)

Routes

GET    /api/v1/prompt-blocks
POST   /api/v1/prompt-blocks
GET    /api/v1/prompt-blocks/{name}
PATCH  /api/v1/prompt-blocks/{name}
DELETE /api/v1/prompt-blocks/{name}
POST   /api/v1/prompt-blocks/{name}/preview
POST   /api/v1/prompt-blocks/{name}/invalidate-cache
Compatibility context-block routes remain for listing, building, and preloading conversation-scoped dynamic blocks:
GET  /api/v1/agent/{agent_id}/context/blocks
POST /api/v1/agent/{agent_id}/context/blocks/build
POST /api/v1/agent/{agent_id}/context/preload