LightSOPLang Execution Monitoring

How the interpreter tracks command execution, enforces limits, and how to extend the monitoring hooks.

DefaultExecutionMonitor at a Glance

The interpreter ships with DefaultExecutionMonitor, imported via lightSOPLang/index.mjs. It captures three primary signals:

These hooks give downstream analytics (or tests) visibility into every command attempt, while the limit checks prevent denial-of-service cascades when scripts misbehave.

Custom Monitors

You can pass a custom monitor via the executionMonitor option when constructing LightSOPLangInterpreter. The interpreter validates the monitor with ensureExecutionMonitor, which simply checks for the methods it intends to call:

Any additional state—metrics, tracing, feature flags—is up to the implementer. Because these hooks run synchronously, keep handlers fast and avoid throwing unless you explicitly want to abort execution.

Data Passed to Hooks

The interpreter sends structured data at each step:

Together, these snapshots let monitoring layers reconstruct the narrative of an execution: which commands fired in what order, where it failed, when the LLM took over, and what payload it received.

Practical Limits

The default monitor uses a simple counter to cap command executions (commandLimit) and failure events (failureLimit) per interpreter instance. If your scripts may legitimately exceed these caps—say, iterative planners—provide a monitor with higher thresholds or custom logic (e.g., per-variable quotas). For safety, still consider logging when limits are approached so you can distinguish expected retries from stuck scripts.

Extending Beyond Defaults

Because monitors are plain objects, it is easy to integrate with observability stacks:

Just remember that monitor callbacks run in the same event loop as the interpreter. Keep side effects non-blocking or move heavy work to async tasks.