[apps] Add gated instructions for Apps. (#10924)

- [x] Add gated instructions for Apps.
This commit is contained in:
Matthew Zeng
2026-02-09 14:48:09 -08:00
committed by GitHub
parent ed977dbeda
commit d90df4761b
6 changed files with 111 additions and 0 deletions

View File

@@ -16,6 +16,7 @@ use codex_core::auth::AuthCredentialsStoreMode;
use codex_core::built_in_model_providers;
use codex_core::default_client::originator;
use codex_core::error::CodexErr;
use codex_core::features::Feature;
use codex_core::models_manager::manager::ModelsManager;
use codex_core::protocol::EventMsg;
use codex_core::protocol::Op;
@@ -666,6 +667,77 @@ async fn includes_user_instructions_message_in_request() {
assert_message_ends_with(&request_body["input"][2], "</environment_context>");
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn includes_apps_guidance_as_developer_message_when_enabled() {
skip_if_no_network!();
let server = MockServer::start().await;
let resp_mock = mount_sse_once(
&server,
sse(vec![ev_response_created("resp1"), ev_completed("resp1")]),
)
.await;
let mut builder = test_codex()
.with_auth(CodexAuth::from_api_key("Test API Key"))
.with_config(|config| {
config.features.enable(Feature::Apps);
});
let codex = builder
.build(&server)
.await
.expect("create new conversation")
.codex;
codex
.submit(Op::UserInput {
items: vec![UserInput::Text {
text: "hello".into(),
text_elements: Vec::new(),
}],
final_output_json_schema: None,
})
.await
.unwrap();
wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await;
let request = resp_mock.single_request();
let request_body = request.body_json();
let input = request_body["input"].as_array().expect("input array");
let apps_snippet = "Apps are mentioned in the prompt in the format";
let has_developer_apps_guidance = input.iter().any(|item| {
item.get("role").and_then(|value| value.as_str()) == Some("developer")
&& item
.get("content")
.and_then(|value| value.as_array())
.and_then(|value| value.first())
.and_then(|value| value.get("text"))
.and_then(|value| value.as_str())
.is_some_and(|text| text.contains(apps_snippet))
});
assert!(
has_developer_apps_guidance,
"expected apps guidance in a developer message, got {input:#?}"
);
let has_user_apps_guidance = input.iter().any(|item| {
item.get("role").and_then(|value| value.as_str()) == Some("user")
&& item
.get("content")
.and_then(|value| value.as_array())
.and_then(|value| value.first())
.and_then(|value| value.get("text"))
.and_then(|value| value.as_str())
.is_some_and(|text| text.contains(apps_snippet))
});
assert!(
!has_user_apps_guidance,
"did not expect apps guidance in user messages, got {input:#?}"
);
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn skills_append_to_instructions() {
skip_if_no_network!();