← Về thư mục
📄 / / profiles / r-and-d / raw_evidence / scientific-agent-skills / skills / simpy / references / cli-guide.md

Bundled CLI guide

Verified 2026-07-23 for skill version 1.1 and SimPy 4.1.2.

The scripts implement one transparent finite-horizon exponential arrival/exponential service multi-server queue. They are examples and diagnostics, not a generic model execution platform.

Safety contract

All scripts:

Run from the repository root after the pinned install:

uv pip install "simpy==4.1.2"

Commands that execute a simulation gate SimPy through a shared dependency loader. If it is absent, they exit without a traceback and print the pinned installation command above. Configuration validation and artifact summarization remain usable without SimPy.

Queue configuration schema

Every field is optional; defaults are shown:

{
  "analysis_mode": "terminating",
  "base_seed": 20260723,
  "horizon": 480.0,
  "max_entities": 10000,
  "max_events": 200000,
  "mean_interarrival": 4.0,
  "mean_service": 6.0,
  "queue_capacity": 20,
  "servers": 2,
  "warm_up": 0.0
}

Semantics:

Bounds:

For analysis_mode="terminating", warm_up must be zero. For analysis_mode="steady_state", warm-up must be positive and less than horizon. This validates consistency only; it does not establish that steady state was reached.

Basic template

python skills/simpy/scripts/basic_simulation_template.py --help
python skills/simpy/scripts/basic_simulation_template.py
python skills/simpy/scripts/basic_simulation_template.py \
  --config queue.json --output run.json

--replication INDEX selects deterministic derived arrival/service seeds. It does not itself create a confidence interval.

Library use:

from basic_simulation_template import QueueConfig, run_simulation

config = QueueConfig.from_mapping({"horizon": 120, "servers": 3})
report = run_simulation(config, replication=0)

Bounded queue scenario and trace

python skills/simpy/scripts/bounded_queue_scenario.py \
  --config queue.json \
  --output scenario.json \
  --trace-output trace.jsonl \
  --trace-max-records 50000

The trace is capped and contains no event repr:

{
  "event_id": 0,
  "event_type": "Initialize",
  "priority": 0,
  "queue_size_before": 1,
  "time": 0.0
}

The .jsonl file has one compact object per line. A trace can truncate while the bounded simulation completes; the report discloses trace.truncated.

Replication configuration schema

{
  "confidence": 0.95,
  "model": {
    "analysis_mode": "terminating",
    "base_seed": 20260723,
    "horizon": 480,
    "max_entities": 10000,
    "max_events": 200000,
    "mean_interarrival": 4,
    "mean_service": 6,
    "queue_capacity": 20,
    "servers": 2,
    "warm_up": 0
  },
  "replications": 20
}

Additional experiment bounds:

python skills/simpy/scripts/replication_runner.py --help
python skills/simpy/scripts/replication_runner.py \
  --config experiment.json --output intervals.json

The runner makes a two-sided Student-t interval from independent replication-level estimates. A metric undefined in any run is marked unavailable instead of dropping that run. It never constructs a CI from individual customers within one run.

The seed manifest uses stable BLAKE2b derivation for separate arrival/service RNG objects. This is deterministic stream separation for the bundled example, not a formal proof of independent substreams. See simulation-methodology.md.

Configuration validator

Validation performs no simulation:

python skills/simpy/scripts/validate_simulation_config.py queue.json
python skills/simpy/scripts/validate_simulation_config.py \
  experiment.json --schema replication

Schemas are queue, replication, or auto. Auto identifies the replication schema by any top-level model, replications, or confidence key. There are no custom model names, module paths, class names, predicates, or callable fields.

Unknown keys such as the following are rejected:

{
  "plugin": "package.module",
  "python": "print('run me')"
}

Event/resource artifact summarizer

Summarize a trace without importing or executing its originating model:

python skills/simpy/scripts/event_trace_summary.py trace.jsonl

Summarize ResourceMonitor CSV:

python skills/simpy/scripts/resource_monitor.py \
  --samples resource.csv --output monitor.json
python skills/simpy/scripts/event_trace_summary.py resource.csv

Accepted trace fields are exactly:

event_id, event_type, priority, queue_size_before, time.

Accepted resource CSV fields are exactly:

time, event, count, queue_length, utilization.

The summarizer checks event trace order by (time, priority, event_id) and computes resource time averages by carrying each state left-continuously to the next sample. It does not infer queue semantics from arbitrary column names.

Resource monitor library

from resource_monitor import EventTraceRecorder, ResourceMonitor

monitor = ResourceMonitor(env, server, "server")
trace = EventTraceRecorder(env, max_records=10_000)
env.run(until=100)
trace.detach()
monitor.finalize(at=100)

print(monitor.summary(start=20, end=100))
monitor.export_csv("resource.csv")
trace.export_jsonl("trace.jsonl")

The monitor patches one resource instance. Do not attach multiple wrappers to the same resource. Its queue timing and private-API caveats are in monitoring.md.

Exit behavior

Expected validation failures use argparse errors and nonzero exit status:

An event-budget error is a failed/incomplete simulation, not a valid censored result. Increase a cap only after diagnosing why it was reached.

Exact pinned tests

PYTHONDONTWRITEBYTECODE=1 uv run --isolated --no-project \
  --python 3.13 --with "simpy==4.1.2" \
  python -m unittest discover -s tests/simpy -v

Tests cover scheduler boundaries, deterministic ties, Conditions, all resource families, preemption causes, monitor time weighting, trace round-trip, config/path safety, hard limits, seed determinism, and Student-t calculations.