mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
6a1ddfc366
## Summary - set the realtime v2 server VAD silence delay to 500ms - update the default realtime 1.5 backend prompt to the v4 text - keep the session payload and prompt rendering tests aligned with those changes ## Why - the VAD change gives the voice path a longer pause before ending the user's turn - the prompt change makes the default bundled realtime prompt match the current v4 content ## Validation - `cargo +1.93.0 test -p codex-core realtime_prompt --manifest-path /tmp/codex-realtime-v2-vad-prompt-v4/codex-rs/Cargo.toml` - `CARGO_TARGET_DIR=/tmp/codex-pr-v4-target cargo +1.93.0 test -p codex-api realtime_v2_session_update_includes_background_agent_tool_and_handoff_output_item --manifest-path /tmp/codex-realtime-v2-vad-prompt-v4/codex-rs/Cargo.toml` - `CARGO_TARGET_DIR=/tmp/codex-pr-v4-target cargo +1.93.0 test -p codex-app-server --test all 'suite::v2::realtime_conversation::realtime_webrtc_start_emits_sdp_notification' --manifest-path /tmp/codex-realtime-v2-vad-prompt-v4/codex-rs/Cargo.toml -- --exact`
83 lines
2.5 KiB
Rust
83 lines
2.5 KiB
Rust
const BACKEND_PROMPT: &str = include_str!("../templates/realtime/backend_prompt.md");
|
|
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 }}"));
|
|
}
|
|
}
|