-
Notifications
You must be signed in to change notification settings - Fork 0
File Level Constructs
File-level constructs define the global execution environment, parameter contracts, dependencies, and reusable definitions for an FML plan. All file-level statements must appear outside any session blocks, typically at the top of the file.
The system directive establishes the global persona and foundational instructions for the LLM across all sessions in the plan.
# Single-line with standard quotes
system("You are an expert research analyst.")
# Multi-line with backticks (recommended for detailed personas)
system(`You are a precise research assistant.
Use your tools to gather accurate findings.
Always cite your sources and adhere strictly to requested schemas.
`)
-
Quantity: At most one
systemdirective may appear per FML file. - Inheritance: Every session in the plan inherits this instruction as the base system message in its LLM context window.
Parameters declare the external inputs required by the plan. They define the input interface and provide runtime type safety.
parameter("identifier", type="string", default="default_value", enum=option1|option2|option3)
| Attribute | Required | Supported Values | Description |
|---|---|---|---|
name (1st arg) |
Yes | Valid identifier string | The parameter key, accessed via params.<name>. |
type |
Yes |
string, int, bool
|
May be quoted (e.g. type="string") or unquoted (type=string). |
default |
No | Matching literal value | Fallback value if no runtime argument is provided. Supports Go templates. |
enum |
No | val1|val2|val3 |
Pipe-delimited list of permitted string choices. |
# Required string parameter without default
parameter("query", type=string)
# Integer parameter with default value
parameter("max_results", type=int, default=10)
# Boolean parameter
parameter("enable_deep_scan", type=bool, default=false)
# Parameter with enum constraint
parameter("environment", type="string", default="staging", enum=development|staging|production)
Note
All parameters are stored in the params namespace. Access them via {{ .params.query }} in Go templates or params.query in Antonmedv expressions.
The set keyword assigns a static or computed value to a global variable.
set variableName = value
set max_retries = 3
set default_region = "us-central1"
set is_production = true
- Values declared with
setat the file level are stored in thevarsnamespace (e.g.,{{ .vars.default_region }}). - Any session can read these global variables.
- If a session declares
set default_region = "europe-west1"locally, it shadows the global variable inside that session without mutating the global value.
The require statement declares external integrations that must be loaded into the execution runtime. FML supports two integration targets:
-
mcp: Model Context Protocol servers providing external functions/tools. -
collection: Vector databases, document stores, or relational collections.
require mcp tool_name
require collection db_name
require mcp github
require mcp web_scraper
require collection internal_knowledge_base
Caution
Strictly One-Liners: require statements are strictly single-line declarations. They do NOT support block bodies, configuration maps, or allowlists at the file level. (Allowlists are configured inside individual sessions via use).
Warning
Never Require Search: The built-in search tool must never be declared with require. Writing require mcp search or require search is a compile error. Simply invoke use search inside the sessions where it is needed.
Transformers intercept and reshape raw tool outputs before they reach the LLM's conversational history. This is vital for reducing token bloat when tool outputs return massive JSON payloads containing irrelevant fields.
transformer("transformerName") {
onFunctionOutput = "targetFunctionName"
# Option A: JMESPath query string
jmesPath = "jmespath_expression"
# OR Option B: Embedded JavaScript transformation
code(( args.map(x => ({ id: x.id, title: x.title })) ))
}
-
Mutual Exclusivity: A transformer can define
jmesPathORcode, but never both. Declaring both will fail validation. -
Automatic Application: Any time the specified
onFunctionOutputfunction is executed, the runtime passes the tool's raw output through the transformer before returning it to the session.
transformer("compact_repo_list") {
onFunctionOutput = "list_repositories"
# Filter to only active repositories and extract name + stars
jmesPath = "[?archived == `false`].{name: name, stars: stargazers_count}"
}
The components block defines shared schema models that can be referenced across multiple sessions. This avoids duplicate schema declarations across complex multi-step pipelines.
components {
schema("ComponentName") {
field_name: type_expr # Field description
opt_field?: type_expr # Optional field
nested_field: {
sub_key: string
}
}
}
Within any session's schema block, reference a declared component by prefixing its name with a dollar sign ($):
session("extract_users") {
schema {
organization: string
members: $ComponentName[] # Array of ComponentName objects
lead: $ComponentName # Single ComponentName object
}
}
components {
schema("Author") {
name: string
email: string
role: admin|contributor|viewer # User permission role
}
schema("DocumentMeta") {
title: string
created_at: string
authors: $Author[]
tags?: string[] # Optional topic tags
}
}
A global call executes a tool function or embedded JavaScript snippet before any session begins. This is commonly used for pre-flight environment checks, database hydration, or fetching authentication tokens.
call("functionName") -> vars:outputVar {
argument_key = argument_value
}
Important
Global file-level call statements MUST define an explicit output target routing (e.g. -> vars:name or the implicit -> name). Omitting the target routing at the file level is a compiler error because there is no ambient session context to receive the output.
parameter("org_id", type=string)
# Fetch customer license before sessions execute
call("fetch_organization_license") -> vars:org_license {
org = "{{ .params.org_id }}"
}
# The variable vars.org_license is now available to all subsequent sessions!
Here is a comprehensive example incorporating all file-level constructs:
# 1. System Persona
system(`You are an automated security and compliance auditor.
Inspect system manifests and identify configuration vulnerabilities.`)
# 2. Input Parameters
parameter("manifest_url", type="string")
parameter("severity_threshold", type="string", default="medium", enum=low|medium|high|critical)
parameter("auto_remediate", type="bool", default=false)
# 3. Global Variables
set audit_version = "2.4.0"
# 4. Tool Requirements
require mcp cloud_security
require collection compliance_rules
# 5. Output Transformer
transformer("filter_rules") {
onFunctionOutput = "query_rules"
jmesPath = "[?severity == 'high' || severity == 'critical']"
}
# 6. Reusable Schemas
components {
schema("Vulnerability") {
cve_id: string
description: string # Plain English explanation
severity: low|medium|high|critical
remediation_steps?: string[]
}
}
# 7. Global PreCall
call("download_manifest") -> vars:raw_manifest {
url = "{{ .params.manifest_url }}"
}
# Sessions begin below...
session("audit_manifest", target="findings") {
# Session implementation
- Audit the manifest for compliance issues.
schema {
manifest_id: string
vulnerabilities: $Vulnerability[]
}
}
FML (Frags Modeling Language) | Getting Started | Cheat Sheet | Examples
Documentation for FML & Gemini Agent Workflows — Maintained by Frags HQ