Skip to content

Cheat Sheet

theirish81 edited this page Sep 3, 2026 · 1 revision

FML Syntax Cheat Sheet

A rapid-reference guide for authoring, reviewing, and debugging FML plans.


1. Quick Syntax Overview

# --- GLOBAL DIRECTIVES ---
system(`System instruction text`)
parameter("param_name", type="string", default="val", enum=opt1|opt2)
set global_var = "value"
require mcp tool_name
require collection db_name

components {
    schema("ComponentName") {
        field_a: string        # Field documentation
        field_b?: int          # Optional field
        field_c: val1|val2|val3 # Enum values
    }
}

call("func") -> vars:global_output {
    arg1 = "val"
}

# --- SESSION DEFINITION ---
session("session_name", after="dep_session", expect="expr_cond", iterate="array_expr", target="custom_key") {
    use mcp tool_name { allowlist = ["func1", "func2"] }
    use search

    call("func") -> vars:local_output {
        arg1 = "{{ .params.param_name }}"
        arg2 = $(vars.global_output)
    }

    + Pre-prompt line 1 (Tools ENABLED)
      Indented multi-line continuation

    - Prompt line 1 (Tools DISABLED - Exactly one allowed)
      Formatting instruction

    context true # Injects all prior session contexts
    context "Custom: {{ .context.dep_session | json }}"

    set local_var = "value"

    schema {
        field1: string
        field2: int[]
        field3: $ComponentName
    }
    # OR for iterate sessions:
    # schema string[]
}

2. Directives & Signatures

File-Level Declarations

Directive Syntax Example Notes
system system("...") or system(`...`) Global LLM persona. Maximum one per file.
parameter parameter("p", type="string", default="x", enum=a|b) Input declaration. Types: string, int, bool.
set set varName = "value" Declares variable in vars namespace.
require require mcp name / require collection name Strictly one-liner. Never use allowlists here. Never require search.
components components { schema("Name") { ... } } Reusable schemas referenced as $Name.
transformer transformer("t") { onFunctionOutput = "f"; jmesPath = "..."; } Either jmesPath or code((...)), never both.
call call("func") -> vars:out { ... } Must specify target at root level.

Session Attributes

Attribute Syntax Example Purpose
name session("session_name") Mandatory identifier. Output published to context.<name>.
after after="session_a" Enforces execution dependency. Mandatory if referencing context.session_a.
expect expect="context.x != nil" Antonmedv expr condition. If false, session & dependents are skipped.
iterate iterate=context.items Antonmedv expr array. Session loops over array elements (it).
target target="custom_key" Overrides storage key. Output written to context.custom_key.

Prompts & Lifecycle

Syntax Allowed Quantity Tool Access Purpose
+ <text> Zero or more ENABLED Context enrichment, research, dynamic tool calls.
- <text> Exactly one DISABLED Schema mapping, final structuring. No tools permitted.
context Maximum one N/A Evaluated at session init. Antipattern to reference local PreCalls.

3. Namespaces & Access Rules

Namespace Source In Go Template ({{ ... }}) In Antonmedv Expr ($(...) / attrs)
params parameter(...) {{ .params.key }} params.key
vars set, PreCall -> vars:x {{ .vars.x }} vars.x
context Upstream session outputs {{ .context.session_name }} context.session_name
it iterate loop item {{ .it }} or {{ .it.field }} it or it.field

Warning

Leading Dot Rule:

  • Go Templates MUST have a leading dot: {{ .params.foo }}.
  • Antonmedv Expr MUST NOT have a leading dot: $(vars.foo) or expect="context.foo != nil".

4. PreCall JavaScript Formats

# Format A: Completion-Value Notation (Simple / Expression-only)
call("transform") -> vars:out {
    items = $(context.gather.items)
    code(
        (
            const list = args.items || [];
            list.filter(x => x.active).map(x => x.id); # Final expression = completion value
        )
    )
}

# Format B: IIFE Notation (Multi-statement / Complex branching)
call("process") -> vars:out {
    items = $(context.gather.items)
    code(
        (
            (() => {
                if (!args.items || args.items.length === 0) return { count: 0 };
                const res = runFunction("verify", { data: args.items });
                return { count: args.items.length, status: res.status };
            })()
        )
    )
}

5. Schema Field Types

Field Type Syntax Example Description
String name: string UTF-8 text string.
Integer count: int Whole number.
Float score: float Floating point number.
Boolean is_active: bool true or false.
Array tags: string[] Array of primitives or objects.
Enum / Union level: low|medium|high Pipe-separated string literal choices.
Enum Array roles: admin|editor|viewer[] Array of union values.
Optional middle_name?: string Field may be omitted (null / absent).
Component Ref author: $UserProfile References a declared components schema.
Inline Object meta: { id: int, hash: string } Anonymous nested object.
Array Shorthand schema string[] Top-level array (mandatory for iterate sessions).

6. Ten Golden Rules of FML

  1. Never require search: Use use search inside sessions; never require mcp search or require search.
  2. Exactly one - prompt: Each session must have exactly one - prompt. Zero or multiple is a compile error.
  3. Tools in + only: Never instruct the model to call tools in a - prompt; tool execution is physically disabled during the prompt phase.
  4. Declare after dependencies: If a session references context.foo, it must declare after="foo".
  5. Array schema for iterate: Any session using iterate must have an array schema (e.g. schema type[] or schema { ... }[]).
  6. Flat schemas: Do not wrap schema fields in a redundant root object named after the session.
  7. Colon in routing: Always write -> vars:name or -> context:key. Never use a dot (-> vars.name is invalid).
  8. Root calls require target: Global call statements must define an output routing (e.g. -> vars:res).
  9. Don't use context block for local PreCalls: context "..." initializes before PreCalls execute; reference PreCall outputs in + or - prompts instead.
  10. Transformer exclusivity: In transformer, use jmesPath OR code, never both.

Clone this wiki locally