mirror of
https://github.com/openai/codex.git
synced 2026-04-30 01:16:54 +00:00
Honor null thread instructions (#16964)
- Treat explicit null thread instructions as a blank-slate override while preserving omitted-field fallback behavior. - Preserve null through rollout resume/fork and keep explicit empty strings distinct. - Add app-server v2 start/fork coverage for the tri-state instruction params.
This commit is contained in:
@@ -23,4 +23,5 @@ pub mod plan_tool;
|
||||
pub mod protocol;
|
||||
pub mod request_permissions;
|
||||
pub mod request_user_input;
|
||||
mod serde_helpers;
|
||||
pub mod user_input;
|
||||
|
||||
@@ -48,6 +48,8 @@ use crate::plan_tool::UpdatePlanArgs;
|
||||
use crate::request_permissions::RequestPermissionsEvent;
|
||||
use crate::request_permissions::RequestPermissionsResponse;
|
||||
use crate::request_user_input::RequestUserInputResponse;
|
||||
use crate::serde_helpers::deserialize_double_option;
|
||||
use crate::serde_helpers::serialize_double_option;
|
||||
use crate::user_input::UserInput;
|
||||
use codex_git_utils::GitSha;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
@@ -2332,7 +2334,7 @@ impl InitialHistory {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_base_instructions(&self) -> Option<BaseInstructions> {
|
||||
pub fn get_base_instructions(&self) -> Option<Option<BaseInstructions>> {
|
||||
// TODO: SessionMeta should (in theory) always be first in the history, so we can probably only check the first item?
|
||||
match self {
|
||||
InitialHistory::New => None,
|
||||
@@ -2540,7 +2542,13 @@ pub struct SessionMeta {
|
||||
/// base_instructions for the session. This *should* always be present when creating a new session,
|
||||
/// but may be missing for older sessions. If not present, fall back to rendering the base_instructions
|
||||
/// from ModelsManager.
|
||||
pub base_instructions: Option<BaseInstructions>,
|
||||
#[serde(
|
||||
default,
|
||||
deserialize_with = "deserialize_double_option",
|
||||
serialize_with = "serialize_double_option",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub base_instructions: Option<Option<BaseInstructions>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub dynamic_tools: Option<Vec<DynamicToolSpec>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
||||
23
codex-rs/protocol/src/serde_helpers.rs
Normal file
23
codex-rs/protocol/src/serde_helpers.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use serde::Deserialize;
|
||||
use serde::Deserializer;
|
||||
use serde::Serialize;
|
||||
use serde::Serializer;
|
||||
|
||||
pub fn deserialize_double_option<'de, T, D>(deserializer: D) -> Result<Option<Option<T>>, D::Error>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
serde_with::rust::double_option::deserialize(deserializer)
|
||||
}
|
||||
|
||||
pub fn serialize_double_option<T, S>(
|
||||
value: &Option<Option<T>>,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
T: Serialize,
|
||||
S: Serializer,
|
||||
{
|
||||
serde_with::rust::double_option::serialize(value, serializer)
|
||||
}
|
||||
Reference in New Issue
Block a user