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.
- Interactive editing of rules, scenarios, and facts.
- Template-driven creation of new models.
- Batch-friendly execution with deterministic outputs.
- 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
- Python 3.10 or newer.
- 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:
SESL_STRICT_OPERANDS: require explicit operand types.SESL_STRICT_PATHS: prevent writes to missing structures.SESL_AUTO_CREATE_PATHS: auto-create parent paths.SESL_ERROR_STYLE: fancy or plain errors.SESL_CONFLICT_POLICY: error, warn, or ignore conflicts.
5. Engine configuration
Configuration layers:
- Engine defaults.
- Environment variable overrides.
- Command-line flags.
- Interactive
optionsvalues.
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
- Parse and normalise command text.
- Substitute
%OPTION%tokens. - Licence and safety checks.
- Dispatch to a handler.
- Validate model edits.
- 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:
- Result facts (commonly under result)
- Metrics: iterations, rules evaluated/fired, elapsed ms
- Support data _sesl.support for explainability
- Monitor/trace blocks showing step-by-step reasoning
- Driver trees and “reasons” summaries
- result: your model’s output facts (often nested).
- metrics: iterations, rules evaluated/fired, elapsed ms.
- _sesl.support: per-rule trace (fired?, facts read/written, reason).
- _sesl.monitor: ordered trace lines for step-by-step reasoning.
- _sesl.driver: driver/decision tree summary.
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:
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:
- Use absolute paths to avoid working-directory surprises.
- If the exe isn’t on PATH, reference it directly (as above).
- Check returncode to know if the run succeeded; inspect stderr for errors.
- If SESL outputs files, set cwd in subprocess.run(..., cwd="...") to control where they land.