Session-level model client (#10664)

Make ModelClient a session-scoped object.
Move state that is session level onto the client, and make state that is
per-turn explicit on corresponding methods.
Stop taking a huge Config object, instead only pass in values that are
actually needed.

---------

Co-authored-by: Josh McKinney <joshka@openai.com>
This commit is contained in:
pakrym-oai
2026-02-04 16:58:48 -08:00
committed by GitHub
Unverified
parent 224c9f768d
commit 0e8d359da9
12 changed files with 601 additions and 333 deletions
+12 -1
View File
@@ -6,6 +6,9 @@ use crate::error::CodexErr;
use crate::error::Result;
use codex_api::MemoryTrace as ApiMemoryTrace;
use codex_api::MemoryTraceMetadata as ApiMemoryTraceMetadata;
use codex_otel::OtelManager;
use codex_protocol::openai_models::ModelInfo;
use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig;
use serde_json::Map;
use serde_json::Value;
@@ -27,9 +30,15 @@ struct PreparedTrace {
///
/// The request/response wiring mirrors the memory trace summarize E2E flow:
/// `/v1/memories/trace_summarize` with one output object per input trace.
///
/// The caller provides the model selection, reasoning effort, and telemetry context explicitly so
/// the session-scoped [`ModelClient`] can be reused across turns.
pub async fn build_memories_from_trace_files(
client: &ModelClient,
trace_paths: &[PathBuf],
model_info: &ModelInfo,
effort: Option<ReasoningEffortConfig>,
otel_manager: &OtelManager,
) -> Result<Vec<BuiltTraceMemory>> {
if trace_paths.is_empty() {
return Ok(Vec::new());
@@ -41,7 +50,9 @@ pub async fn build_memories_from_trace_files(
}
let traces = prepared.iter().map(|trace| trace.payload.clone()).collect();
let output = client.summarize_memory_traces(traces).await?;
let output = client
.summarize_memory_traces(traces, model_info, effort, otel_manager)
.await?;
if output.len() != prepared.len() {
return Err(CodexErr::InvalidRequest(format!(
"unexpected memory summarize output length: expected {}, got {}",