prediction: push the bulk of the main event loop into the session impl finally

This commit is contained in:
2026-06-17 20:12:58 +02:00
parent cbf7cbd1dd
commit a8a44dae63
+68 -58
View File
@@ -44,7 +44,8 @@ struct Session {
scenery: Scenery,
tokens_consumed: usize,
activity_notify: watch::Sender<bool>,
scene_sink: watch::Sender<Scene>
scene_sink: watch::Sender<Scene>,
do_regen: bool
}
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
@@ -83,10 +84,70 @@ impl Session {
direction,
tokens_consumed: 0,
activity_notify,
scene_sink
scene_sink,
do_regen: false
}
}
async fn commit(&mut self) {
let save_data = SaveData {
direction: self.direction.clone(),
messages: self.messages.clone(),
scenery: self.scenery.clone()
};
save_data.save();
if self.do_regen {
self.regenerate_options().await;
}
}
async fn on_event(&mut self, evt: PredictionAction) {
self.do_regen = match evt {
PredictionAction::ConversationAppend(msg) => {
let do_regen = match msg {
ConversationEntry::Eva(_) | ConversationEntry::ShipComputer(_) | ConversationEntry::User(_) => true,
_ => false
};
self.insert_conversation(msg);
do_regen
},
PredictionAction::SetPlaylist(playlist_name) => {
let args = MixxxQuery { playlist_name };
match MixxxDB.query(&args).await {
Err(err) => log::info!("Failed to load mixxx playlist: {:?}.", err),
Ok(playlist) => {
self.scenery.current_playlist = vec![];
for item in playlist.clone() {
if let Contents::Track(as_track) = item.contents() {
self.scenery.current_playlist.push(as_track.clone());
}
self.scenery.artifacts.insert(item);
}
self.scenery.artifacts.synchronize().await;
self.direction.playlist = args.playlist_name;
log::info!("Mixxx playlist reloaded.");
}
}
false
},
PredictionAction::GeneratePredictions => {
true
},
PredictionAction::SetNarrative(narrative) => {
self.direction.narrative = narrative;
log::info!("Updated stage direction narrative");
true
},
PredictionAction::SetShowEndTime(end_time) => {
self.direction.end_time = end_time;
false
}
};
}
async fn tool_stage_event(&mut self, args: StageEventArgs) -> ToolResults {
let msg = match args.event {
StageEvent::ShipComputer(text) => ConversationEntry::ShipComputer(text),
@@ -139,6 +200,7 @@ impl Session {
}
async fn regenerate_options(&mut self) {
self.do_regen = false;
self.reply_options.responses.clear();
self.refresh();
self.activity_notify.send_if_modified(|x| { if !*x { *x = true; true } else { false }});
@@ -332,62 +394,10 @@ pub async fn start_prediction(saved_session: SaveData, mut messages: tokio::sync
tokio::spawn(async move {
loop {
if let Some(evt) = action_src.recv().await {
let mut session = shared_session.write().await;
let do_regen = match evt {
PredictionAction::ConversationAppend(msg) => {
let do_regen = match msg {
ConversationEntry::Eva(_) | ConversationEntry::ShipComputer(_) | ConversationEntry::User(_) => true,
_ => false
};
session.insert_conversation(msg);
do_regen
},
PredictionAction::SetPlaylist(playlist_name) => {
let args = MixxxQuery { playlist_name };
match MixxxDB.query(&args).await {
Err(err) => log::info!("Failed to load mixxx playlist: {:?}.", err),
Ok(playlist) => {
session.scenery.current_playlist = vec![];
for item in playlist.clone() {
if let Contents::Track(as_track) = item.contents() {
session.scenery.current_playlist.push(as_track.clone());
}
session.scenery.artifacts.insert(item);
}
session.scenery.artifacts.synchronize().await;
session.direction.playlist = args.playlist_name;
log::info!("Mixxx playlist reloaded.");
}
}
false
},
PredictionAction::GeneratePredictions => {
true
},
PredictionAction::SetNarrative(narrative) => {
session.direction.narrative = narrative;
log::info!("Updated stage direction narrative");
true
},
PredictionAction::SetShowEndTime(end_time) => {
session.direction.end_time = end_time;
false
}
};
let save_data = SaveData {
direction: session.direction.clone(),
messages: session.messages.clone(),
scenery: session.scenery.clone()
};
save_data.save();
if do_regen {
drop(session);
shared_session.write().await.regenerate_options().await;
}
shared_session.write().await.on_event(evt).await;
// Commit in a separate unlock operation, so the logging task has time to write messages into the conversation
// FIXME: The conversation we see in the UI really needs to go to another task.
shared_session.write().await.commit().await;
}
}
});