core: load AGENTS.md from foreign environments (#28958)

## Why

Make it possible to load AGENTS.md from remote exec-servers whose OS is
different than app-server.

## What

- keep `AGENTS.md` discovery and provenance as `PathUri`, with
root-aware parent and ancestor traversal
- expose lifecycle instruction sources as legacy app-server path strings
in events while retaining `PathUri` internally
- preserve and test mixed POSIX and Windows paths in model context and
TUI status output
- cover remote Windows loading end to end by seeding the Wine prefix
through host filesystem APIs
- fix bug in `PathUri`'s parent() implementation that would erase
Windows drive letters
This commit is contained in:
Adam Perry @ OpenAI
2026-06-18 15:06:23 -07:00
committed by GitHub
parent 406062c3af
commit dce673905a
38 changed files with 550 additions and 203 deletions
@@ -1181,7 +1181,7 @@ impl ThreadRequestProcessor {
)
.await?;
let instruction_sources = thread.instruction_sources().await;
let instruction_sources = thread.legacy_instruction_sources().await;
let config_snapshot = thread
.config_snapshot()
.instrument(tracing::info_span!(
@@ -2681,7 +2681,7 @@ impl ThreadRequestProcessor {
self.outgoing.send_error(request_id, err).await;
return Ok(());
}
let instruction_sources = codex_thread.instruction_sources().await;
let instruction_sources = codex_thread.legacy_instruction_sources().await;
let SessionConfiguredEvent { rollout_path, .. } = session_configured;
let Some(rollout_path) = rollout_path else {
let error =
@@ -2989,7 +2989,7 @@ impl ThreadRequestProcessor {
/*include_turns*/ false,
);
thread_summary.session_id = existing_thread.session_configured().session_id.to_string();
let instruction_sources = existing_thread.instruction_sources().await;
let instruction_sources = existing_thread.legacy_instruction_sources().await;
let listener_command_tx = {
let thread_state = thread_state.lock().await;
@@ -3422,7 +3422,7 @@ impl ThreadRequestProcessor {
.map_err(|err| core_thread_write_error("inherit source thread name", err))?;
}
let instruction_sources = forked_thread.instruction_sources().await;
let instruction_sources = forked_thread.legacy_instruction_sources().await;
// Auto-attach a conversation listener when forking a thread.
log_listener_attach_result(
+3 -2
View File
@@ -13,7 +13,7 @@ use codex_protocol::ThreadId;
use codex_protocol::protocol::EventMsg;
use codex_protocol::protocol::RolloutItem;
use codex_rollout::state_db::StateDbHandle;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_path_uri::LegacyAppPathString;
use std::collections::HashMap;
use std::collections::HashSet;
use std::sync::Arc;
@@ -31,7 +31,7 @@ pub(crate) struct PendingThreadResumeRequest {
pub(crate) request_id: ConnectionRequestId,
pub(crate) history_items: Vec<RolloutItem>,
pub(crate) config_snapshot: ThreadConfigSnapshot,
pub(crate) instruction_sources: Vec<AbsolutePathBuf>,
pub(crate) instruction_sources: Vec<LegacyAppPathString>,
pub(crate) thread_summary: codex_app_server_protocol::Thread,
pub(crate) emit_thread_goal_update: bool,
pub(crate) thread_goal_state_db: Option<StateDbHandle>,
@@ -200,6 +200,7 @@ mod tests {
use codex_protocol::config_types::CollaborationMode;
use codex_protocol::config_types::ModeKind;
use codex_protocol::config_types::Settings;
use codex_utils_absolute_path::AbsolutePathBuf;
use pretty_assertions::assert_eq;
#[test]