SESL logo light
Login

SESL CLI User Guide

A complete guide to the SESL command line: online mode, batch mode, file execution, configuration, and troubleshooting.

1. Introduction

The SESL CLI is the primary tool for loading, inspecting, editing, validating, and running SESL models. It works with the same models used by the engine and provides rich tracing, linting, and automation features.

  1. Interactive editing of rules, scenarios, and facts.
  2. Template-driven creation of new models.
  3. Batch-friendly execution with deterministic outputs.
  4. Full traces, driver trees, and monitor output for explainability.

2. Operating modes

2.1 Online mode

Interactive shell with completion, prompts, and live updates.

sesl --online
sesl

2.2 Batch mode

Non-interactive execution with automatic confirmations, ideal for CI and scripts.

sesl --batch "LOAD model.sesl; RUN DESCRIBE"

2.3 File-execution mode

Loads and runs a SESL file directly.

sesl model.sesl

3. Installation and requirements

  1. Python 3.10 or newer.
  2. Required libraries: YAML parser, colour support.

Install from PyPI (replace with your package name if different):

pip install sesl

Quick check:

sesl --online

4. Start-up and environment

Environment variables can override defaults:

  1. SESL_STRICT_OPERANDS: require explicit operand types.
  2. SESL_STRICT_PATHS: prevent writes to missing structures.
  3. SESL_AUTO_CREATE_PATHS: auto-create parent paths.
  4. SESL_ERROR_STYLE: fancy or plain errors.
  5. SESL_CONFLICT_POLICY: error, warn, or ignore conflicts.

5. Engine configuration

Configuration layers:

  1. Engine defaults.
  2. Environment variable overrides.
  3. Command-line flags.
  4. Interactive options values.

Key flags:

--strict-operands     # enforce operand typing
--strict-paths        # disallow missing parents
--auto-create-paths   # create missing parents
--conflict-policy warn|error
--error-style fancy|plain
--max-iter 50         # limit forward chaining passes

6. Command lifecycle

  1. Parse and normalise command text.
  2. Substitute %OPTION% tokens.
  3. Licence and safety checks.
  4. Dispatch to a handler.
  5. Validate model edits.
  6. Print coloured output and traces.

7. Command reference

7.1 File and model

LOAD model.sesl           # load and validate
SAVE model.sesl           # save current model
NEW                       # start empty model
NEW template.seslt        # create from template with %OPTION% substitutions
DIR                       # list SESL files
CD path/to/dir            # change working directory

7.2 Metadata

ADD META key=value
META DELETE key

7.3 Listing

LIST                      # summary
LIST ALL                  # full YAML
LIST RULE rule_name
LIST SCENARIO scenario
LIST FACT scenario
LIST FACT ALL

7.4 Copy

COPY MODEL new_name
COPY RULE old [new]
COPY SCENARIO old [new]
COPY FACT scenario [newScenario]

7.5 Facts editing

ADD FACT Scenario1 key.path=value
ADD FACT Scenario1            # prompts for multiline YAML until END
DELETE FACT Scenario1 key.path

7.6 Rule editing

ADD RULE                     # inline or multiline YAML
DELETE RULE rule_name

7.7 Scenario editing

ADD SCENARIO Name            # optionally with YAML body
DELETE SCENARIO Name

7.8 Execution

RUN                          # run all scenarios
RUN DESCRIBE                 # full trace/monitor
RUN SCENARIO Name            # single scenario
RUN SCENARIO Name DESCRIBE
RUN DRIVER                   # driver tree summary
RUN REASON                   # rule firing reasons

7.9 Linting

LINT
LINT ERRORS
LINT WARNINGS

7.10 Options & colour

OPTIONS                      # list saved options
OPTIONS key=value            # persist option
OPTIONS DELETE key
COLOUR ON | COLOUR OFF

8. Dot-path editing

Use dot-paths to target nested structures; list indices expand automatically:

ADD FACT Scenario1 person.address.street="High Road"
ADD FACT Scenario1 items.0.name="Apple"

