Split world state settings by topic

This commit is contained in:
pakrym-oai
2026-06-20 20:08:21 -07:00
parent 93c115ee50
commit 5d25a63b07
10 changed files with 426 additions and 320 deletions

View File

@@ -0,0 +1,40 @@
use super::WorldStateSection;
use super::developer_message;
use crate::context::CollaborationModeInstructions;
use crate::context::ContextualUserFragment;
use crate::session::turn_context::TurnContext;
use codex_protocol::config_types::CollaborationMode;
use codex_protocol::models::ResponseItem;
use codex_protocol::protocol::TurnContextItem;
#[derive(Debug, Default)]
pub(crate) struct CollaborationModeState {
baseline: Option<Option<CollaborationMode>>,
enabled: bool,
}
impl CollaborationModeState {
pub(crate) fn from_turn_context(turn_context: &TurnContext) -> Self {
Self {
baseline: Some(Some(turn_context.collaboration_mode.clone())),
enabled: turn_context.config.include_collaboration_mode_instructions,
}
}
pub(crate) fn from_turn_context_item(turn_context_item: &TurnContextItem) -> Self {
Self {
baseline: Some(turn_context_item.collaboration_mode.clone()),
enabled: false,
}
}
}
impl WorldStateSection for CollaborationModeState {
fn render_diff(&self, previous: &Self) -> Option<ResponseItem> {
if !self.enabled || self.baseline == previous.baseline {
return None;
}
CollaborationModeInstructions::from_collaboration_mode(self.baseline.as_ref()?.as_ref()?)
.map(|instructions| developer_message(instructions.render()))
}
}

View File

