Skip to content

DSL β€” Usage Guide

πŸ”‘ Key Concepts

The DSL is how you program Trigger Blocks. Instead of using menus or long settings forms, you write a short, readable rule that says:

  • On β†’ what event should trigger
  • If β†’ an optional condition to check
  • Do β†’ one or more actions the trigger should perform
  • Emit β†’ optional outputs that are passed into the workflow

Every rule written in the DSL is directly connected to a tool. That means:

  • Events come from the tool (e.g. "email_received", "page_created").
  • Variables are pieces of data provided by the tool (e.g. subject, filepath, page_id).
  • Capabilities (actions) are what the tool can do (e.g. save_artifacts, set_variable, index_document).
  • Emits define what the workflow should output to the next step (commonly query=...).

πŸ“˜ Key Definitions

  • Event: The trigger that starts the rule. Always defined by the tool.
  • Predicate (if …): A condition written with functions like not_empty(x) or contains(str, 'abc').
  • Action (do …): A step that uses a capability from the tool. Each action has a name and parameters.
  • Emit: Key-value outputs produced after the actions. Used for passing data or queries into the workflow.

🧩 Parsing (Beta)

Every tool in INTELLITHING comes with its own capabilities, variables, types, and hints. To make working with them easier, the parser at the bottom of the tool’s rule configuration lets you create rules using natural language instead of learning the full syntax.

Here’s how it works:

  1. Review the tool’s documentation to understand its capabilities and variables.
  2. Type your desired rule in plain natural language.
  3. Click Parse.
  4. The system will generate a fully executable rule for you.

This means you don’t need to memorize each tool’s syntax. Instead, you can write naturally, and the parser will convert it into a valid, execution-ready rule.

πŸ’‘ Tip: Use the parser to get started quickly, then fine-tune the generated rule if you need more control.

πŸ“ Rule Syntax

The general form of a rule is:

on <event> [if <predicate>] do <action>(param=value, ...) [, <action>(...)] [emit key=value, ...]
  • on β€” required. Must be one of the tool’s supported events.
  • if β€” optional. Condition that decides whether the rule should run.
  • do β€” required. One or more actions, separated by commas.
  • emit β€” optional. Defines query text or payload for downstream blocks.

πŸš€ Example

Let's say we picked gmail tool and want to create a rule

The tool offers the following which can be found in its documentaion.

⛔️ These are all tool specific

Events offered by this particular tool

  • email_received
  • email_sent

Pick one. Your rule only runs when that event occurs.

Variables offered by this particular tool

Available for predicates and templates:

  • subject (string) – Email subject
  • from (string) – Sender
  • to (string) – Recipient(s)
  • cc (string) – CC addresses
  • body (string) – Body snippet (up to \~2k chars)
  • attachments (array) – List of attachments (each has filename, mime, size, data)
  • has_attachments (bool) – Convenience flag
  • id (string) – Message id
  • date (string, YYYY-MM-DD) – Email date
  • event (string) – Event subtype
  • saved_paths (array) – Paths written by save_artifacts
  • filepath (string) – First saved path (set by save_artifacts)

Template tokens offered by this particular tool

Resolved by the Gmail tool when you render templates:

  • {yyyy}, {mm}, {dd} – Current UTC date parts
  • {event} – Current event
  • {subject_slug} – Slug from email subject
  • {attachment_name} – Slug from the current attachment’s filename

You can mix these with regular DSL placeholders like {subject} or {attachments[0].filename]}.

Capabilities (actions you can call in do ...)

  1. save_artifacts β€” Persist all attachments to disk using templates. Params:

  2. dir_template (string)

  3. filename_template (string)
  4. base_dir (string)
  5. decode_base64 (boolean)

Produces:

  • saved_paths (array), filepath (string)
  • If multiple files are saved, it also creates per-item emissions with {"filepath": "...", "query": "This is the file path: ..."}
  • If exactly one file is saved, it sets a top-level query to "This is the file path: <path>"

  • set_variable β€” Set/override a variable from a template. Params (required):

  • name (string)

  • value_template (string)

