Files
codex/codex-rs/ext/extension-api/src/user_instructions.rs
T
Adam Perry @ OpenAI 236b50125d [codex] Load user instructions through an injected provider (#27101)
## Why

We want to remove implicit use of `$CODEX_HOME` from `codex-core` and
make embedders responsible for supplying user-level instructions. This
also ensures user instructions load when no primary environment is
selected.

## What changed

Stacked on #27415, which makes `codex exec` surface thread-scoped
runtime warnings.

- Added `UserInstructionsProvider` to `codex-extension-api`, with
absolute source attribution and recoverable loading warnings.
- Added `codex-home` with the filesystem-backed provider for
`AGENTS.override.md` and `AGENTS.md`, preserving precedence, fallback,
trimming, lossy UTF-8 handling, and the existing uncapped global
instruction size.
- Removed global instruction loading from `Config` and require
`ThreadManager` callers to inject a provider.
- Load provider instructions once for each fresh root runtime, including
runtimes without a primary environment. Running sessions retain their
snapshot, while child agents inherit the parent snapshot without
invoking the provider.
- Keep provider instructions separate while loading project `AGENTS.md`,
then assemble the model-visible instructions with the existing ordering,
source attribution, warning, and turn-context behavior.
- Wired the Codex home provider through the CLI, app server, MCP server,
core facade, and thread-manager sample.

## Validation

- `just test -p codex-home -p codex-extension-api`
- `just test -p codex-core agents_md`
- `just test -p codex-core guardian`
- `just test -p codex-app-server
thread_start_without_selected_environment_includes_only_global_instruction_source`
- `just test -p codex-exec warning`
- `just bazel-lock-check`
2026-06-11 19:28:47 +00:00

42 lines
1.6 KiB
Rust

use std::future::Future;
use std::pin::Pin;
use codex_utils_absolute_path::AbsolutePathBuf;
/// User instructions supplied by the host.
///
/// `source` must be an absolute filesystem path because the app-server
/// `instructionSources` API currently exposes instruction sources as
/// `AbsolutePathBuf` values.
// TODO(anp): Replace the absolute path with a more general instruction-source
// abstraction when non-filesystem providers need first-class attribution.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct UserInstructions {
/// Model-visible user instruction text.
pub text: String,
/// Absolute filesystem path reported through `instructionSources`.
pub source: AbsolutePathBuf,
}
/// Result of loading host-provided user instructions.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct LoadedUserInstructions {
/// Loaded instructions, or `None` when the provider has no applicable text.
pub instructions: Option<UserInstructions>,
/// Recoverable loading problems that should be surfaced during startup.
pub warnings: Vec<String>,
}
/// Future returned by a [`UserInstructionsProvider`].
pub type LoadUserInstructionsFuture<'a> =
Pin<Box<dyn Future<Output = LoadedUserInstructions> + Send + 'a>>;
/// Loads the user instructions that apply when a root thread runtime starts.
///
/// Implementations should return any recoverable loading problems as warnings
/// while still returning usable fallback instructions when available.
pub trait UserInstructionsProvider: Send + Sync {
/// Loads the snapshot to use for a newly created root runtime.
fn load_user_instructions(&self) -> LoadUserInstructionsFuture<'_>;
}