STATEK
Prompt Definitions

STATEK Prompt Definition Guide

STATEK prompt definition files keep agent instructions and model metadata outside Python code. They are Markdown files loaded from STATEK_PROMPT_FILES_DIR or from StatekSettings(prompt_files_dir=...).

A prompt file is matched to an agent by filename stem:

prompts/
  calendar_assistant.md
  dispatcher.md

calendar_assistant.md applies to Agent(role="calendar_assistant", ...).

⚠️

Prompt files can change what code an agent writes and what tools it can ask the model provider to call. Treat them as executable configuration: review changes, keep secrets out of prompt text, and deploy with the same sandboxing, permissioning, resource limits, and operational controls you use for agent code.

File Format

A prompt file has metadata comment lines followed by a required # System Prompt heading:

# MODEL: openai/gpt-5-mini
# TEMPERATURE: 0.2
# CHAT_STYLE: DIRECT
# DESCRIPTION: Helps users inspect and update calendar state
 
# System Prompt
ROLE: Calendar assistant and Python workspace operator.
GOAL: Help users inspect calendar objects and make safe scheduling changes.
 
Available variables: {shared_var_names}
 
Available functions:
{brief_tools}

Rules verified in the prompt parser:

  • Files must be .md files in the configured prompt directory.
  • Metadata lines before # System Prompt use # KEY: value.
  • Metadata keys are uppercased by the parser.
  • # System Prompt is required and is matched case-insensitively.
  • Content below # System Prompt is parsed as the agent system prompt.
  • A file without # System Prompt raises a parsing error.
  • Unknown metadata keys are preserved in the metadata dictionary, but STATEK gives them no framework behavior unless application code reads them.

Loading Behavior

Configure prompt loading through settings:

from statek.settings import StatekSettings
 
settings = StatekSettings(prompt_files_dir="./prompts")

or with the environment:

STATEK_PROMPT_FILES_DIR=./prompts

In a typical application, prompt files are the versioned source of truth for an agent's instructions and model metadata. Give each file the same stem as the agent role, such as calendar_assistant.md for Agent(role="calendar_assistant"), and STATEK uses that definition for the role.

This lets the Python agent definition focus on tools, context, and durable workspace setup, while product behavior lives in Markdown that can be reviewed and updated separately. Once prompt files are configured, treat inline _system_prompt and _metadata values as development defaults rather than the production definition.

Prompt changes affect new job definitions created from the updated agent configuration. Existing job definitions keep the metadata they were created with, so a running or already-defined job does not silently switch models or behavior just because a prompt file changed.

Advanced: update_prompt_config(...) can refresh already-created agent objects from prompt definitions during operational workflows, but existing job definitions still preserve their captured configuration except for explicitly supported refresh behavior.

Metadata Reference

MODEL

MODEL is required when creating job definitions.

Use one model:

# MODEL: openai/gpt-5-mini

or a complete difficulty mapping:

# MODEL: L:gpt-5-mini,MH:gpt-5

When a mapping uses difficulty labels, all three levels must be covered exactly once. Labels are L, M, H, or the full names low, medium, high.

PROVIDER

PROVIDER selects the provider when the provider is not embedded in MODEL.

# PROVIDER: OPENAI
# MODEL: gpt-5-mini

If the model string already embeds provider information, provider selection follows the model name.

TEMPERATURE

TEMPERATURE is parsed as a float from 0.0 through 1.0 and sent to providers that support it:

# TEMPERATURE: 0.2

Values outside that range raise a request error.

REASONING

Truthy REASONING values enable provider reasoning or thinking parameters where implemented:

# REASONING: true

OpenRouter receives a reasoning field. Claude-compatible requests receive a thinking field.

CHAT_STYLE

CHAT_STYLE controls chat and code formatting:

# CHAT_STYLE: DIRECT

Supported values are CONSOLE, MARKDOWN, MD_DIALOG, and DIRECT. See Chat Styles for how each style represents Python execution, console output, dialog, examples, and formal tool calls.

