mirror of
https://github.com/openai/codex.git
synced 2026-05-06 06:12:59 +03:00
V2
This commit is contained in:
5
codex-rs/core/src/state/mod.rs
Normal file
5
codex-rs/core/src/state/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
pub(crate) mod session;
|
||||
pub(crate) mod turn;
|
||||
|
||||
pub(crate) use session::SessionState;
|
||||
pub(crate) use turn::TurnState;
|
||||
48
codex-rs/core/src/state/session.rs
Normal file
48
codex-rs/core/src/state/session.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::Arc;
|
||||
|
||||
use codex_utils_readiness::ReadinessFlag;
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
use crate::conversation_history::ConversationHistory;
|
||||
use crate::protocol::RateLimitSnapshot;
|
||||
use crate::protocol::ReviewDecision;
|
||||
use crate::protocol::TokenUsageInfo;
|
||||
|
||||
pub(crate) struct SessionState {
|
||||
pub(crate) approved_commands: HashSet<Vec<String>>,
|
||||
pub(crate) pending_approvals: HashMap<String, oneshot::Sender<ReviewDecision>>,
|
||||
pub(crate) history: ConversationHistory,
|
||||
pub(crate) token_info: Option<TokenUsageInfo>,
|
||||
pub(crate) latest_rate_limits: Option<RateLimitSnapshot>,
|
||||
readiness_queue: VecDeque<Arc<ReadinessFlag>>,
|
||||
}
|
||||
|
||||
impl SessionState {
|
||||
pub(crate) fn push_readiness(&mut self, flag: Arc<ReadinessFlag>) {
|
||||
self.readiness_queue.push_back(flag);
|
||||
}
|
||||
|
||||
pub(crate) fn next_readiness(&mut self) -> Option<Arc<ReadinessFlag>> {
|
||||
self.readiness_queue.pop_front()
|
||||
}
|
||||
|
||||
pub(crate) fn clear_readiness(&mut self) {
|
||||
self.readiness_queue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SessionState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
approved_commands: HashSet::new(),
|
||||
pending_approvals: HashMap::new(),
|
||||
history: ConversationHistory::new(),
|
||||
token_info: None,
|
||||
latest_rate_limits: None,
|
||||
readiness_queue: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
120
codex-rs/core/src/state/turn.rs
Normal file
120
codex-rs/core/src/state/turn.rs
Normal file
@@ -0,0 +1,120 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use codex_utils_readiness::ReadinessFlag;
|
||||
use serde_json::Value;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::client::ModelClient;
|
||||
use crate::config_types::ShellEnvironmentPolicy;
|
||||
use crate::openai_tools::ToolsConfig;
|
||||
use crate::protocol::AskForApproval;
|
||||
use crate::protocol::InputItem;
|
||||
use crate::protocol::SandboxPolicy;
|
||||
use codex_protocol::models::ResponseInputItem;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct TurnContext {
|
||||
pub(crate) client: ModelClient,
|
||||
/// The session's current working directory. All relative paths provided by
|
||||
/// the model as well as sandbox policies are resolved against this path
|
||||
/// instead of `std::env::current_dir()`.
|
||||
pub(crate) cwd: PathBuf,
|
||||
pub(crate) base_instructions: Option<String>,
|
||||
pub(crate) user_instructions: Option<String>,
|
||||
pub(crate) approval_policy: AskForApproval,
|
||||
pub(crate) sandbox_policy: SandboxPolicy,
|
||||
pub(crate) shell_environment_policy: ShellEnvironmentPolicy,
|
||||
pub(crate) tools_config: ToolsConfig,
|
||||
pub(crate) is_review_mode: bool,
|
||||
pub(crate) final_output_json_schema: Option<Value>,
|
||||
}
|
||||
|
||||
impl TurnContext {
|
||||
pub(crate) fn resolve_path(&self, path: Option<String>) -> PathBuf {
|
||||
path.as_ref()
|
||||
.map(PathBuf::from)
|
||||
.map_or_else(|| self.cwd.clone(), |p| self.cwd.join(p))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct TurnMailbox {
|
||||
latest_readiness: Option<Arc<ReadinessFlag>>,
|
||||
pending: VecDeque<ResponseInputItem>,
|
||||
}
|
||||
|
||||
pub(crate) struct TurnState {
|
||||
sub_id: String,
|
||||
turn_context: Arc<TurnContext>,
|
||||
initial_input: Option<ResponseInputItem>,
|
||||
initial_readiness: Option<Arc<ReadinessFlag>>,
|
||||
mailbox: Mutex<TurnMailbox>,
|
||||
}
|
||||
|
||||
impl TurnState {
|
||||
pub(crate) fn new(
|
||||
sub_id: String,
|
||||
turn_context: Arc<TurnContext>,
|
||||
initial_input: Vec<InputItem>,
|
||||
readiness: Option<Arc<ReadinessFlag>>,
|
||||
) -> Self {
|
||||
let initial_input = if initial_input.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(initial_input.into())
|
||||
};
|
||||
|
||||
Self {
|
||||
sub_id,
|
||||
turn_context,
|
||||
initial_input,
|
||||
initial_readiness: readiness,
|
||||
mailbox: Mutex::new(TurnMailbox::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn sub_id(&self) -> &str {
|
||||
&self.sub_id
|
||||
}
|
||||
|
||||
pub(crate) fn turn_context(&self) -> Arc<TurnContext> {
|
||||
Arc::clone(&self.turn_context)
|
||||
}
|
||||
|
||||
pub(crate) fn initial_input(&self) -> Option<ResponseInputItem> {
|
||||
self.initial_input.clone()
|
||||
}
|
||||
|
||||
pub(crate) fn initial_readiness(&self) -> Option<Arc<ReadinessFlag>> {
|
||||
self.initial_readiness.clone()
|
||||
}
|
||||
|
||||
pub(crate) async fn enqueue_user_input(
|
||||
&self,
|
||||
items: Vec<InputItem>,
|
||||
readiness: Option<Arc<ReadinessFlag>>,
|
||||
) {
|
||||
let mut mailbox = self.mailbox.lock().await;
|
||||
if let Some(flag) = readiness {
|
||||
mailbox.latest_readiness = Some(flag);
|
||||
}
|
||||
if items.is_empty() {
|
||||
return;
|
||||
}
|
||||
let input: ResponseInputItem = items.into();
|
||||
mailbox.pending.push_back(input);
|
||||
}
|
||||
|
||||
pub(crate) async fn drain_mailbox(
|
||||
&self,
|
||||
current: Option<Arc<ReadinessFlag>>,
|
||||
) -> (Vec<ResponseItem>, Option<Arc<ReadinessFlag>>) {
|
||||
let mut mailbox = self.mailbox.lock().await;
|
||||
let readiness = mailbox.latest_readiness.take().or(current);
|
||||
let items = mailbox.pending.drain(..).map(ResponseItem::from).collect();
|
||||
(items, readiness)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user