Opp repl tasks and results
Composable Anthropic-format Agent Skills for driving OMNeT++ simulations via opp_repl. Works in Claude, Windsurf, and any SKILL.md-aware agent.
npx -y skills add tabgab/opp_repl-skill --skill opp-repl-tasks-and-resultsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
The opp_repl Task/Result object model — SimulationTask, TestTask, UpdateTask, BuildTask, CompareSimulationsTask; result codes (DONE/SKIP/CANCEL/ERROR, PASS/FAIL, KEEP/INSERT/UPDATE, IDENTICAL/DIVERGENT/DIFFERENT); MultipleTaskResults filtering/drill-down/rerun; trajectories (fingerprint & stdout); project-state hashing; and git-bisect for test regressions. Load when you need to inspect, filter, or rerun anything opp_repl has produced.
SKILL.md
8.2 KB, as published. Nobody here has run it
Tasks and task results
Every opp_repl operation is a Task; every task produces a
TaskResult. Batches return a MultipleTaskResults. These
objects are your programmable handle on what the REPL just did.
Upstream references:
- https://github.com/omnetpp/opp_repl/blob/main/doc/tasks.md
- https://github.com/omnetpp/opp_repl/blob/main/doc/task_results.md
Task families
| Family | Base classes | Result codes |
|---|---|---|
| Simulations | SimulationTask / MultipleSimulationTasks | DONE / SKIP / CANCEL / ERROR |
| Tests | TestTask, SimulationTestTask, FingerprintTestTask, SpeedTestTask, StatisticalTestTask, ChartTestTask, SmokeTestTask | PASS / FAIL + simulation codes |
| Updates | UpdateTask, FingerprintUpdateTask, SpeedUpdateTask, StatisticalResultsUpdateTask, ChartUpdateTask | KEEP / INSERT / UPDATE / SKIP / CANCEL / ERROR |
| Builds | BuildTask, MsgCompileTask, CppCompileTask, LinkTask, CopyBinaryTask, BuildSimulationProjectTask | DONE / SKIP (up-to-date) / ERROR |
| Comparisons | CompareSimulationsTask | IDENTICAL / DIVERGENT / DIFFERENT / SKIP / CANCEL / ERROR |
What a SimulationTask carries
simulation_config+run_number-> identifies WHAT to run.mode-> release / debug / sanitize / coverage / profile.- Time limits ->
sim_time_limit,cpu_time_limit; plain strings or callables(config, run_number) -> str. - Runner ->
subprocess(default),opp_env(auto when the project is opp_env-managed),inprocess(CFFI),ide(auto whendebug=Trueor a breakpoint parameter is set). - Output overrides -> stdout / eventlog /
.sca/.vecfile paths. - Knobs ->
record_eventlog,record_pcap,user_interface("Cmdenv"default or"Qtenv"), extrainifile_entries.
Inspecting a SimulationTaskResult
r = run_simulations(config_filter="PureAloha1", sim_time_limit="1s")
t = r.results[0]
t.result_code # e.g. "DONE"
t.expected_result # usually "DONE"
t.is_expected() # actual == expected
t.elapsed_time # wall clock
t.cpu_time, t.cycles, t.instructions # from OMNeT++ CPU summary
t.error_message, t.error_module # when ERROR
t.last_event_number, t.last_simulation_time
t.stdout_file, t.eventlog_file, t.sca_file, t.vec_file
t.used_ned_types # sorted list of NED types instantiated
t.subprocess_result # raw CompletedProcess
t.print_result() # colored one-line summary
t.print_stdout(); t.print_stderr() # captured I/O
t.get_description() # string form
Post-mortem trajectories:
ft = t.get_fingerprint_trajectory() # per-event fingerprint values
st = t.get_stdout_trajectory() # event# <-> stdout lines (regex OK)
Result-data accessors (current opp_repl, >= commit 2e6835e):
df = t.get_scalars() # .sca file as a pandas DataFrame
df = t.get_vectors() # .vec file as a pandas DataFrame
df = t.get_histograms() # histograms from .sca
Signatures:
get_scalars(include_fields=True, include_runattrs=False, **kwargs)
get_vectors(include_runattrs=False, **kwargs)
get_histograms(include_runattrs=False, **kwargs)
See opp-repl-result-analysis for typical aggregation patterns,
filter options, and fallbacks for older opp_repl.
MultipleTaskResults drill-down
r = run_simulations(sim_time_limit="1s")
r.get_done_results()
r.get_error_results()
r.get_unexpected_results() # excludes SKIP/CANCEL
r.get_fail_results() # test-task specific (FAIL)
r.is_all_results_done()
r.is_all_results_expected()
r.filter_results(
result_filter="ERROR",
error_message_filter="Unknown parameter")
Every filter returns a new MultipleTaskResults, so chains compose.
Aggregated result-data accessors
MultipleSimulationTaskResults (current opp_repl) also exposes
the same .get_scalars() / .get_vectors() / .get_histograms()
methods. They concatenate per-run DataFrames across every DONE
result:
r = run_simulations(sim_time_limit="1s")
df = r.get_scalars() # one row per (run, module, name)
df.groupby("name").value.mean() # aggregate across reps
Non-DONE results (SKIP, CANCEL, ERROR, FAIL) contribute nothing —
the method silently skips them. Check r.is_all_results_done()
first if your aggregation looks sparse.
Re-running
Both single and multiple results support .rerun(), optionally with
parameter overrides:
r.rerun() # repeat everything
r.get_error_results().rerun() # only failures
r.results[0].rerun(mode="debug") # one task in debug
.recreate() produces a modified copy of the task without running
it; useful when you want to tweak parameters and inspect before
executing.
Hashing and caching
Every task computes a SHA-256 over its relevant inputs (project state, config, run number, mode, time limits). Higher-level machinery such as fingerprint tests uses these hashes to decide whether a cached baseline is still valid.
Git-bisecting a regression
opp_repl supports bisecting failing tests across git commits. The idea: given a known-good commit and a known-bad commit, the bisect machinery runs the test at each midpoint until the introducing commit is isolated. Use this for fingerprint / statistical / speed regressions where rerun times are feasible.
Treat the bisect helper as a facade over run_*_tests() +
git-checkout; see help(bisect_fingerprint_tests) for the exact
signature. The family of bisect functions is:
bisect_fingerprint_tests, bisect_statistical_tests,
bisect_smoke_tests, bisect_chart_tests, bisect_sanitizer_tests,
bisect_speed_tests, bisect_simulations_between_commits.
Their common signature is e.g.:
bisect_fingerprint_tests(simulation_project, good_hash, bad_hash, update_good_results=True, **kwargs).
The general pattern:
bisect_fingerprint_tests(simulation_project=inet_project,
good_hash="v4.5", bad_hash="HEAD",
config_filter="Vlan",
sim_time_limit="1s")
Pitfalls
-
Test tasks reuse simulation codes plus PASS/FAIL. A PASS test can still have a DONE/ERROR simulation underneath — inspect
.simulation_task_resultwhen a test unexpectedly fails. -
SKIPon simulation = "requires user input / not runnable headless". It is not the same as "build was up-to-date" (which is SKIP on a BuildTask). -
filter_results(error_message_filter=...)is a regex on the parsed error message; include^/$to anchor. -
Reruns inherit the ORIGINAL task's parameters. Override via kwargs:
result.rerun(sim_time_limit="10s"). -
tr.stdout/tr.stderrmay beNoneon ERROR. They are parsed from files the simulation writes (cmdenv-output-file, stderr capture) — if the process died before writing, the fields stayNone. For EVERYERRORresult, go to the raw subprocess output:print(tr.subprocess_result.returncode) print(tr.subprocess_result.stderr) print(tr.subprocess_result.stdout) print(tr.subprocess_result.args) # shows the exact cmd lineSee
opp-repl-troubleshootingfor an exit-code-to-cause table.
See also
opp-repl-concepts— where tasks sit in the hierarchy.opp-repl-running-simulations— creates SimulationTasks.opp-repl-comparing-simulations— CompareSimulationsTask.opp-repl-filtering— filter configs before tasks are created.- Every
opp-repl-*-testsskill — task-family details per test type.