Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions backend/app/api/sentiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,12 @@ def inject_event(campaign_id: str):
custom_prompt=body.get("custom_prompt"),
timeout=float(body.get("timeout", 60.0)),
)
# `result` carries its own success flag (e.g. the sim environment was
# unreachable) without raising — propagate it instead of always
# reporting HTTP success, which previously let the UI show "Event
# injected successfully" for injections that silently did nothing.
if not result.get("success"):
return jsonify({"success": False, "result": result, "error": result.get("error")}), 502
return jsonify({"success": True, "result": result})
except ValueError as e:
return jsonify({"success": False, "error": str(e)}), 404
Expand Down
32 changes: 25 additions & 7 deletions backend/app/services/campaign_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,11 +596,17 @@ def inject_scenario_event(
prompt=prompt,
timeout=timeout,
)
if scenario.lower() == "b":
campaign.scenario_b_injected = True
else:
campaign.scenario_c_injected = True
self._save(campaign)
# Only mark the scenario as injected if the interview actually
# reached agents. `interview_all_agents` doesn't raise when the
# environment is unreachable — it returns success=False — so
# checking only for exceptions here previously let a silent no-op
# be recorded as a successful injection.
if result.get("success"):
if scenario.lower() == "b":
campaign.scenario_b_injected = True
else:
campaign.scenario_c_injected = True
self._save(campaign)
return result
except Exception as e:
logger.error(f"Event injection failed for Scenario {scenario}: {e}")
Expand Down Expand Up @@ -809,24 +815,36 @@ def _execute_pending_injections(
f"Executing staggered injection tier={tier} round={current_round} "
f"sim={sim_id}: {prompt[:60]}..."
)
succeeded = False
try:
SimulationRunner.interview_all_agents(
result = SimulationRunner.interview_all_agents(
simulation_id=sim_id,
prompt=prompt,
timeout=30.0,
)
succeeded = bool(result.get("success"))
if not succeeded:
logger.warning(
f"Staggered injection tier={tier} reported failure (non-fatal): "
f"{result.get('error')}"
)
except Exception as e:
logger.warning(f"Staggered injection tier={tier} failed (non-fatal): {e}")

# Mark this tier attempted either way so we don't retry it forever,
# but only a *successful* tier counts toward the scenario being
# considered "injected".
inj["done"] = True
inj["succeeded"] = succeeded
executed_any = True
executed_scenarios.add(inj.get("scenario"))

if executed_any:
for scenario in executed_scenarios:
if not scenario:
continue
if all(i["done"] for i in campaign.pending_injections if i.get("scenario") == scenario):
scenario_injections = [i for i in campaign.pending_injections if i.get("scenario") == scenario]
if all(i["done"] for i in scenario_injections) and any(i.get("succeeded") for i in scenario_injections):
if scenario == "b":
campaign.scenario_b_injected = True
elif scenario == "c":
Expand Down
Loading
Loading