@@ -1,14 +1,35 @@
mod collaboration_mode;
mod environment;
mod settings;
mod model;
mod multi_agent_mode;
mod permissions;
mod personality;
mod realtime;
use codex_protocol::models::ContentItem;
use codex_protocol::models::ResponseItem;
use indexmap::IndexMap;
use std::any::Any;
use std::any::TypeId;
use std::fmt;
pub(crate) use collaboration_mode::CollaborationModeState;
pub(crate) use environment::EnvironmentsState;
pub(crate) use settings::SettingsState;
pub(crate) use model::ModelState;
pub(crate) use multi_agent_mode::MultiAgentModeState;
pub(crate) use permissions::PermissionsState;
pub(crate) use personality::PersonalityState;
pub(crate) use realtime::RealtimeState;
fn developer_message(text: String) -> ResponseItem {
ResponseItem::Message {
id: None,
role: "developer".to_string(),
content: vec![ContentItem::InputText { text }],
phase: None,
metadata: None,
}
}
trait ErasedWorldStateSection: Send + Sync {
fn as_any(&self) -> &dyn Any;
@@ -67,7 +88,8 @@ impl WorldState {
}
pub(crate) fn render_diff(&self, previous: &Self) -> Vec<ResponseItem> {
self.sections
let section_items = self
.sections
.iter()
.filter_map(|(type_id, section)| {
let previous = previous
@@ -76,6 +98,29 @@ impl WorldState {
.map(|section| section.as_any());
section.render_diff(previous)
})
.collect()
.collect::<Vec<_>>();
let mut items = Vec::with_capacity(section_items.len());
for item in section_items {
match (items.last_mut(), item) {
(
Some(ResponseItem::Message {
id: None,
role: previous_role,
content: previous_content,
phase: None,
metadata: None,
}),
ResponseItem::Message {
id: None,
role,
content,
phase: None,
metadata: None,
},
) if *previous_role == role => previous_content.extend(content),
(_, item) => items.push(item),
}
}
items
}
}

View File

@@ -0,0 +1,44 @@
use super::WorldStateSection;
use super::developer_message;
use crate::context::ContextualUserFragment;
use crate::context::ModelSwitchInstructions;
use crate::session::turn_context::TurnContext;
use codex_protocol::models::ResponseItem;
#[derive(Debug, Default)]
pub(crate) struct ModelState {
model: Option<String>,
instructions: String,
}
impl ModelState {
pub(crate) fn from_turn_context(turn_context: &TurnContext) -> Self {
Self {
model: Some(turn_context.model_info.slug.clone()),
instructions: turn_context
.model_info
.get_model_instructions(turn_context.personality),
}
}
pub(crate) fn from_previous_model(model: Option<&str>) -> Self {
Self {
model: model.map(str::to_string),
instructions: String::new(),
}
}
pub(crate) fn rendered_diff(&self, previous: &Self) -> Option<String> {
let previous_model = previous.model.as_ref()?;
if self.model.as_ref() == Some(previous_model) || self.instructions.is_empty() {
return None;
}
Some(ModelSwitchInstructions::new(&self.instructions).render())
}
}
impl WorldStateSection for ModelState {
fn render_diff(&self, previous: &Self) -> Option<ResponseItem> {
self.rendered_diff(previous).map(developer_message)
}
}

View File

@@ -0,0 +1,52 @@
use super::WorldStateSection;
use super::developer_message;
use crate::context::ContextualUserFragment;
use crate::context::MultiAgentModeInstructions;
use crate::session::multi_agents;
use crate::session::turn_context::TurnContext;
use codex_features::Feature;
use codex_protocol::config_types::MultiAgentMode;
use codex_protocol::models::ResponseItem;
use codex_protocol::protocol::TurnContextItem;
#[derive(Debug, Default)]
pub(crate) struct MultiAgentModeState(Option<Option<MultiAgentMode>>);
impl MultiAgentModeState {
pub(crate) fn from_turn_context(turn_context: &TurnContext) -> Self {
Self(Some(multi_agents::effective_multi_agent_mode(
turn_context.multi_agent_version,
&turn_context.config.multi_agent_v2,
&turn_context.session_source,
turn_context.multi_agent_mode,
turn_context
.config
.features
.enabled(Feature::MultiAgentMode),
)))
}
pub(crate) fn from_turn_context_item(turn_context_item: &TurnContextItem) -> Self {
Self(Some(turn_context_item.multi_agent_mode))
}
}
impl WorldStateSection for MultiAgentModeState {
fn render_diff(&self, previous: &Self) -> Option<ResponseItem> {
let previous_mode = previous.0.as_ref()?;
let current_mode = self.0.as_ref()?;
if current_mode == previous_mode {
return None;
}
let mode = match current_mode {
Some(mode) => *mode,
None if *previous_mode == Some(MultiAgentMode::Proactive) => {
MultiAgentMode::ExplicitRequestOnly
}
None => return None,
};
Some(developer_message(
MultiAgentModeInstructions::new(mode).render(),
))
}
}

View File

@@ -0,0 +1,74 @@
use super::WorldStateSection;
use super::developer_message;
use crate::context::ContextualUserFragment;
use crate::context::PermissionsInstructions;
use crate::session::turn_context::TurnContext;
use codex_execpolicy::Policy;
use codex_features::Feature;
use codex_protocol::models::PermissionProfile;
use codex_protocol::models::ResponseItem;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::TurnContextItem;
#[derive(Debug, PartialEq)]
struct PermissionValues {
permission_profile: PermissionProfile,
approval_policy: AskForApproval,
}
#[derive(Debug, Default)]
pub(crate) struct PermissionsState {
values: Option<PermissionValues>,
rendered: Option<String>,
}
impl PermissionsState {
pub(crate) fn from_turn_context(turn_context: &TurnContext, exec_policy: &Policy) -> Self {
let rendered = turn_context
.config
.include_permissions_instructions
.then(|| {
PermissionsInstructions::from_permission_profile(
&turn_context.permission_profile,
turn_context.approval_policy.value(),
turn_context.config.approvals_reviewer,
exec_policy,
#[allow(deprecated)]
&turn_context.cwd,
turn_context
.config
.features
.enabled(Feature::ExecPermissionApprovals),
turn_context
.config
.features
.enabled(Feature::RequestPermissionsTool),
)
.render()
});
Self {
values: Some(PermissionValues {
permission_profile: turn_context.permission_profile(),
approval_policy: turn_context.approval_policy.value(),
}),
rendered,
}
}
pub(crate) fn from_turn_context_item(turn_context_item: &TurnContextItem) -> Self {
Self {
values: Some(PermissionValues {
permission_profile: turn_context_item.permission_profile(),
approval_policy: turn_context_item.approval_policy,
}),
rendered: None,
}
}
}
impl WorldStateSection for PermissionsState {
fn render_diff(&self, previous: &Self) -> Option<ResponseItem> {
let rendered = self.rendered.as_ref()?;
(self.values != previous.values).then(|| developer_message(rendered.clone()))
}
}

View File

@@ -0,0 +1,60 @@
use super::WorldStateSection;
use super::developer_message;
use crate::context::ContextualUserFragment;
use crate::context::PersonalitySpecInstructions;
use crate::session::turn_context::TurnContext;
use codex_protocol::config_types::Personality;
use codex_protocol::models::ResponseItem;
use codex_protocol::openai_models::ModelInfo;
use codex_protocol::protocol::TurnContextItem;
#[derive(Debug, Default)]
pub(crate) struct PersonalityState {
enabled: bool,
model: Option<String>,
personality: Option<Personality>,
spec: Option<String>,
}
impl PersonalityState {
pub(crate) fn from_turn_context(turn_context: &TurnContext, enabled: bool) -> Self {
let personality = turn_context.personality;
Self {
enabled,
model: Some(turn_context.model_info.slug.clone()),
personality,
spec: personality
.and_then(|personality| Self::message(&turn_context.model_info, personality)),
}
}
pub(crate) fn from_turn_context_item(turn_context_item: &TurnContextItem) -> Self {
Self {
enabled: false,
model: Some(turn_context_item.model.clone()),
personality: turn_context_item.personality,
spec: None,
}
}
pub(crate) fn message(model_info: &ModelInfo, personality: Personality) -> Option<String> {
model_info
.model_messages
.as_ref()
.and_then(|spec| spec.get_personality_message(Some(personality)))
.filter(|message| !message.is_empty())
}
}
impl WorldStateSection for PersonalityState {
fn render_diff(&self, previous: &Self) -> Option<ResponseItem> {
if !self.enabled || self.model != previous.model || self.personality == previous.personality
{
return None;
}
self.personality?;
self.spec
.as_ref()
.map(|spec| developer_message(PersonalitySpecInstructions::new(spec).render()))
}
}

View File

@@ -0,0 +1,60 @@
use super::WorldStateSection;
use super::developer_message;
use crate::context::ContextualUserFragment;
use crate::context::RealtimeEndInstructions;
use crate::context::RealtimeStartInstructions;
use crate::context::RealtimeStartWithInstructions;
use crate::session::turn_context::TurnContext;
use codex_protocol::models::ResponseItem;
#[derive(Debug, Default)]
pub(crate) struct RealtimeState {
active: Option<bool>,
active_fallback: Option<bool>,
start_instructions: Option<String>,
}
impl RealtimeState {
pub(crate) fn from_turn_context(turn_context: &TurnContext) -> Self {
Self {
active: Some(turn_context.realtime_active),
active_fallback: None,
start_instructions: turn_context
.config
.experimental_realtime_start_instructions
.clone(),
}
}
pub(crate) fn from_previous(active: Option<bool>, active_fallback: Option<bool>) -> Self {
Self {
active,
active_fallback,
start_instructions: None,
}
}
pub(crate) fn rendered_diff(&self, previous: &Self) -> Option<String> {
match (previous.active, self.active.unwrap_or(false)) {
(Some(true), false) => Some(RealtimeEndInstructions::new("inactive").render()),
(Some(false), true) | (None, true) => Some(
if let Some(instructions) = self.start_instructions.as_deref() {
RealtimeStartWithInstructions::new(instructions).render()
} else {
RealtimeStartInstructions.render()
},
),
(Some(true), true) | (Some(false), false) => None,
(None, false) => previous
.active_fallback
.filter(|active| *active)
.map(|_| RealtimeEndInstructions::new("inactive").render()),
}
}
}
impl WorldStateSection for RealtimeState {
fn render_diff(&self, previous: &Self) -> Option<ResponseItem> {
self.rendered_diff(previous).map(developer_message)
}
}

View File

@@ -1,303 +0,0 @@
use super::WorldStateSection;
use crate::context::CollaborationModeInstructions;
use crate::context::ContextualUserFragment;
use crate::context::ModelSwitchInstructions;
use crate::context::MultiAgentModeInstructions;
use crate::context::PermissionsInstructions;
use crate::context::PersonalitySpecInstructions;
use crate::context::RealtimeEndInstructions;
use crate::context::RealtimeStartInstructions;
use crate::context::RealtimeStartWithInstructions;
use crate::session::PreviousTurnSettings;
use crate::session::multi_agents;
use crate::session::turn_context::TurnContext;
use codex_execpolicy::Policy;
use codex_features::Feature;
use codex_protocol::config_types::CollaborationMode;
use codex_protocol::config_types::MultiAgentMode;
use codex_protocol::config_types::Personality;
use codex_protocol::models::ContentItem;
use codex_protocol::models::PermissionProfile;
use codex_protocol::models::ResponseItem;
use codex_protocol::openai_models::ModelInfo;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::TurnContextItem;
#[derive(Debug, PartialEq)]
struct PermissionValues {
permission_profile: PermissionProfile,
approval_policy: AskForApproval,
}
#[derive(Debug, Default)]
pub(crate) struct SettingsState {
model: Option<String>,
model_instructions: String,
permissions: Option<PermissionValues>,
permissions_rendered: Option<String>,
// The outer option tracks whether a baseline exists; the inner option is the effective mode.
collaboration_mode: Option<Option<CollaborationMode>>,
collaboration_mode_enabled: bool,
multi_agent_mode: Option<Option<MultiAgentMode>>,
realtime_active: Option<bool>,
realtime_active_fallback: Option<bool>,
realtime_start_instructions: Option<String>,
personality_enabled: bool,
personality_model: Option<String>,
personality: Option<Personality>,
personality_spec: Option<String>,
}
impl SettingsState {
pub(crate) fn from_turn_context(
turn_context: &TurnContext,
exec_policy: &Policy,
personality_enabled: bool,
) -> Self {
let permissions_rendered =
turn_context
.config
.include_permissions_instructions
.then(|| {
PermissionsInstructions::from_permission_profile(
&turn_context.permission_profile,
turn_context.approval_policy.value(),
turn_context.config.approvals_reviewer,
exec_policy,
#[allow(deprecated)]
&turn_context.cwd,
turn_context
.config
.features
.enabled(Feature::ExecPermissionApprovals),
turn_context
.config
.features
.enabled(Feature::RequestPermissionsTool),
)
.render()
});
let model = turn_context.model_info.slug.clone();
let personality = turn_context.personality;
Self {
model: Some(model.clone()),
model_instructions: turn_context.model_info.get_model_instructions(personality),
permissions: Some(PermissionValues {
permission_profile: turn_context.permission_profile(),
approval_policy: turn_context.approval_policy.value(),
}),
permissions_rendered,
collaboration_mode: Some(Some(turn_context.collaboration_mode.clone())),
collaboration_mode_enabled: turn_context.config.include_collaboration_mode_instructions,
multi_agent_mode: Some(multi_agents::effective_multi_agent_mode(
turn_context.multi_agent_version,
&turn_context.config.multi_agent_v2,
&turn_context.session_source,
turn_context.multi_agent_mode,
turn_context
.config
.features
.enabled(Feature::MultiAgentMode),
)),
realtime_active: Some(turn_context.realtime_active),
realtime_active_fallback: None,
realtime_start_instructions: turn_context
.config
.experimental_realtime_start_instructions
.clone(),
personality_enabled,
personality_model: Some(model),
personality,
personality_spec: personality.and_then(|personality| {
Self::personality_message(&turn_context.model_info, personality)
}),
}
}
pub(crate) fn from_turn_context_item(
turn_context_item: &TurnContextItem,
previous_turn_settings: Option<&PreviousTurnSettings>,
) -> Self {
Self {
model: previous_turn_settings.map(|settings| settings.model.clone()),
model_instructions: String::new(),
permissions: Some(PermissionValues {
permission_profile: turn_context_item.permission_profile(),
approval_policy: turn_context_item.approval_policy,
}),
permissions_rendered: None,
collaboration_mode: Some(turn_context_item.collaboration_mode.clone()),
collaboration_mode_enabled: false,
multi_agent_mode: Some(turn_context_item.multi_agent_mode),
realtime_active: turn_context_item.realtime_active,
realtime_active_fallback: previous_turn_settings
.and_then(|settings| settings.realtime_active),
realtime_start_instructions: None,
personality_enabled: false,
personality_model: Some(turn_context_item.model.clone()),
personality: turn_context_item.personality,
personality_spec: None,
}
}
pub(crate) fn model_update(
previous_turn_settings: Option<&PreviousTurnSettings>,
turn_context: &TurnContext,
) -> Option<String> {
render_model_update(
previous_turn_settings.map(|settings| settings.model.as_str()),
Some(turn_context.model_info.slug.as_str()),
&turn_context
.model_info
.get_model_instructions(turn_context.personality),
)
}
pub(crate) fn realtime_update(
previous: Option<&TurnContextItem>,
previous_turn_settings: Option<&PreviousTurnSettings>,
turn_context: &TurnContext,
) -> Option<String> {
render_realtime_update(
previous.and_then(|item| item.realtime_active),
previous_turn_settings.and_then(|settings| settings.realtime_active),
turn_context.realtime_active,
turn_context
.config
.experimental_realtime_start_instructions
.as_deref(),
)
}
pub(crate) fn personality_message(
model_info: &ModelInfo,
personality: Personality,
) -> Option<String> {
model_info
.model_messages
.as_ref()
.and_then(|spec| spec.get_personality_message(Some(personality)))
.filter(|message| !message.is_empty())
}
fn model_diff(&self, previous: &Self) -> Option<String> {
render_model_update(
previous.model.as_deref(),
self.model.as_deref(),
&self.model_instructions,
)
}
fn permissions_diff(&self, previous: &Self) -> Option<String> {
let rendered = self.permissions_rendered.as_ref()?;
(self.permissions != previous.permissions).then(|| rendered.clone())
}
fn collaboration_mode_diff(&self, previous: &Self) -> Option<String> {
if !self.collaboration_mode_enabled
|| self.collaboration_mode == previous.collaboration_mode
{
return None;
}
let collaboration_mode = self.collaboration_mode.as_ref()?.as_ref()?;
CollaborationModeInstructions::from_collaboration_mode(collaboration_mode)
.map(|instructions| instructions.render())
}
fn multi_agent_mode_diff(&self, previous: &Self) -> Option<String> {
let previous_mode = previous.multi_agent_mode.as_ref()?;
let current_mode = self.multi_agent_mode.as_ref()?;
if current_mode == previous_mode {
return None;
}
match current_mode {
Some(mode) => Some(MultiAgentModeInstructions::new(*mode).render()),
None if *previous_mode == Some(MultiAgentMode::Proactive) => {
Some(MultiAgentModeInstructions::new(MultiAgentMode::ExplicitRequestOnly).render())
}
None => None,
}
}
fn realtime_diff(&self, previous: &Self) -> Option<String> {
render_realtime_update(
previous.realtime_active,
previous.realtime_active_fallback,
self.realtime_active.unwrap_or(false),
self.realtime_start_instructions.as_deref(),
)
}
fn personality_diff(&self, previous: &Self) -> Option<String> {
if !self.personality_enabled
|| self.personality_model != previous.personality_model
|| self.personality == previous.personality
{
return None;
}
self.personality?;
self.personality_spec
.as_ref()
.map(|spec| PersonalitySpecInstructions::new(spec).render())
}
}
impl WorldStateSection for SettingsState {
fn render_diff(&self, previous: &Self) -> Option<ResponseItem> {
// Keep model-switch instructions first so the new model sees its guidance before other
// settings updates, while retaining one developer message for the complete diff.
let content = [
self.model_diff(previous),
self.permissions_diff(previous),
self.collaboration_mode_diff(previous),
self.multi_agent_mode_diff(previous),
self.realtime_diff(previous),
self.personality_diff(previous),
]
.into_iter()
.flatten()
.map(|text| ContentItem::InputText { text })
.collect::<Vec<_>>();
(!content.is_empty()).then(|| ResponseItem::Message {
id: None,
role: "developer".to_string(),
content,
phase: None,
metadata: None,
})
}
}
fn render_model_update(
previous_model: Option<&str>,
current_model: Option<&str>,
model_instructions: &str,
) -> Option<String> {
let previous_model = previous_model?;
if current_model == Some(previous_model) || model_instructions.is_empty() {
return None;
}
Some(ModelSwitchInstructions::new(model_instructions).render())
}
fn render_realtime_update(
previous_active: Option<bool>,
previous_active_fallback: Option<bool>,
active: bool,
start_instructions: Option<&str>,
) -> Option<String> {
match (previous_active, active) {
(Some(true), false) => Some(RealtimeEndInstructions::new("inactive").render()),
(Some(false), true) | (None, true) => {
Some(if let Some(instructions) = start_instructions {
RealtimeStartWithInstructions::new(instructions).render()
} else {
RealtimeStartInstructions.render()
})
}
(Some(true), true) | (Some(false), false) => None,
(None, false) => previous_active_fallback
.filter(|realtime_active| *realtime_active)
.map(|_| RealtimeEndInstructions::new("inactive").render()),
}
}

View File

@@ -32,7 +32,9 @@ use crate::context::NetworkRuleSaved;
use crate::context::PermissionsInstructions;
use crate::context::PersonalitySpecInstructions;
use crate::context::RecommendedPluginsInstructions;
use crate::context::world_state::SettingsState;
use crate::context::world_state::ModelState;
use crate::context::world_state::PersonalityState;
use crate::context::world_state::RealtimeState;
use crate::current_time::TimeProvider;
use crate::default_skill_metadata_budget;
use crate::environment_selection::TurnEnvironmentSnapshot;
@@ -3029,8 +3031,12 @@ impl Session {
state.auto_compact_window_id(),
)
};
if let Some(model_switch_message) =
SettingsState::model_update(previous_turn_settings.as_ref(), turn_context)
if let Some(model_switch_message) = ModelState::from_turn_context(turn_context)
.rendered_diff(&ModelState::from_previous_model(
previous_turn_settings
.as_ref()
.map(|settings| settings.model.as_str()),
))
{
developer_sections.push(model_switch_message);
}
@@ -3072,10 +3078,15 @@ impl Session {
{
developer_sections.push(collab_instructions.render());
}
if let Some(realtime_update) = SettingsState::realtime_update(
reference_context_item.as_ref(),
previous_turn_settings.as_ref(),
turn_context,
if let Some(realtime_update) = RealtimeState::from_turn_context(turn_context).rendered_diff(
&RealtimeState::from_previous(
reference_context_item
.as_ref()
.and_then(|item| item.realtime_active),
previous_turn_settings
.as_ref()
.and_then(|settings| settings.realtime_active),
),
) {
developer_sections.push(realtime_update);
}
@@ -3087,7 +3098,7 @@ impl Session {
&& base_instructions == model_info.get_model_instructions(Some(personality));
if !has_baked_personality
&& let Some(personality_message) =
SettingsState::personality_message(&model_info, personality)
PersonalityState::message(&model_info, personality)
{
developer_sections
.push(PersonalitySpecInstructions::new(personality_message).render());

View File

@@ -2,7 +2,12 @@ use super::PreviousTurnSettings;
use super::Session;
use super::turn_context::TurnContext;
use crate::context::EnvironmentsState;
use crate::context::world_state::SettingsState;
use crate::context::world_state::CollaborationModeState;
use crate::context::world_state::ModelState;
use crate::context::world_state::MultiAgentModeState;
use crate::context::world_state::PermissionsState;
use crate::context::world_state::PersonalityState;
use crate::context::world_state::RealtimeState;
use crate::context::world_state::WorldState;
use crate::environment_selection::TurnEnvironmentSnapshot;
use codex_execpolicy::Policy;
@@ -17,9 +22,16 @@ fn build_world_state_from_turn_context_with_environments(
personality_feature_enabled: bool,
) -> WorldState {
let mut world_state = WorldState::default();
world_state.add_section(SettingsState::from_turn_context(
world_state.add_section(ModelState::from_turn_context(turn_context));
world_state.add_section(PermissionsState::from_turn_context(
turn_context,
exec_policy,
));
world_state.add_section(CollaborationModeState::from_turn_context(turn_context));
world_state.add_section(MultiAgentModeState::from_turn_context(turn_context));
world_state.add_section(RealtimeState::from_turn_context(turn_context));
world_state.add_section(PersonalityState::from_turn_context(
turn_context,
personality_feature_enabled,
));
if turn_context.config.include_environment_context {
@@ -36,10 +48,21 @@ pub(crate) fn build_world_state_from_turn_context_item(
previous_turn_settings: Option<&PreviousTurnSettings>,
) -> WorldState {
let mut world_state = WorldState::default();
world_state.add_section(SettingsState::from_turn_context_item(
turn_context_item,
previous_turn_settings,
world_state.add_section(ModelState::from_previous_model(
previous_turn_settings.map(|settings| settings.model.as_str()),
));
world_state.add_section(PermissionsState::from_turn_context_item(turn_context_item));
world_state.add_section(CollaborationModeState::from_turn_context_item(
turn_context_item,
));
world_state.add_section(MultiAgentModeState::from_turn_context_item(
turn_context_item,
));
world_state.add_section(RealtimeState::from_previous(
turn_context_item.realtime_active,
previous_turn_settings.and_then(|settings| settings.realtime_active),
));
world_state.add_section(PersonalityState::from_turn_context_item(turn_context_item));
world_state.add_section(EnvironmentsState::from_turn_context_item(turn_context_item));
world_state
}