Produces:

  • (none directly; it returns {name: rendered_value})

Predicates you can use in if ...

Use simple boolean functions such as:

  • not_empty(x), empty(x)
  • contains(str, 'needle'), startswith(s, 'p'), endswith(s, 's')
  • equals(a, b)
  • len_gt(x, n), len_lt(x, n), len_eq(x, n)
  • Combine with and, or, not, and parentheses.

Bringing it together

Goal: When a new email with attachments arrives, save all attachments into a dated folder structure and make those file paths available to the workflow. Also set a handy variable for downstream steps and produce a human-readable query.

Rule:

on email_received if not_empty(attachments)
do save_artifacts(
       base_dir='workspace/archive/',
       dir_template='gmail/{yyyy}-{mm}-{dd}/',
       filename_template='{subject_slug}-{attachment_name}'
   ),
   set_variable(name='latest_file', value_template='{filepath}')
emit query='Saved attachment(s). First file: {latest_file}'

What this does

  1. Trigger Runs on email_received only.

  2. Filter (if …) not_empty(attachments) ensures we only act when the email actually has attachments.

  3. Action 1 β€” save_artifacts(...)

  4. Where files go

  5. base_dir='workspace/archive/' β†’ everything is rooted here.

  6. dir_template='gmail/{yyyy}-{mm}-{dd}/' β†’ daily folder like workspace/archive/gmail/2025-08-23/.
  7. How files are named

  8. filename_template='{subject_slug}-{attachment_name}' β†’ slugified subject + slugified original filename (the adapter provides both tokens).

  9. Outputs

  10. Sets saved_paths (array) for all saved files.

  11. Sets filepath to the first saved file path.
  12. If there are multiple attachments, the action also returns per-file emissions with a ready-made query for each item ("This is the file path: <path>").
  13. If there is only one attachment, it sets a top-level query with that text.

  14. Action 2 β€” set_variable(...)

  15. Creates/updates latest_file with the value of {filepath} (the first saved path from the prior action).

  16. This is convenient for downstream blocks to refer to β€œthe first file” without re-indexing arrays.

  17. Emit

  18. Emits a final query for the workflow: Saved attachment(s). First file: {latest_file}

  19. If save_artifacts produced per-item emissions (multiple attachments), your workflow will also receive those itemized emissions, each with its own filepath and query. The workflow can fan-out or iterate as designed.

Resulting data available to downstream blocks

  • latest_file β€” path to the first saved file
  • filepath β€” same as above (from save_artifacts)
  • saved_paths β€” list of all saved paths
  • query β€” the rule-level summary you emitted
  • For multi-file emails: a list of emissions each containing filepath and a per-item query

Authoring Checklist

  • Pick an event: email_received or email_sent.
  • Narrow with a predicate (optional): e.g., not_empty(attachments).
  • Choose actions from this tool only:

  • save_artifacts(...) (dir/file templates; optional base dir; optional base64 decode)

  • set_variable(name, value_template)
  • Use templates inside params and emit:

  • Regular variables: {subject}, {from}, {attachments[0].filename]}

  • Gmail adapter tokens: {yyyy}, {mm}, {dd}, {subject_slug}, {attachment_name}
  • Emit a concise query (and/or additional key/value pairs) your workflow can display or pass along.

Tips & Pitfalls for this particular example

  • No attachments? Predicate should guard the action: use if not_empty(attachments) to avoid a no-op.
  • Multiple attachments: Expect per-item emissions from save_artifacts with per-file queries.
  • Single attachment: A top-level query is set by save_artifacts; you can still override/augment with your own emit.
  • Won’t overwrite with empty values: set_variable skips replacing an existing non-empty value with an empty string.
  • Date tokens are UTC-based for {yyyy}, {mm}, {dd}.
  • Processed once: The connector marks processed messages as seen to avoid reprocessing on later intervals.

Summary

  • DSL is how you program trigger blocks to start workflows.
  • Each tool defines events, variables, and capabilities in its own doc section.
  • The DSL stitches them together with the pattern:
on β†’ if β†’ do β†’ emit