Complete documentation for Struckdown.
[[variable]] # Basic completion
[[type:variable]] # Typed completion
# Reference previous extraction
<checkpoint> # Memory boundary
<system>...</system> # System message block
<system local>...</system> # System message (segment-scoped)
| Type | Syntax | Example |
|---|---|---|
| Text | [[name]] |
Default text response |
| Boolean | [[bool:answer]] |
True/False |
| Integer | [[int:count]] |
Whole numbers |
| Number | [[number:price]] |
Int or float |
| Pick | [[pick:color\|red,blue]] |
Choose from options |
| Date | [[date:when]] |
Date extraction |
| DateTime | [[datetime:timestamp]] |
DateTime with timezone |
| Time | [[time:meeting]] |
Time extraction |
| Duration | [[duration:length]] |
Time spans |
| JSON | [[json:data]] |
Any valid JSON value |
| Record | [[record:info]] |
JSON object (string keys) |
| Syntax | Meaning |
|---|---|
[[3*item]] |
Exactly 3 items |
[[2:4*item]] |
Between 2-4 items |
[[*item]] |
Zero or more |
[[+item]] |
One or more |
[[?item]] |
Zero or one |
[[{n}*item]] |
Exactly n items |
[[{n,}*item]] |
At least n items |
[[!date:deadline]] # ! makes field required
[[date:optional]] # Optional (default)
[[date:required|required]] # Explicit required option
[[number:age|min=0,max=120]] # Number range
[[pick:size|S,M,L|required]] # Required selection
[[@action:var|param=value]] # Call Python function
[[@action:var|param="literal"]] # Literal string (quoted)
[[@search:results|query=q]] # Variable reference (unquoted)
# Interactive
sd chat "Prompt: [[var]]"
sd chat -p prompt.sd
# Batch
sd batch *.txt "[[extract]]" -o results.json
sd batch *.txt -p prompt.sd -o results.csv
# Options
-o, --output FILE # Output file (json/csv/xlsx)
-p, --prompt FILE # Prompt file
-k, --keep-inputs # Include input fields
-q, --quiet # Suppress progress
--verbose # Debug logging
<system> (global system prompt, persistent across segments)
↓
Segment 1: prompt → [[var1]]
↓
<checkpoint> (memory boundary)
↓
Segment 2: → [[var2]]
↓
<checkpoint>
↓
Segment 3: → [[var3]]
Global system messages persist across <checkpoint> boundaries.
Only user/assistant message history is cleared. Local system prompts (<system local>) are cleared at each checkpoint.
~/.struckdown/cache# Required
export LLM_API_KEY="sk-..."
export LLM_API_BASE="https://api.openai.com/v1"
# Optional
export DEFAULT_LLM="gpt-4o-mini" # Default model
export STRUCKDOWN_CACHE="~/.struckdown/cache" # Cache directory
export STRUCKDOWN_CACHE_SIZE=10240 # Cache size (MB)
Struckdown automatically parallelizes independent segments:
Segment A: [[var_a]]
Segment B: [[var_b]] # Runs in parallel with A
Segment C: [[var_c]] # Waits for A
Date patterns are automatically expanded:
[[date*:dates]] # Input: "first 3 Tuesdays in October"
# Output: [date1, date2, date3]
Parameters in custom actions are automatically coerced:
@Actions.register('add')
def add(context, a: int, b: int):
return str(a + b)
# "10" and "5" are converted to int automatically
[[@add:result|a=10,b=5]]
“No module named ‘struckdown’“
# Make sure it's installed
uv pip list | grep struckdown
# Reinstall if needed
uv pip install git+https://github.com/benwhalley/struckdown
“Set LLM_API_KEY and LLM_API_BASE environment variables”
export LLM_API_KEY="sk-..."
export LLM_API_BASE="https://api.openai.com/v1"
Cache corruption
# Clear cache
rm -rf ~/.struckdown/cache
# Or disable caching
export STRUCKDOWN_CACHE=0
Template parsing errors
[[completions]] are at the end of segments<checkpoint> is on its own lineSee issues at github.com/benwhalley/struckdown
MIT