9. YAML merging

Merge inline or multiline YAML into a scenario:

ADD FACT ScenarioA { income: 50000, debts: 12000 }

ADD FACT ScenarioA
income: 50000
expenses:
  utilities: 200
  food: 150
END

10. Output structure

From the SESL CLI guide (guides/CLI_User_Guide.html, section “Output structure”), a batch run emits:

  1. Result facts (commonly under result)
  2. Metrics: iterations, rules evaluated/fired, elapsed ms
  3. Support data _sesl.support for explainability
  4. Monitor/trace blocks showing step-by-step reasoning
  5. Driver trees and “reasons” summaries
  6. If you run something like sesl --batch "LOAD model.sesl; RUN DESCRIBE" and capture stdout/stderr you would recieve output similar to below. It’s representative JSON-style text you’ll see on stdout (or an emitted file if you redirect):

    
    {
      "result": {
        "decision": "approve",
        "score": 0.82,
        "limits": { "max_amount": 25000 }
      },
      "metrics": {
        "iterations": 3,
        "rules_evaluated": 42,
        "rules_fired": 7,
        "elapsed_ms": 124
      },
      "_sesl": {
        "support": [
          {
            "rule": "eligibility.check_age",
            "fired": true,
            "facts_read": ["applicant.age"],
            "facts_written": ["eligibility.age_ok"],
            "reason": "age >= 21"
          },
          {
            "rule": "decision.finalize",
            "fired": true,
            "facts_read": ["eligibility.*", "risk.score"],
            "facts_written": ["result.decision", "result.score"],
            "reason": "risk.score >= 0.7 and eligibility.ok"
          }
        ],
        "monitor": [
          "RUN SCENARIO Demo",
          "TRACE: eligibility.check_age fired",
          "TRACE: decision.finalize fired"
        ],
        "driver": [
          { "node": "eligibility", "status": "ok" },
          { "node": "decision", "status": "approve", "score": 0.82 }
        ]
      }
    }
    

    Typical keys to expect:

    1. result: your model’s output facts (often nested).
    2. metrics: iterations, rules evaluated/fired, elapsed ms.
    3. _sesl.support: per-rule trace (fired?, facts read/written, reason).
    4. _sesl.monitor: ordered trace lines for step-by-step reasoning.
    5. _sesl.driver: driver/decision tree summary.

12. Calling SESL from Python

You can launch the SESL dist exe with --batch from Python using subprocess. On Windows, pass the args as a list to avoid quoting issues.Example (synchronous, capture output):


import subprocess
from pathlib import Path

SESL_EXE = Path(r"C:\path\to\dist\sesl.exe")  # update to your dist exe
MODEL = Path(r"C:\path\to\model.sezl")       # update to your model file

cmd = [str(SESL_EXE), "--batch", str(MODEL)]

result = subprocess.run(
    cmd,
    capture_output=True,
    text=True,
    check=False  # set True to raise on non-zero exit
)

print("returncode:", result.returncode)
print("stdout:", result.stdout)
print("stderr:", result.stderr)          
          

If --batch expects additional flags (e.g., output file, format), add them in the list, e.g.:


cmd = [str(SESL_EXE), "--batch", str(MODEL), "--out", "results.json"]

Async variant (if you need it):


import asyncio
from pathlib import Path

async def run_sesl():
    cmd = [r"C:\path\to\dist\sesl.exe", "--batch", r"C:\path\to\model.sezl"]
    proc = await asyncio.create_subprocess_exec(
        *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
    )
    stdout, stderr = await proc.communicate()
    print("returncode:", proc.returncode)
    print("stdout:", stdout.decode())
    print("stderr:", stderr.decode())

asyncio.run(run_sesl())

Quick tips:

  1. Use absolute paths to avoid working-directory surprises.
  2. If the exe isn’t on PATH, reference it directly (as above).
  3. Check returncode to know if the run succeeded; inspect stderr for errors.
  4. If SESL outputs files, set cwd in subprocess.run(..., cwd="...") to control where they land.