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:
Ahmed Ibrahim authored and GitHub committed 2026-04-07 04:10:19 +00:00
1 parent 4bb507d2c4
commit 24c598e8a9
39 files changed
+550 -101

No files matched your search

+2 -2
View File
@@ -81,7 +81,7 @@ pub enum RolloutRecorderParams {
conversation_id: ThreadId,
forked_from_id: Option<ThreadId>,
source: SessionSource,
base_instructions: BaseInstructions,
base_instructions: Option<BaseInstructions>,
dynamic_tools: Vec<DynamicToolSpec>,
event_persistence_mode: EventPersistenceMode,
},
@@ -110,7 +110,7 @@ impl RolloutRecorderParams {
conversation_id: ThreadId,
forked_from_id: Option<ThreadId>,
source: SessionSource,
base_instructions: BaseInstructions,
base_instructions: Option<BaseInstructions>,
dynamic_tools: Vec<DynamicToolSpec>,
event_persistence_mode: EventPersistenceMode,
) -> Self {
+2 -2
View File
@@ -73,7 +73,7 @@ async fn recorder_materializes_only_after_explicit_persist() -> std::io::Result<
thread_id,
/*forked_from_id*/ None,
SessionSource::Exec,
BaseInstructions::default(),
Some(BaseInstructions::default()),
Vec::new(),
EventPersistenceMode::Limited,
),
@@ -166,7 +166,7 @@ async fn metadata_irrelevant_events_touch_state_db_updated_at() -> std::io::Resu
thread_id,
/*forked_from_id*/ None,
SessionSource::Cli,
BaseInstructions::default(),
Some(BaseInstructions::default()),
Vec::new(),
EventPersistenceMode::Limited,
),
+2 -5
View File
@@ -977,7 +977,7 @@ async fn test_get_thread_contents() {
}
#[tokio::test]
async fn test_base_instructions_missing_in_meta_defaults_to_null() {
async fn test_base_instructions_missing_in_meta_stays_missing() {
let temp = TempDir::new().unwrap();
let home = temp.path();
@@ -1011,10 +1011,7 @@ async fn test_base_instructions_missing_in_meta_defaults_to_null() {
.await
.expect("session meta head");
let first = head.first().expect("first head entry");
assert_eq!(
first.get("base_instructions"),
Some(&serde_json::Value::Null)
);
assert_eq!(first.get("base_instructions"), None);
}
#[tokio::test]