LLM_TOOLS_SCOPE

LLM_TOOLS_SCOPE controls which tool calls are sent to the model provider:

# LLM_TOOLS_SCOPE: SYSTEM
# LLM_TOOLS_SCOPE: APPLICATION+show_example
# LLM_TOOLS_SCOPE: ALL-panic

Supported categories are:

  • SYSTEM: registered system tools
  • APPLICATION: tools supplied by the application agent
  • ALL: system and application tools

You can add explicit tool names with +tool_name and remove names with -tool_name. Hidden tools cannot be exposed by explicit addition.

DESCRIPTION

DESCRIPTION is short capability text for routing or discovery:

# DESCRIPTION: Routes incoming requests to the best specialist agent.

update_prompt_config(...) applies it to matching agents as their description.

DEFAULT_DIFFICULTY

DEFAULT_DIFFICULTY selects the static difficulty when no example or dynamic escalation applies:

# DEFAULT_DIFFICULTY: M

Accepted values are L, M, H, low, medium, and high. If it is absent, STATEK falls back to STATEK_DEFAULT_DIFFICULTY, which defaults to M.

AUTO_LANG_HINT and AUTO_LANG_RULE

These are advanced language controls for localized jobs.

AUTO_LANG_HINT: False disables the language hint appended to user messages or push log messages for non-English locales. AUTO_LANG_RULE: False disables the language rule appended to the outgoing system prompt for non-English locales.

Locale Selection

Locale is selected when a job is created. It is not a # LOCALE: prompt-file metadata key.

Use locale when the application already knows the user's preferred language and country from account settings, tenant policy, request metadata, or a dispatcher decision. The locale is stored on the job definition and affects the request STATEK sends to the model.

In application code, pass a StatekLocale object:

from statek import create_new_job
from statek.locale import resolve_locale
 
job = create_new_job(
    agent=calendar_assistant,
    shared_vars={"message": incoming_message, "calendar": calendar},
    locale=resolve_locale("PL-PL"),
)

External client code can pass either a StatekLocale object or a locale string. StatekClientAPI resolves strings with resolve_locale(...) before creating the job:

from statek.statek_client_api import StatekClientAPI
 
job = StatekClientAPI().submit_new_job(
    agent=dispatcher,
    shared_vars={"event": incoming_event},
    locale="ES-ES",
    source="webhook",
)

When a job creates a child job and does not pass an explicit locale, STATEK inherits the parent job's locale. Pass a different locale only when the child job should deliberately switch language behavior.

Locale changes two automatic prompt behaviors:

  • for languages with a hardcoded rule, STATEK appends that rule to the outgoing system_prompt
  • for languages with a hardcoded hint, STATEK appends that hint to user messages and push-log messages

English locales and jobs without locale leave the prompt unchanged. Languages without a hardcoded rule or hint also do not receive automatic injected text, even when the language and country codes are valid. Current automatic rules and hints are defined for Polish, German, French, Spanish, and Italian.

Prompt metadata can disable either automatic behavior:

# MODEL: openai/gpt-5-mini
# AUTO_LANG_RULE: False
# AUTO_LANG_HINT: False
 
# System Prompt
ROLE: Calendar assistant.
GOAL: Help the user manage scheduling requests.

Use AUTO_LANG_RULE: False when your prompt already contains the complete language policy. Use AUTO_LANG_HINT: False when appending a reminder to each user-facing message would be noisy or your application already injects localized request text.

System Prompt Sections

The system prompt body can be plain text or a parsed set of sections. The intro text before the first section is always included.

STATEK recognizes four section delimiter styles:

<identity>Identity text.</identity>
 
--- RULES ---
Rules text.
 
*** WORKFLOW ***
Workflow text.
 
## Output
Output text.

Markdown headings from ## through ###### are section delimiters. # System Prompt is the prompt-file boundary, not a system prompt section.

When STATEK formats a prompt for a job, sections without difficulty metadata apply to every job. Sections with difficulty metadata apply only when the current job difficulty matches.

