mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
## Why `codex_core` is consistently a bottleneck for incremental builds during iteration. The simplest fix is to make the crate smaller. ## Summary `codex-core` owns several reusable prompt renderers and static prompt assets, which makes the crate harder to split apart. Rename `codex-review-prompts` to `codex-prompts` and move shared review, goal, permissions, compaction, realtime, hierarchical AGENTS.md, and `apply_patch` prompts into it. Move prompt-only tests and update consumers and `CODEOWNERS`. ## Validation - `just test -p codex-prompts -p codex-apply-patch` - `just test -p codex-core prompt_caching` - Bazel builds for the affected crates
83 lines
2.4 KiB
Rust
83 lines
2.4 KiB
Rust
use codex_prompts::BACKEND_PROMPT;
|
|
const DEFAULT_USER_FIRST_NAME: &str = "there";
|
|
const USER_FIRST_NAME_PLACEHOLDER: &str = "{{ user_first_name }}";
|
|
|
|
pub(crate) fn prepare_realtime_backend_prompt(
|
|
prompt: Option<Option<String>>,
|
|
config_prompt: Option<String>,
|
|
) -> String {
|
|
if let Some(config_prompt) = config_prompt
|
|
&& !config_prompt.trim().is_empty()
|
|
{
|
|
return config_prompt;
|
|
}
|
|
|
|
match prompt {
|
|
Some(Some(prompt)) => return prompt,
|
|
Some(None) => return String::new(),
|
|
None => {}
|
|
}
|
|
|
|
BACKEND_PROMPT
|
|
.trim_end()
|
|
.replace(USER_FIRST_NAME_PLACEHOLDER, ¤t_user_first_name())
|
|
}
|
|
|
|
fn current_user_first_name() -> String {
|
|
[whoami::realname(), whoami::username()]
|
|
.into_iter()
|
|
.filter_map(|name| name.split_whitespace().next().map(str::to_string))
|
|
.find(|name| !name.is_empty())
|
|
.unwrap_or_else(|| DEFAULT_USER_FIRST_NAME.to_string())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::prepare_realtime_backend_prompt;
|
|
|
|
#[test]
|
|
fn prepare_realtime_backend_prompt_prefers_config_override() {
|
|
assert_eq!(
|
|
prepare_realtime_backend_prompt(
|
|
Some(Some("prompt from request".to_string())),
|
|
Some("prompt from config".to_string()),
|
|
),
|
|
"prompt from config"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn prepare_realtime_backend_prompt_uses_request_prompt() {
|
|
assert_eq!(
|
|
prepare_realtime_backend_prompt(
|
|
Some(Some("prompt from request".to_string())),
|
|
/*config_prompt*/ None,
|
|
),
|
|
"prompt from request"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn prepare_realtime_backend_prompt_preserves_empty_request_prompt() {
|
|
assert_eq!(
|
|
prepare_realtime_backend_prompt(Some(Some(String::new())), /*config_prompt*/ None),
|
|
""
|
|
);
|
|
assert_eq!(
|
|
prepare_realtime_backend_prompt(Some(None), /*config_prompt*/ None),
|
|
""
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn prepare_realtime_backend_prompt_renders_default() {
|
|
let prompt =
|
|
prepare_realtime_backend_prompt(/*prompt*/ None, /*config_prompt*/ None);
|
|
|
|
assert!(prompt.starts_with("## Identity, tone, and role"));
|
|
assert!(prompt.contains("You are Codex, an OpenAI general-purpose agentic assistant"));
|
|
assert!(prompt.contains("The user's name is "));
|
|
assert!(!prompt.contains("{{ user_first_name }}"));
|
|
}
|
|
}
|