Block Format
llmist uses a simple block format that works with any text model. This format uses marker prefixes to delimit gadget calls and their parameters—no native tool calling or structured outputs required.
Basic Structure
Section titled “Basic Structure”A gadget call consists of a start marker, parameters, and an end marker:
!!!GADGET_START:GadgetName!!!ARG:parameter_nameparameter_value!!!ARG:another_paramanother_value!!!GADGET_ENDMarkers
Section titled “Markers”| Marker | Purpose |
|---|---|
!!!GADGET_START:Name | Begins a gadget call with the gadget name |
!!!ARG:pointer | Declares a parameter (value on following line(s)) |
!!!GADGET_END | Ends the gadget call |
Parameter Syntax
Section titled “Parameter Syntax”Parameters use !!!ARG: followed by a JSON Pointer path (without leading /) to specify where to place the value.
Simple Parameters
Section titled “Simple Parameters”!!!ARG:filenamecalculator.ts!!!ARG:languagetypescriptResult: { filename: "calculator.ts", language: "typescript" }
Nested Objects
Section titled “Nested Objects”Use / to create nested structures:
!!!ARG:config/timeout30!!!ARG:config/retries3Result: { config: { timeout: 30, retries: 3 } }
Arrays
Section titled “Arrays”Use numeric indices (0-based):
!!!ARG:items/0first!!!ARG:items/1second!!!ARG:items/2thirdResult: { items: ["first", "second", "third"] }
Arrays of Objects
Section titled “Arrays of Objects”Combine array indices with nested paths:
!!!ARG:users/0/nameAlice!!!ARG:users/0/age25!!!ARG:users/1/nameBob!!!ARG:users/1/age30Result: { users: [{ name: "Alice", age: 25 }, { name: "Bob", age: 30 }] }
Automatic Type Coercion
Section titled “Automatic Type Coercion”Single-line values are automatically coerced to appropriate types:
| Value | Coerced Type | Result |
|---|---|---|
true | boolean | true |
false | boolean | false |
42 | number | 42 |
3.14 | number | 3.14 |
-17 | number | -17 |
hello | string | "hello" |
| (multiline) | string | preserved as-is |
Multiline Values
Section titled “Multiline Values”Multiline content is preserved exactly as written:
!!!ARG:codefunction hello() { console.log("Hello, World!"); return { key: "value" };}!!!ARG:filenameexample.ts- Internal newlines are preserved
- A single trailing newline is stripped
- Great for code, documentation, or any multi-line content
Dependencies
Section titled “Dependencies”Gadgets can specify dependencies on other gadgets using invocation IDs. This enables DAG (Directed Acyclic Graph) execution: independent gadgets run in parallel, dependent gadgets wait.
Syntax
Section titled “Syntax”!!!GADGET_START:GadgetName:invocation_id:dep1,dep2| Component | Required | Description |
|---|---|---|
GadgetName | Yes | Name of the gadget to call |
invocation_id | Optional | Unique ID for this call (auto-generated if omitted) |
dep1,dep2 | Optional | Comma-separated IDs this gadget depends on |
Example
Section titled “Example”!!!GADGET_START:FetchData:fetch_users!!!ARG:url/api/users!!!GADGET_END
!!!GADGET_START:FetchData:fetch_orders!!!ARG:url/api/orders!!!GADGET_END
!!!GADGET_START:MergeData:merge_all:fetch_users,fetch_orders!!!ARG:formatjson!!!GADGET_ENDIn this example:
fetch_usersandfetch_ordersexecute in parallel (no dependencies)merge_allwaits for both to complete before executing- If
fetch_usersfails,merge_allis automatically skipped
Customizing Markers
Section titled “Customizing Markers”You can customize the marker prefixes if needed:
await LLMist.createAgent() .withGadgetStartPrefix('<<<START:') .withGadgetEndPrefix('<<<END:') .withGadgetArgPrefix('@param:') .ask('...');This would expect:
<<<START:FloppyDisk@param:filenameDOOM.ZIP@param:megabytes50<<<END:Implicit Termination
Section titled “Implicit Termination”The end marker (!!!GADGET_END) is optional. A gadget block terminates when:
- An explicit
!!!GADGET_ENDis encountered - A new
!!!GADGET_START:begins (implicit termination) - The stream ends (finalization)
This allows streaming parsers to handle incomplete or truncated responses gracefully.
Error Handling
Section titled “Error Handling”The parser reports errors for:
- Duplicate pointers: Same path specified twice in one gadget
- Array index gaps: Non-sequential array indices (e.g.,
items/0thenitems/5) - Invalid array indices: Negative or non-numeric indices
Parse errors are captured in the parseError field while parametersRaw preserves the original text for debugging.
EBNF Grammar Reference
Section titled “EBNF Grammar Reference”For implementers, here’s the formal grammar:
(* Top-level structure *)gadget_block = start_marker , header_line , newline , parameters , [ end_marker ] ;
(* Markers - these are configurable *)start_marker = START_PREFIX ; (* default: "!!!GADGET_START:" *)end_marker = END_PREFIX ; (* default: "!!!GADGET_END" *)arg_prefix = ARG_PREFIX ; (* default: "!!!ARG:" *)
(* Header line: gadget name with optional ID and dependencies *)header_line = gadget_name , [ ":" , invocation_id , [ ":" , dependencies ] ] ;gadget_name = identifier ;invocation_id = identifier ;dependencies = identifier , { "," , identifier } ;
(* Parameters section: zero or more argument definitions *)parameters = { parameter } ;parameter = arg_prefix , pointer , newline , value ;
(* JSON Pointer path (without leading /) for nested structures *)pointer = segment , { "/" , segment } ;segment = identifier | array_index ;array_index = digit , { digit } ;
(* Value: all text until next arg_prefix or end_marker *)value = { any_character } ;
(* Basic tokens *)identifier = letter_or_underscore , { letter_or_underscore | digit } ;letter_or_underscore = letter | "_" ;letter = "A" | "B" | ... | "Z" | "a" | "b" | ... | "z" ;digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;newline = LF ;any_character = (* any Unicode character *) ;See Also
Section titled “See Also”- Creating Gadgets - Full guide to gadget creation
- Gadget Examples - Common gadget patterns
- CLI Reference - Command-line usage