Target line-based sections with a difficulty prefix:

--- MH:RETRIEVAL ---
Use the broader retrieval workflow for medium and high difficulty tasks.
 
## L:Fast Path
Prefer the shortest safe answer path.

Target XML sections with attributes:

<retrieval difficulty="high">
Use the high-effort retrieval workflow.
</retrieval>
 
<examples target_difficulties="LMH">
Example usage notes.
</examples>

Valid labels are L, M, H, low, medium, and high. Compact labels such as LMH and delimited values such as low, high are accepted where the parser expects difficulty lists.

Current Agent.system_prompt(...) formatting emits dashed sections by default:

--- RULES ---
Rules text.

CHAT_STYLE does not change prompt section parsing. It changes chat history, examples, code blocks, console output, and tool execution shape.

Placeholders

STATEK expands common placeholders when formatting the system prompt for a job:

  • {brief_tools} inserts concise tool descriptions.
  • {tools} inserts normal tool descriptions.
  • {detailed_tools} inserts Python-style tool details.
  • {shared_var_names} expands from the job's shared_vars.

Other {name} placeholders can be supplied through job params or other format context.

# MODEL: openai/gpt-5-mini
 
# System Prompt
You operate on the durable Python workspace.
 
Available variables: {shared_var_names}
Request id: {request_id}
 
Available functions:
{brief_tools}

A matching job definition can pass context for those placeholders:

job_def = agent.create_job_def(
    shared_vars={"ticket": ticket, "customer": customer},
    request_id="REQ-1042",
)

If a placeholder line starts with #, tool descriptions are embedded as a Python block comment. This is useful when you want tool docs inside a code-oriented prompt.

Difficulty And panic()

Difficulty is a routing label for model selection and prompt section selection. It is not a guarantee of quality or deterministic behavior.

Resolution order:

  1. If the current job has a matching example difficulty, use it as dynamic difficulty.
  2. If dynamic difficulty already exists, a lower example difficulty does not downgrade it.
  3. If a higher matching example difficulty appears, it can raise the dynamic difficulty.
  4. If no dynamic difficulty applies, use job metadata DEFAULT_DIFFICULTY.
  5. If metadata does not define it, use STATEK_DEFAULT_DIFFICULTY.

panic() is a system tool that escalates the current job one step:

  • low to medium
  • medium to high
  • high raises an error

Use panic() when the current model or prompt section set is not enough for the task. It is an escalation mechanism, not a general retry button.

panic() is only available to the model when the LLM tool scope exposes that system tool, for example:

# LLM_TOOLS_SCOPE: SYSTEM

or:

# LLM_TOOLS_SCOPE: ALL

or:

# LLM_TOOLS_SCOPE: +panic

Chat Styles

CHAT_STYLE affects how chat history, code, console output, examples, and tool execution are represented. See Chat Styles for practical guidance and examples.

  • CONSOLE: console output is shown with > prefixes.
  • MARKDOWN: Python examples use fenced Python blocks; console output is plain text.
  • MD_DIALOG: Markdown dialog style with Python code blocks and console XML blocks.
  • DIRECT: Python execution uses the python_cli tool; Python code fences in model responses are ignored.

Related settings:

STATEK_CHAT_STYLE=DIRECT
STATEK_EXAMPLES_STYLE=MARKDOWN
STATEK_XML_BOX_CONSOLE=console_output
STATEK_XML_BOX_EXAMPLE=code_block

STATEK_CHAT_STYLE is the default job chat style when a job definition does not override it. STATEK_EXAMPLES_STYLE controls example formatting, falling back to chat style when absent. STATEK_XML_BOX_CONSOLE and STATEK_XML_BOX_EXAMPLE wrap console or example output in configured XML tags where the formatter supports boxing.

Minimal Prompt File

# MODEL: openai/gpt-5-mini
# TEMPERATURE: 0.2
# CHAT_STYLE: DIRECT
# LLM_TOOLS_SCOPE: APPLICATION
# DESCRIPTION: Helps users inspect and update calendar state.
 
