behavior-tree.fbl
fbl0.140.14behavior-tree.fbl
Example document behavior-tree.fbl
Views generated from the file
This view is drawn by this site from behavior-tree.fbl itself. It shows the data in the document, not the notation the diagram draws.
behavior-tree.fbl at 9dec21cDiagram as text (Mermaid)
flowchart LR
accTitle: Bindings of behavior-tree.fbl
accDescr: Flowchart of the bindings in behavior-tree.fbl: 1 binding(s) (abm) as boxes with the files they claim and their body's format family, and 12 element rule(s) and 0 relation rule(s) as rounded boxes with the type each produces.
b_abm["Agent behavior model, Markdown<br/>abm<br/>.md, bullets family"]
e_abm_sequence("sequence<br/>Sequence")
b_abm -->|element| e_abm_sequence
e_abm_fallback("fallback<br/>Fallback")
b_abm -->|element| e_abm_fallback
e_abm_parallel("parallel<br/>Parallel")
b_abm -->|element| e_abm_parallel
e_abm_retry("retry<br/>Retry")
b_abm -->|element| e_abm_retry
e_abm_repeat_until("repeat-until<br/>RepeatUntil")
b_abm -->|element| e_abm_repeat_until
e_abm_guard("guard<br/>Guard")
b_abm -->|element| e_abm_guard
e_abm_approval("approval<br/>Approval")
b_abm -->|element| e_abm_approval
e_abm_check("check<br/>Check")
b_abm -->|element| e_abm_check
e_abm_do("do<br/>Do")
b_abm -->|element| e_abm_do
e_abm_ask_user("ask-user<br/>AskUser")
b_abm -->|element| e_abm_ask_user
e_abm_delegate("delegate<br/>Delegate")
b_abm -->|element| e_abm_delegate
e_abm_implicit_do("implicit-do<br/>Do")
b_abm -->|element| e_abm_implicit_doThe file
Download behavior-tree.fbl (16,742 bytes, unchanged from the source).
{
"$schema": "https://etalii.net/adp/fbl/schema/0.1/fbl.schema.json#/$defs/Document",
"fbl": "0.7",
"doc": "Agent Behavior Modelling's Markdown file format (definitions/diagrams/agent-behavior-modelling.dis and agent-behavior-modelling.md, section The file format) declared as a binding of the bullets family (FBL 0.7, section 4.8). It is a declared reading of that tool's format beside the persistence plugin its specification names: it changes neither the tool type's specification, whose persistence keeps naming agent-behavior-modelling.fbl#abm and the plugin net.etalii.adp.etalii.abmMarkdown, nor any host. The tree is the list items under the first heading Behavior or Behaviour, at any level, case-insensitive. A node is one item, its keyword in bold with the label after it (- **Do in order:** Handle the request), one rule per keyword, read without regard to case, with the colon inside or after the bold. Retry's count is inside its keyword and is the attempts attribute. An item without a keyword is an implicit Do, read by the last rule. Nothing in the Markdown names a node: no rule has an id, so a node's id is the one the specification derives from its place (1, 1.2, 1.2.1). Notes are the item's continuation lines. A nested item is a child of the item it is nested in, whatever that item's type, so the tool's own constraints report a leaf with children and a wrapper with more than one; the containment checks DISL builds in are switched off in the specification. The first node added to a file without the section appends ## Behavior at the end of the file. Everything else in the file, the legend the tool writes into a new file included, is unbound and kept byte for byte. Known differences from the tool's own reader and writer (AbmParser.cs, AbmWriter.cs), which FBL 0.7 cannot state: (1) the tool reads only the first list in the section, ending it at a line in the list's column that is not an item, where this binding reads every item that stands in the section; (2) the tool writes Retry up to 1 time, singular, for a count of one, where this binding writes the count's digits in place and keeps the word that was there, and a new Retry is written with times whatever its count; (3) the tool's notes leave out the trailing whitespace of each line, which the continuation keeps; (4) the tool rewrites a renamed item's whole line in its canonical form (**Keyword:** label, one space after the marker, no space after the bold when the label is empty), where this binding replaces the label alone; (5) the tool ends the section at a heading of its level or higher even inside a list item and indented up to three columns, and closes a fence on any line that starts with the fence's first three characters, where FBL 0.7 reads such a line as an item's continuation, and closes a fence only on a run of the same character with nothing after it; (6) the tool suggests the reading for a Behavior heading in any case, where claims.suggest is a substring and matches # Behavior and # Behaviour as written; (7) the tool does not read an item with no text after its marker, which this binding reads as an implicit Do with an empty label; (8) the tool titles a new file Agent when the name leaves nothing, where the template writes {base}.",
"bindings": {
"abm": {
"title": "Agent behavior model, Markdown",
"claims": {
"extensions": [".md"],
"shared": true,
"registrationOnly": true,
"origins": ["etalii/agent-behavior-modelling"],
"suggest": { "contains": ["# Behavior", "# Behaviour"] }
},
"body": { "kind": "file", "family": "bullets" },
"reader": "declared",
"text": { "newline": "crlf", "indent": 2, "finalNewline": true },
"sections": [
{
"name": "behavior",
"doc": "The first heading whose text is Behavior or Behaviour, at any level; the section ends at the next heading with as many # or fewer.",
"heading": "^Behaviou?r$",
"caseInsensitive": true
}
],
"elements": [
{
"name": "sequence",
"type": "Sequence",
"within": ["behavior"],
"line": "^\\*\\*\\s*Do +in +order\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": { "label": { "group": "label", "empty": "keep" }, "notes": { "continuation": true, "empty": "remove" } },
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Do in order:**[ {label}]"
},
"remove": {}
},
{
"name": "fallback",
"type": "Fallback",
"within": ["behavior"],
"line": "^\\*\\*\\s*Try +in +order\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": { "label": { "group": "label", "empty": "keep" }, "notes": { "continuation": true, "empty": "remove" } },
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Try in order:**[ {label}]"
},
"remove": {}
},
{
"name": "parallel",
"type": "Parallel",
"within": ["behavior"],
"line": "^\\*\\*\\s*Do +together\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": { "label": { "group": "label", "empty": "keep" }, "notes": { "continuation": true, "empty": "remove" } },
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Do together:**[ {label}]"
},
"remove": {}
},
{
"name": "retry",
"type": "Retry",
"doc": "The count is part of the keyword: Retry up to 3 times, Retry up to 1 time. The binding reads either form and writes the count's digits in place; a new Retry is written with times.",
"within": ["behavior"],
"line": "^\\*\\*\\s*Retry +up +to +(?<attempts>\\d{1,6}) +times?\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": {
"label": { "group": "label", "empty": "keep" },
"attempts": { "group": "attempts", "number": "shortest", "empty": "refuse" },
"notes": { "continuation": true, "empty": "remove" }
},
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Retry up to {attempts} times:**[ {label}]"
},
"remove": {}
},
{
"name": "repeat-until",
"type": "RepeatUntil",
"within": ["behavior"],
"line": "^\\*\\*\\s*Repeat +until\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": { "label": { "group": "label", "empty": "keep" }, "notes": { "continuation": true, "empty": "remove" } },
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Repeat until:**[ {label}]"
},
"remove": {}
},
{
"name": "guard",
"type": "Guard",
"within": ["behavior"],
"line": "^\\*\\*\\s*Only +while\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": { "label": { "group": "label", "empty": "keep" }, "notes": { "continuation": true, "empty": "remove" } },
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Only while:**[ {label}]"
},
"remove": {}
},
{
"name": "approval",
"type": "Approval",
"within": ["behavior"],
"line": "^\\*\\*\\s*Ask +approval +before\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": { "label": { "group": "label", "empty": "keep" }, "notes": { "continuation": true, "empty": "remove" } },
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Ask approval before:**[ {label}]"
},
"remove": {}
},
{
"name": "check",
"type": "Check",
"within": ["behavior"],
"line": "^\\*\\*\\s*Check\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": { "label": { "group": "label", "empty": "keep" }, "notes": { "continuation": true, "empty": "remove" } },
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Check:**[ {label}]"
},
"remove": {}
},
{
"name": "do",
"type": "Do",
"within": ["behavior"],
"line": "^\\*\\*\\s*Do\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": { "label": { "group": "label", "empty": "keep" }, "notes": { "continuation": true, "empty": "remove" } },
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Do:**[ {label}]"
},
"remove": {}
},
{
"name": "ask-user",
"type": "AskUser",
"within": ["behavior"],
"line": "^\\*\\*\\s*Ask +the +user\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": { "label": { "group": "label", "empty": "keep" }, "notes": { "continuation": true, "empty": "remove" } },
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Ask the user:**[ {label}]"
},
"remove": {}
},
{
"name": "delegate",
"type": "Delegate",
"within": ["behavior"],
"line": "^\\*\\*\\s*Delegate\\s*(?::\\s*\\*\\*|\\*\\*:?)\\s*(?<label>.*?)\\s*$",
"caseInsensitive": true,
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": { "label": { "group": "label", "empty": "keep" }, "notes": { "continuation": true, "empty": "remove" } },
"insert": {
"place": "last-child",
"container": "behavior",
"create": { "at": "end-of-document", "text": "## Behavior" },
"emit": "**Delegate:**[ {label}]"
},
"remove": {}
},
{
"name": "implicit-do",
"type": "Do",
"doc": "An item with no keyword, or with a bold lead that is none of the eleven (a Retry without a count among them), is a Do labelled with the whole item, and its implicit attribute is true. This rule comes after the keyword rules, so it takes only what none of them took, and every item of the section is read. It has no insert: a Do is added through the rule do, with its keyword.",
"within": ["behavior"],
"line": "^\\s*(?<label>.*?)\\s*$",
"parent": {
"rules": ["sequence", "fallback", "parallel", "retry", "repeat-until", "guard", "approval", "check", "do", "ask-user", "delegate", "implicit-do"],
"slot": "children"
},
"attributes": {
"label": { "group": "label", "empty": "keep" },
"notes": { "continuation": true, "empty": "remove" },
"implicit": { "value": "true" }
},
"remove": {}
}
],
"template": {
"text": "# {base}\r\n\r\nDescribe the agent here: who it works for, and what it is for.\r\n\r\n## How to follow the behavior\r\n\r\nThe behavior below is a behavior tree, and it is your instructions. Start at its first node and work through it from the top. Each list item is a node; the items indented under a node are its children, in order. Every node ends in success or failure, and its parent decides what happens next:\r\n\r\n- **Do in order** runs its children one after another, and fails as soon as one fails.\r\n- **Try in order** tries its children one after another, and succeeds as soon as one succeeds.\r\n- **Do together** runs its children independently, at the same time where you can, and succeeds when all of them succeed.\r\n- **Retry up to N times** runs its child again when it fails, at most N times in all.\r\n- **Repeat until** runs its child again and again until its condition holds.\r\n- **Only while** runs its child only while its condition holds, and abandons it when the condition stops holding.\r\n- **Ask approval before** says what its child is about to do and waits for the user's explicit approval; without it, the node fails.\r\n- **Check** answers its question from the conversation, your memory or a tool result; it succeeds when the answer is yes, and never acts.\r\n- **Do** carries out one piece of work: a tool call, an answer, an edit.\r\n- **Ask the user** asks its question and waits for the answer.\r\n- **Delegate** hands its task to a sub-agent, or follows the behavior file it links to.\r\n\r\nLines under a node that are not list items are notes: follow them while you carry out that node.\r\n\r\n## Behavior\r\n\r\n- **Do in order:** Handle the request\r\n",
"doc": "The tool's new document: a title, one line saying what the file is for, the section that tells the agent how to follow the tree, and the Behavior section with one Do in order."
}
}
}
}In an IDE
No IDE host runs this example yet.