-
Notifications
You must be signed in to change notification settings - Fork 0
Language Overview
FML (Frags Modeling Language) is a declarative domain-specific language (DSL) engineered for orchestrating agentic LLM workflows. It bridges deterministic computation (tool calling, API piping, data filtering) with generative reasoning (context synthesis, extraction, schema-constrained structured output).
FML was designed around four core architectural principles:
- Strict Phased Isolation: Tool calling and schema formatting are fundamentally incompatible operations when demanded simultaneously from an LLM. FML enforces a temporal barrier: tools run during context enrichment, and are stripped during output formatting.
- Determinism Wherever Possible: Non-deterministic LLM operations should only be used where reasoning is required. PreCalls, data transformers, and variable routing handle deterministic data shaping with zero token overhead.
- Type Preservation & Type Safety: Data flowing between tools, scripts, and sessions preserves native Go/JSON data types (arrays, maps, primitives) without inadvertent stringification.
-
Isolated Scopes & Traceability: Inputs, runtime variables, and completed session artifacts live in separate namespaces (
params,vars,context,it), preventing variable clobbering and simplifying plan debugging.
An FML source file consists of two primary regions:
# -------------------------------------------------------------------
# 1. FILE-LEVEL (GLOBAL) DECLARATIONS
# Must appear outside any session blocks
# -------------------------------------------------------------------
system(`You are an intelligent data analyst assistant.`)
parameter("dataset_id", type="string")
set default_limit = 100
require mcp analytics_engine
require collection internal_db
components {
schema("MetricRecord") {
timestamp: string
value: float
}
}
call("pre_warm_cache") -> vars:cache_status {
dataset = "{{ .params.dataset_id }}"
}
# -------------------------------------------------------------------
# 2. SESSION CONSTRUCTS
# Independent LLM execution blocks forming a directed acyclic graph
# -------------------------------------------------------------------
session("analyze_metrics", target="analysis") {
use mcp analytics_engine { allowlist = ["query"] }
call("verify_dataset") {
dataset = "{{ .params.dataset_id }}"
}
+ Retrieve key performance indicators for dataset {{ .params.dataset_id }}.
Ensure anomaly detection is executed.
- Synthesize the metrics into the requested JSON schema.
schema {
metrics: $MetricRecord[]
status: success|warning|critical # System health assessment
}
}
FML uses the hash symbol (#) for comments:
# This is a single-line comment
session("example") {
# Comments inside sessions can appear anywhere
schema {
name: string # INLINE COMMENTS IN SCHEMAS ACT AS LLM FIELD DESCRIPTIONS!
score: float # Confidence score between 0.0 and 1.0
}
}
Tip
Inline comments in schema blocks are parsed by the FML runtime and converted into schema descriptions in the JSON Schema passed to the model. Always use inline comments on schema fields to guide the LLM's output.
FML supports two string literal formats:
-
Double-Quoted Strings (
"..."): Used for single-line strings, session names, parameter names, tool names, and simple templates. -
Backtick Strings (
`...`): Used for multi-line strings, such as thesystemprompt directive.
system(`Line 1 of system prompt.
Line 2 of system prompt.
Line 3 of system prompt.`)
Prompts (+ and -) support multi-line instructions via indentation:
session("audit") {
+ First line of pre-prompt instruction.
Second line continued automatically via indentation.
Third line referencing {{ .params.dataset_id }}.
- Format the final answer cleanly.
Ensure all schema constraints are strictly respected.
schema {
status: string
}
}
Any indented lines following a + or - token belong to that prompt block until the next unindented FML keyword or block boundary.
FML integrates two specialized expression engines. Choosing the right syntax depends on whether you need string interpolation or native typed evaluation:
| Feature | Go text/template
|
Antonmedv expr
|
|---|---|---|
| Syntax | {{ .namespace.field }} |
$(namespace.field) or raw in attributes |
| Leading Dot |
Required (e.g. .params.x) |
Forbidden (e.g. params.x) |
| Used In | Pre-prompts (+), Prompts (-), quoted call arguments, context string, defaults |
call arguments $(...), expect="...", iterate="..."
|
| Output Type | Always a string | Native types (array, object, bool, int, float) |
| Built-in Functions | Go template standard pipelines, custom ` | json` filter |
| Keyword / Symbol | Scope | Purpose |
|---|---|---|
system(...) |
Global (Max 1) | Declares the global system persona/prompt. Supports quotes or backticks. |
parameter(...) |
Global | Declares runtime input parameters (type, default, enum). |
set var = val |
Global or Session | Assigns a variable in the vars namespace. |
require <kind> <name> |
Global | Declares an external tool requirement (mcp or collection). Strictly one-liner. |
transformer(...) |
Global | Declares a data transformer (jmesPath or code) for tool function outputs. |
components |
Global | Declares reusable schema definitions (schema("Name") { ... }). |
call("func") |
Global or Session | Executes a deterministic tool or JavaScript code block. |
session("name", ...) |
Top-level | Declares an LLM execution unit with dependency chaining and schema validation. |
use <kind> <name> |
Session-level | Activates a tool for this session; supports { allowlist = [...] }. |
use search |
Session-level | Activates the built-in search tool (takes no name). |
+ <instruction> |
Session-level | Pre-prompt: Context gathering; tool calling permitted. |
- <instruction> |
Session-level (Max 1) | Prompt: Output formatting; tool calling strictly disabled. |
context <val> |
Session-level (Max 1) | Injects context: context true or context "...". Evaluated at session init. |
schema { ... } |
Session-level | Defines the JSON output structure enforced on the session's prompt. |
Traditional Agent Loops:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Single Prompt containing: β
β - System instructions β
β - Massive tool schemas (often 20+ tools) β
β - Tool calling instructions β
β - JSON Schema definition β
β - Raw intermediate data dumps β
β β
β Result: High token cost, frequent hallucination, β
β formatting failures, unrepeatable execution. β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
FML Phased DAG Architecture:
ββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββ
β Global Scope β βββΆ β Session: Tool Calling Phase β βββΆ β Session: Output β
β - Parameters β β - call: Deterministic PreCalls β β - No tools β
β - Require Tools β β - + Pre-prompt: Research & Tools β β - Strict Schema β
β - Schema Models β β - Compact sanitized variables β β - Validated JSONβ
ββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββ
By decoupling information retrieval from structured JSON generation, FML produces predictable, reliable agent execution graphs.
FML (Frags Modeling Language) | Getting Started | Cheat Sheet | Examples
Documentation for FML & Gemini Agent Workflows β Maintained by Frags HQ