fix(runtime): isolate agent state by project (#101)

This commit is contained in:
2026-07-25 22:14:02 +02:00
parent 6a87c4635f
commit 6e98fd89f7
52 changed files with 1894 additions and 805 deletions

View File

@ -1174,7 +1174,7 @@ fn seed_live_agent_session(
size,
);
session.status = domain::SessionStatus::Running;
sessions.insert(PtyHandle { session_id }, session);
sessions.insert_in_project(project().id, PtyHandle { session_id }, session);
}
fn nid(n: u128) -> domain::NodeId {
@ -1220,7 +1220,7 @@ async fn launch_new_in_other_cell_refuses_when_agent_live_elsewhere() {
// No silent move, no respawn, registry untouched.
assert_eq!(
sessions.node_for_agent(&agent.id),
sessions.node_for_agent_in_project(project().id, &agent.id),
Some(host),
"session stays pinned on its host node"
);
@ -1309,7 +1309,10 @@ async fn launch_other_cell_with_conversation_id_rebinds_no_respawn() {
assert_eq!(out.session.id, sid(42), "returns the existing session");
assert_eq!(out.session.node_id, target, "view rebound to target cell");
assert_eq!(sessions.node_for_agent(&agent.id), Some(target));
assert_eq!(
sessions.node_for_agent_in_project(project().id, &agent.id),
Some(target)
);
assert_eq!(sessions.len(), before, "registry size is unchanged");
assert!(pty.spawns().is_empty(), "no PTY spawn on explicit reattach");
}
@ -1328,7 +1331,9 @@ async fn launch_succeeds_after_session_removed() {
// Live, then removed (close/exit).
seed_live_agent_session(&sessions, agent.id, nid(1), sid(42));
sessions.remove(&sid(42));
assert!(sessions.session_for_agent(&agent.id).is_none());
assert!(sessions
.session_for_agent_in_project(project().id, &agent.id)
.is_none());
let mut input = launch_input(agent.id);
input.node_id = Some(nid(2));