# System Prompt
ROLE: Calendar assistant.
GOAL: Help the user answer scheduling questions using Python.
 
Available variables: {shared_var_names}
 
Available functions:
{brief_tools}

Advanced Prompt File

# MODEL: L:gpt-5-mini,MH:gpt-5
# DEFAULT_DIFFICULTY: M
# TEMPERATURE: 0.1
# CHAT_STYLE: DIRECT
# LLM_TOOLS_SCOPE: SYSTEM
# DESCRIPTION: Researches internal documents and summarizes verified findings.
 
# System Prompt
ROLE: Research assistant.
GOAL: Inspect available context and produce source-grounded answers.
 
Available variables: {shared_var_names}
 
--- L:FAST PATH ---
Use the smallest useful lookup. Prefer direct answers when the needed object is already in context.
 
--- MH:RETRIEVAL ---
When the answer is not already visible, list available documents or examples before making a claim.
 
<verification difficulty="high">
Cross-check important facts against at least two available sources when the tools expose them.
</verification>
 
--- AVAILABLE FUNCTIONS ---
{brief_tools}

Because CHAT_STYLE is DIRECT, Python execution should happen through the python_cli system tool when it is exposed. With LLM_TOOLS_SCOPE: SYSTEM, the model can use system tools such as python_cli, show_example, and panic() when those tools are registered for the active chat style.

Dispatcher Pattern

Dispatcher prompts are useful when one durable job decides whether to answer directly, continue an existing thread, or start a specialist job. Keep them narrow: load context in warmup code, print the relevant facts, and tell the dispatcher to make one routing decision.

# MODEL: openai/gpt-5-mini
# TEMPERATURE: 0.1
# CHAT_STYLE: DIRECT
# LLM_TOOLS_SCOPE: SYSTEM
# DEFAULT_DIFFICULTY: L
# DESCRIPTION: Routes incoming requests to the best specialist agent.
 
# System Prompt
ROLE: Request dispatcher.
GOAL: Route the current request to an existing job or the best specialist agent.
 
The warmup code already prepared and printed:
- the incoming request
- recent active jobs
- available specialist agents
- relevant example names
 
--- ROUTING POLICY ---
- Continue an existing job only when the request is clearly a follow-up.
- Start a new specialist job for a fresh self-contained request.
- Prefer the narrowest specialist that has the needed tools.
- Use `default_example_id` only when a printed example is reasonably similar.
 
--- OUTPUT ---
Call exactly one routing function. Do not perform unrelated exploration.
 
--- AVAILABLE FUNCTIONS ---
{brief_tools}

This pattern keeps application-specific business rules in your application prompt while avoiding private domain details in shared documentation.

Example File Snippet

Example files can carry metadata that show_example and difficulty resolution use. See Examples Machinery for the full file format and runtime tools:

# seq_id: 0
# name: Summarize one document
# difficulty: low
 
```python
docs = list_recent_documents(limit=3)
print(docs)
```
 
> [0] onboarding.md
> [1] billing.md
 
```python
summary = summarize_document(docs[0])
print(summary)
```

Example difficulty is optional. When present, it can raise the job's dynamic difficulty for prompt section selection and mapped model selection.

Related Configuration

Prompt definitions often work with these settings:

STATEK_PROMPT_FILES_DIR=./prompts
STATEK_EXAMPLES_DIR=./examples
STATEK_DOCUMENTS_DIR=./documents
STATEK_CHAT_STYLE=DIRECT
STATEK_EXAMPLES_STYLE=MARKDOWN
STATEK_DEFAULT_DIFFICULTY=M

Use prompt files for role instructions and model metadata. Keep durable objects, tool implementations, warmup behavior, provider credentials, and permission boundaries in application code and deployment configuration.

Use Documents Machinery when an agent should list and retrieve file-backed reference material at runtime instead of embedding it directly in the prompt.