This commit is contained in:
jif-oai
2025-10-31 13:28:33 +01:00
parent 69341a04f4
commit cfe7fb825c
6 changed files with 67 additions and 39 deletions
+3 -4
View File
@@ -101,7 +101,7 @@ impl ResponsesBackend {
self.client
.stream(prompt)
.await
.map(|stream| stream.boxed())
.map(futures::StreamExt::boxed)
}
}
@@ -181,8 +181,8 @@ impl ModelClient {
pub async fn stream(&self, payload: &StreamPayload) -> Result<ResponseStream> {
let mut prompt = payload.prompt.clone();
self.populate_prompt(&mut prompt);
if self.provider.wire_api == WireApi::Responses {
if let Some(path) = &*CODEX_RS_SSE_FIXTURE {
if self.provider.wire_api == WireApi::Responses
&& let Some(path) = &*CODEX_RS_SSE_FIXTURE {
warn!(path, "Streaming from fixture");
let stream = stream_from_fixture(
path,
@@ -194,7 +194,6 @@ impl ModelClient {
.boxed();
return Ok(wrap_stream(stream));
}
}
let backend = self
.backend
+14 -15
View File
@@ -303,7 +303,7 @@ pub(crate) struct SessionConfiguration {
provider: ModelProviderInfo,
/// If not specified, server will use its default model.
model: String,
pub(crate) model: String,
model_reasoning_effort: Option<ReasoningEffortConfig>,
model_reasoning_summary: ReasoningSummaryConfig,
@@ -315,7 +315,7 @@ pub(crate) struct SessionConfiguration {
user_instructions: Option<String>,
/// Base instructions override.
base_instructions: Option<String>,
pub(crate) base_instructions: Option<String>,
/// Compact prompt override.
compact_prompt: Option<String>,
@@ -335,7 +335,7 @@ pub(crate) struct SessionConfiguration {
cwd: PathBuf,
/// Set of feature flags for this session
features: Features,
pub(crate) features: Features,
// TODO(pakrym): Remove config from here
original_config_do_not_use: Arc<Config>,
@@ -588,8 +588,9 @@ impl Session {
config.active_profile.clone(),
);
// Create the mutable state for the Session.
let state = SessionState::new(session_configuration.clone());
let model_family = find_family_for_model(&session_configuration.model)
.unwrap_or_else(|| config.model_family.clone());
let state = SessionState::new(session_configuration.clone(), model_family);
let services = SessionServices {
mcp_connection_manager,
@@ -696,7 +697,6 @@ impl Session {
pub(crate) async fn update_settings(&self, updates: SessionSettingsUpdate) {
let mut state = self.state.lock().await;
state.session_configuration = state.session_configuration.apply(&updates);
}
@@ -942,12 +942,6 @@ impl Session {
self.send_raw_response_items(turn_context, items).await;
}
async fn prompt_for_turn(&self, turn_context: &TurnContext) -> Prompt {
let supports_chain = turn_context.client.supports_responses_api_chaining();
let mut state = self.state.lock().await;
state.prompt_for_turn(supports_chain)
}
fn reconstruct_history_from_rollout(
&self,
turn_context: &TurnContext,
@@ -1801,7 +1795,8 @@ pub(crate) async fn run_task(
// Construct the input that we will send to the model.
sess.record_conversation_items(&turn_context, &pending_input)
.await;
let prompt = sess.prompt_for_turn(&turn_context).await;
let mut state = sess.state.lock().await;
let prompt = state.prompt_for_turn();
let turn_input_messages: Vec<String> = {
prompt
@@ -2594,7 +2589,9 @@ mod tests {
session_source: SessionSource::Exec,
};
let state = SessionState::new(session_configuration.clone());
let model_family = find_family_for_model(&session_configuration.model)
.unwrap_or_else(|| config.model_family.clone());
let state = SessionState::new(session_configuration.clone(), model_family);
let services = SessionServices {
mcp_connection_manager: McpConnectionManager::default(),
@@ -2670,7 +2667,9 @@ mod tests {
session_source: SessionSource::Exec,
};
let state = SessionState::new(session_configuration.clone());
let model_family = find_family_for_model(&session_configuration.model)
.unwrap_or_else(|| config.model_family.clone());
let state = SessionState::new(session_configuration.clone(), model_family);
let services = SessionServices {
mcp_connection_manager: McpConnectionManager::default(),
+38 -3
View File
@@ -3,27 +3,39 @@
use codex_protocol::models::ResponseItem;
use crate::client_common::Prompt;
use crate::client_common::compute_full_instructions;
use crate::codex::SessionConfiguration;
use crate::conversation_history::ConversationHistory;
use crate::conversation_history::ResponsesApiChainState;
use crate::conversation_history::format_prompt_items;
use crate::model_family::ModelFamily;
use crate::protocol::RateLimitSnapshot;
use crate::protocol::TokenUsage;
use crate::protocol::TokenUsageInfo;
use crate::tools::spec::ToolsConfig;
use crate::tools::spec::ToolsConfigParams;
use crate::tools::spec::build_specs;
use crate::tools::spec::tools_metadata_for_prompt;
/// Persistent, session-scoped state previously stored directly on `Session`.
pub(crate) struct SessionState {
pub(crate) session_configuration: SessionConfiguration,
pub(crate) history: ConversationHistory,
pub(crate) latest_rate_limits: Option<RateLimitSnapshot>,
pub(crate) model_family: ModelFamily,
}
impl SessionState {
/// Create a new session state mirroring previous `State::default()` semantics.
pub(crate) fn new(session_configuration: SessionConfiguration) -> Self {
pub(crate) fn new(
session_configuration: SessionConfiguration,
model_family: ModelFamily,
) -> Self {
Self {
session_configuration,
history: ConversationHistory::new(),
latest_rate_limits: None,
model_family,
}
}
@@ -79,13 +91,36 @@ impl SessionState {
self.history.set_token_usage_full(context_window);
}
pub(crate) fn prompt_for_turn(&mut self, supports_responses_api_chaining: bool) -> Prompt {
pub(crate) fn prompt_for_turn(&mut self) -> Prompt {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_family: &self.model_family,
features: &self.session_configuration.features,
});
let (tool_specs, _registry) = build_specs(&tools_config, None).build();
let tool_specs = tool_specs.into_iter().map(|c| c.spec).collect::<Vec<_>>();
let prompt_items = self.history.get_history_for_prompt();
let chain_state = self.history.responses_api_chain();
let (prompt, reset_chain) = build_prompt_from_items(prompt_items, chain_state.as_ref());
let (mut prompt, reset_chain) = build_prompt_from_items(prompt_items, chain_state.as_ref());
if reset_chain {
self.reset_responses_api_chain();
}
// Populate prompt fields that depend only on session state.
let (tools_json, has_freeform_apply_patch) =
tools_metadata_for_prompt(&tool_specs).expect("tool specs serialization");
format_prompt_items(&mut prompt.input, has_freeform_apply_patch);
let apply_patch_present = tool_specs.iter().any(|spec| spec.name() == "apply_patch");
let base_override = self.session_configuration.base_instructions.as_deref();
let instructions =
compute_full_instructions(base_override, &self.model_family, apply_patch_present)
.into_owned();
prompt.instructions = instructions;
prompt.tools = tools_json;
prompt.parallel_tool_calls = self.model_family.supports_parallel_tool_calls;
prompt
}
}