Skip to content
Merged
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
59 changes: 59 additions & 0 deletions codex-rs/core/src/environment_selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ impl ResolvedTurnEnvironments {
self.primary()
.map(|environment| environment.environment.get_filesystem())
}

pub(crate) fn single_local_environment_cwd(&self) -> Option<&AbsolutePathBuf> {
let [environment] = self.turn_environments.as_slice() else {
return None;
};

(!environment.environment.is_remote()).then_some(&environment.cwd)
}
}

pub(crate) fn resolve_environment_selections(
Expand Down Expand Up @@ -210,4 +218,55 @@ url = "ws://127.0.0.1:8765"
);
assert_eq!(resolved.primary().expect("primary environment").shell, None);
}

#[tokio::test]
async fn single_local_environment_cwd_requires_exactly_one_local_environment() {
let cwd = AbsolutePathBuf::current_dir().expect("cwd");
let local_manager = EnvironmentManager::default_for_tests();
let local = resolve_environment_selections(
&local_manager,
&[TurnEnvironmentSelection {
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
cwd: cwd.clone(),
}],
)
.expect("local environment should resolve");
let remote_manager = EnvironmentManager::create_for_tests(
Some("ws://127.0.0.1:8765".to_string()),
Some(test_runtime_paths()),
)
.await;
let remote = resolve_environment_selections(
&remote_manager,
&[TurnEnvironmentSelection {
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
cwd: cwd.clone(),
}],
)
.expect("remote environment should resolve");
local_manager
.upsert_environment(
REMOTE_ENVIRONMENT_ID.to_string(),
"ws://127.0.0.1:8765".to_string(),
)
.expect("remote environment should register");
let multiple = resolve_environment_selections(
&local_manager,
&[
TurnEnvironmentSelection {
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
cwd: cwd.clone(),
},
TurnEnvironmentSelection {
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
cwd: cwd.clone(),
},
],
)
.expect("multiple environments should resolve");

assert_eq!(local.single_local_environment_cwd(), Some(&cwd));
assert_eq!(remote.single_local_environment_cwd(), None);
assert_eq!(multiple.single_local_environment_cwd(), None);
}
}
4 changes: 3 additions & 1 deletion codex-rs/core/src/session/review.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ pub(super) async fn spawn_review_thread(
client_id: None,
}];
let tc = Arc::new(review_turn_context);
tc.turn_metadata_state.spawn_git_enrichment_task();
if tc.environments.single_local_environment_cwd().is_some() {
tc.turn_metadata_state.spawn_git_enrichment_task();
}
// TODO(ccunningham): Review turns currently rely on `spawn_task` for TurnComplete but do not
// emit a parent TurnStarted. Consider giving review a full parent turn lifecycle
// (TurnStarted + TurnComplete) for consistency with other standalone tasks.
Expand Down
8 changes: 7 additions & 1 deletion codex-rs/core/src/session/turn_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,13 @@ impl Session {
turn_context.final_output_json_schema = final_schema;
}
let turn_context = Arc::new(turn_context);
turn_context.turn_metadata_state.spawn_git_enrichment_task();
if turn_context
.environments
.single_local_environment_cwd()
.is_some()
{
turn_context.turn_metadata_state.spawn_git_enrichment_task();
}
turn_context
}

Expand Down
Loading