Six fields produced by SimulationConfigGenerator never reach the simulation. Every claim below
resolves to a path:line on b5b53acc and can be checked with grep alone — no need to run
anything.
The six fields
| field |
written by generator |
rendered in UI |
read by any runner |
scheduled_events |
yes (hardcoded to []) |
no |
no |
narrative_direction |
yes |
yes |
no |
stance |
yes (per agent) |
yes |
no |
sentiment_bias |
yes (per agent) |
yes |
no |
recency_weight |
yes |
yes |
no |
echo_chamber_strength |
yes |
yes |
no |
git grep -nw -E "scheduled_events|narrative_direction|stance|sentiment_bias|recency_weight|echo_chamber_strength" b5b53acc -- backend/scripts/
# (no output)
The three runners — run_reddit_simulation.py, run_twitter_simulation.py and
run_parallel_simulation.py — have zero occurrences of any of them. This is not a limitation of
the Reddit path: no path consumes them.
What run_reddit_simulation.py actually reads from the config is four keys that drive the
simulation — llm_model (:450), time_config (:478), agent_configs (:479) and
event_config.initial_posts (:592-593) — plus simulation_id, echoed to the log at :532.
scheduled_events is the starkest case, and it maps to a README promise
The README advertises:
You can inject variables dynamically from a "God's-eye view"
That is what scheduled_events is for. It exists in exactly two places in the whole repository:
git grep -nw scheduled_events b5b53acc
b5b53acc:backend/app/services/simulation_config_generator.py:121: scheduled_events: List[Dict[str, Any]] = field(default_factory=list)
b5b53acc:backend/app/services/simulation_config_generator.py:725: scheduled_events=[],
:121 is the dataclass field. :725 is _parse_event_config overwriting whatever the model
returned with a hardcoded empty list — so the generator does not even populate it. And unlike the
other five, it has no binding in the frontend at all: it is generated, discarded, and never shown.
The event-config prompt does not ask for it either (simulation_config_generator.py:696-705 asks
only for hot_topics, narrative_direction, initial_posts and reasoning).
The mechanism to deliver it already exists
initial_posts is published through ManualAction(action_type=ActionType.CREATE_POST) in a single
env.step() before the round loop (run_reddit_simulation.py:597-620), and the loop starts right
after at :626 (Twitter is symmetric: :612-627 and :633).
A scheduled event is the same publication, fired from inside the loop at its target round. Nothing
new needs inventing.
I have this implemented and tested and am happy to open a PR — see the end.
Notes on the other five, so the issue is accurate rather than tidy
These are not all the same case, and I would rather say so than round them into one bullet:
-
stance / sentiment_bias have a natural destination: the free-text persona field, composed
in oasis_profile_generator.py:721 and :770. But it is currently unreachable —
SimulationManager.prepare_simulation generates the profiles (around simulation_manager.py:357)
before it generates the simulation_config.json that holds the per-agent stances
(around :425-443). At persona-building time the value does not exist yet. Fixing that means reordering
the pipeline, which felt like the maintainers' call rather than an outside PR — so I left it out.
-
recency_weight does have a real counterpart downstream: calculate_hot_score
(oasis/social_platform/recsys.py) already weights recency through a seconds / 45000 term, with
45000 hardcoded. But recsys.py lives in camel-oasis==0.2.5 (backend/requirements.txt:22),
a pinned PyPI dependency, not in this repo — so wiring it would be a PR to camel-ai/oasis, not here.
-
echo_chamber_strength has nowhere to live under recsys_type='reddit': that recommender is
pure hot score (likes − dislikes + time), with no notion of similarity, affinity or clustering. The
only cosine-similarity path is twitter/twhin-bert. Removing it, or scoping it to the twitter
path, seems more honest than wiring it.
Worth noting: recsys_type and max_rec_post_len have zero occurrences in this repository —
MiroFish never configures the recommender at all, it takes whatever OASIS defaults to.
A separate defect found while testing: simulation processes never exit
Not part of the six fields, but it surfaced on stock code and seems worth reporting:
simulation_runner.py:517-525 builds the spawn command as [python, script, --config, path]
plus optionally --max-rounds. --no-wait is never passed.
run_reddit_simulation.py:710-713 — --no-wait defaults to False.
run_reddit_simulation.py:732 — wait_for_commands=not args.no_wait, therefore always True
for any simulation started through the API.
simulation_runner.py:641 — the monitor thread runs while process.poll() is None: ... sleep(2),
waiting for an exit that never comes, so its finalization block is never reached.
The only way out is an explicit POST /api/simulation/stop; no natural-completion path calls it.
Every API-started simulation therefore leaves its process resident, holding the whole OASIS
environment, until something stops it.
Happy to split this into its own issue if you prefer.
Offer
I have scheduled_events implemented end to end on top of b5b53acc — generator prompt, parser,
agent assignment shared with initial_posts, and both runners — with unit tests, and verified on a
clean checkout. With an empty list the execution path is identical to today, so existing configs are
unaffected.
One design question I would rather ask than assume: should the trigger be the round number, or the
simulated clock time? I used round, because it is what the generator can reason about and what
the loop already indexes, but the time config would allow "at simulated hour N" instead. Happy to
follow whichever you prefer before opening the PR.
I am also aware of #573, which adds a Narrative Layer with a "God Mode" inject_event. That one
explicitly targets the prose layer and lists "Mid-sim OASIS prompt injection" among its non-goals, so
the two are complementary rather than overlapping — this would give #573's God Mode something real to
push into, if that is ever wanted.
Six fields produced by
SimulationConfigGeneratornever reach the simulation. Every claim belowresolves to a
path:lineonb5b53accand can be checked withgrepalone — no need to runanything.
The six fields
scheduled_events[])narrative_directionstancesentiment_biasrecency_weightecho_chamber_strengthThe three runners —
run_reddit_simulation.py,run_twitter_simulation.pyandrun_parallel_simulation.py— have zero occurrences of any of them. This is not a limitation ofthe Reddit path: no path consumes them.
What
run_reddit_simulation.pyactually reads from the config is four keys that drive thesimulation —
llm_model(:450),time_config(:478),agent_configs(:479) andevent_config.initial_posts(:592-593) — plussimulation_id, echoed to the log at:532.scheduled_eventsis the starkest case, and it maps to a README promiseThe README advertises:
That is what
scheduled_eventsis for. It exists in exactly two places in the whole repository::121is the dataclass field.:725is_parse_event_configoverwriting whatever the modelreturned with a hardcoded empty list — so the generator does not even populate it. And unlike the
other five, it has no binding in the frontend at all: it is generated, discarded, and never shown.
The event-config prompt does not ask for it either (
simulation_config_generator.py:696-705asksonly for
hot_topics,narrative_direction,initial_postsandreasoning).The mechanism to deliver it already exists
initial_postsis published throughManualAction(action_type=ActionType.CREATE_POST)in a singleenv.step()before the round loop (run_reddit_simulation.py:597-620), and the loop starts rightafter at
:626(Twitter is symmetric::612-627and:633).A scheduled event is the same publication, fired from inside the loop at its target round. Nothing
new needs inventing.
I have this implemented and tested and am happy to open a PR — see the end.
Notes on the other five, so the issue is accurate rather than tidy
These are not all the same case, and I would rather say so than round them into one bullet:
stance/sentiment_biashave a natural destination: the free-textpersonafield, composedin
oasis_profile_generator.py:721and:770. But it is currently unreachable —SimulationManager.prepare_simulationgenerates the profiles (aroundsimulation_manager.py:357)before it generates the
simulation_config.jsonthat holds the per-agent stances(around
:425-443). At persona-building time the value does not exist yet. Fixing that means reorderingthe pipeline, which felt like the maintainers' call rather than an outside PR — so I left it out.
recency_weightdoes have a real counterpart downstream:calculate_hot_score(
oasis/social_platform/recsys.py) already weights recency through aseconds / 45000term, with45000hardcoded. Butrecsys.pylives incamel-oasis==0.2.5(backend/requirements.txt:22),a pinned PyPI dependency, not in this repo — so wiring it would be a PR to
camel-ai/oasis, not here.echo_chamber_strengthhas nowhere to live underrecsys_type='reddit': that recommender ispure hot score (likes − dislikes + time), with no notion of similarity, affinity or clustering. The
only cosine-similarity path is
twitter/twhin-bert. Removing it, or scoping it to the twitterpath, seems more honest than wiring it.
Worth noting:
recsys_typeandmax_rec_post_lenhave zero occurrences in this repository —MiroFish never configures the recommender at all, it takes whatever OASIS defaults to.
A separate defect found while testing: simulation processes never exit
Not part of the six fields, but it surfaced on stock code and seems worth reporting:
simulation_runner.py:517-525builds the spawn command as[python, script, --config, path]plus optionally
--max-rounds.--no-waitis never passed.run_reddit_simulation.py:710-713—--no-waitdefaults toFalse.run_reddit_simulation.py:732—wait_for_commands=not args.no_wait, therefore alwaysTruefor any simulation started through the API.
simulation_runner.py:641— the monitor thread runswhile process.poll() is None: ... sleep(2),waiting for an exit that never comes, so its finalization block is never reached.
The only way out is an explicit
POST /api/simulation/stop; no natural-completion path calls it.Every API-started simulation therefore leaves its process resident, holding the whole OASIS
environment, until something stops it.
Happy to split this into its own issue if you prefer.
Offer
I have
scheduled_eventsimplemented end to end on top ofb5b53acc— generator prompt, parser,agent assignment shared with
initial_posts, and both runners — with unit tests, and verified on aclean checkout. With an empty list the execution path is identical to today, so existing configs are
unaffected.
One design question I would rather ask than assume: should the trigger be the round number, or the
simulated clock time? I used
round, because it is what the generator can reason about and whatthe loop already indexes, but the time config would allow "at simulated hour N" instead. Happy to
follow whichever you prefer before opening the PR.
I am also aware of #573, which adds a Narrative Layer with a "God Mode"
inject_event. That oneexplicitly targets the prose layer and lists "Mid-sim OASIS prompt injection" among its non-goals, so
the two are complementary rather than overlapping — this would give #573's God Mode something real to
push into, if that is ever wanted.