mirror of
https://github.com/openai/codex.git
synced 2026-04-21 21:24:51 +00:00
Compare commits
1 Commits
codex-debu
...
codex-work
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bacd398f31 |
@@ -1042,10 +1042,7 @@
|
|||||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||||
"enum": [
|
"enum": [
|
||||||
"plan",
|
"plan",
|
||||||
"code",
|
"default"
|
||||||
"pair_programming",
|
|
||||||
"execute",
|
|
||||||
"custom"
|
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -686,7 +686,7 @@
|
|||||||
"$ref": "#/definitions/ModeKind"
|
"$ref": "#/definitions/ModeKind"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default": "code"
|
"default": "default"
|
||||||
},
|
},
|
||||||
"model_context_window": {
|
"model_context_window": {
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
@@ -3280,10 +3280,7 @@
|
|||||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||||
"enum": [
|
"enum": [
|
||||||
"plan",
|
"plan",
|
||||||
"code",
|
"default"
|
||||||
"pair_programming",
|
|
||||||
"execute",
|
|
||||||
"custom"
|
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -5433,7 +5430,7 @@
|
|||||||
"$ref": "#/definitions/ModeKind"
|
"$ref": "#/definitions/ModeKind"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default": "code"
|
"default": "default"
|
||||||
},
|
},
|
||||||
"model_context_window": {
|
"model_context_window": {
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
|
|||||||
@@ -1264,7 +1264,7 @@
|
|||||||
"$ref": "#/definitions/ModeKind"
|
"$ref": "#/definitions/ModeKind"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default": "code"
|
"default": "default"
|
||||||
},
|
},
|
||||||
"model_context_window": {
|
"model_context_window": {
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
@@ -4061,10 +4061,7 @@
|
|||||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||||
"enum": [
|
"enum": [
|
||||||
"plan",
|
"plan",
|
||||||
"code",
|
"default"
|
||||||
"pair_programming",
|
|
||||||
"execute",
|
|
||||||
"custom"
|
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2526,7 +2526,7 @@
|
|||||||
"$ref": "#/definitions/v2/ModeKind"
|
"$ref": "#/definitions/v2/ModeKind"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default": "code"
|
"default": "default"
|
||||||
},
|
},
|
||||||
"model_context_window": {
|
"model_context_window": {
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
@@ -6008,10 +6008,7 @@
|
|||||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||||
"enum": [
|
"enum": [
|
||||||
"plan",
|
"plan",
|
||||||
"code",
|
"default"
|
||||||
"pair_programming",
|
|
||||||
"execute",
|
|
||||||
"custom"
|
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -12273,10 +12270,7 @@
|
|||||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||||
"enum": [
|
"enum": [
|
||||||
"plan",
|
"plan",
|
||||||
"code",
|
"default"
|
||||||
"pair_programming",
|
|
||||||
"execute",
|
|
||||||
"custom"
|
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -686,7 +686,7 @@
|
|||||||
"$ref": "#/definitions/ModeKind"
|
"$ref": "#/definitions/ModeKind"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default": "code"
|
"default": "default"
|
||||||
},
|
},
|
||||||
"model_context_window": {
|
"model_context_window": {
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
@@ -3280,10 +3280,7 @@
|
|||||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||||
"enum": [
|
"enum": [
|
||||||
"plan",
|
"plan",
|
||||||
"code",
|
"default"
|
||||||
"pair_programming",
|
|
||||||
"execute",
|
|
||||||
"custom"
|
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -686,7 +686,7 @@
|
|||||||
"$ref": "#/definitions/ModeKind"
|
"$ref": "#/definitions/ModeKind"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default": "code"
|
"default": "default"
|
||||||
},
|
},
|
||||||
"model_context_window": {
|
"model_context_window": {
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
@@ -3280,10 +3280,7 @@
|
|||||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||||
"enum": [
|
"enum": [
|
||||||
"plan",
|
"plan",
|
||||||
"code",
|
"default"
|
||||||
"pair_programming",
|
|
||||||
"execute",
|
|
||||||
"custom"
|
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -686,7 +686,7 @@
|
|||||||
"$ref": "#/definitions/ModeKind"
|
"$ref": "#/definitions/ModeKind"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default": "code"
|
"default": "default"
|
||||||
},
|
},
|
||||||
"model_context_window": {
|
"model_context_window": {
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
@@ -3280,10 +3280,7 @@
|
|||||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||||
"enum": [
|
"enum": [
|
||||||
"plan",
|
"plan",
|
||||||
"code",
|
"default"
|
||||||
"pair_programming",
|
|
||||||
"execute",
|
|
||||||
"custom"
|
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -53,10 +53,7 @@
|
|||||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||||
"enum": [
|
"enum": [
|
||||||
"plan",
|
"plan",
|
||||||
"code",
|
"default"
|
||||||
"pair_programming",
|
|
||||||
"execute",
|
|
||||||
"custom"
|
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
/**
|
/**
|
||||||
* Initial collaboration mode to use when the TUI starts.
|
* Initial collaboration mode to use when the TUI starts.
|
||||||
*/
|
*/
|
||||||
export type ModeKind = "plan" | "code" | "pair_programming" | "execute" | "custom";
|
export type ModeKind = "plan" | "default";
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
//! Validates that the collaboration mode list endpoint returns the expected default presets.
|
//! Validates that the collaboration mode list endpoint returns the expected default presets.
|
||||||
//!
|
//!
|
||||||
//! The test drives the app server through the MCP harness and asserts that the list response
|
//! The test drives the app server through the MCP harness and asserts that the list response
|
||||||
//! includes the plan, coding, pair programming, and execute modes with their default model and reasoning
|
//! includes the plan and default modes with their default model and reasoning effort
|
||||||
//! effort settings, which keeps the API contract visible in one place.
|
//! settings, which keeps the API contract visible in one place.
|
||||||
|
|
||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
|
|
||||||
@@ -45,23 +45,8 @@ async fn list_collaboration_modes_returns_presets() -> Result<()> {
|
|||||||
let CollaborationModeListResponse { data: items } =
|
let CollaborationModeListResponse { data: items } =
|
||||||
to_response::<CollaborationModeListResponse>(response)?;
|
to_response::<CollaborationModeListResponse>(response)?;
|
||||||
|
|
||||||
let expected = [
|
let expected = vec![plan_preset(), default_preset()];
|
||||||
plan_preset(),
|
assert_eq!(expected, items);
|
||||||
code_preset(),
|
|
||||||
pair_programming_preset(),
|
|
||||||
execute_preset(),
|
|
||||||
];
|
|
||||||
assert_eq!(expected.len(), items.len());
|
|
||||||
for (expected_mask, actual_mask) in expected.iter().zip(items.iter()) {
|
|
||||||
assert_eq!(expected_mask.name, actual_mask.name);
|
|
||||||
assert_eq!(expected_mask.mode, actual_mask.mode);
|
|
||||||
assert_eq!(expected_mask.model, actual_mask.model);
|
|
||||||
assert_eq!(expected_mask.reasoning_effort, actual_mask.reasoning_effort);
|
|
||||||
assert_eq!(
|
|
||||||
expected_mask.developer_instructions,
|
|
||||||
actual_mask.developer_instructions
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,35 +62,11 @@ fn plan_preset() -> CollaborationModeMask {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the pair programming preset that the list response is expected to return.
|
/// Builds the default preset that the list response is expected to return.
|
||||||
///
|
fn default_preset() -> CollaborationModeMask {
|
||||||
/// The helper keeps the expected model and reasoning defaults co-located with the test
|
|
||||||
/// so that mismatches point directly at the API contract being exercised.
|
|
||||||
fn pair_programming_preset() -> CollaborationModeMask {
|
|
||||||
let presets = test_builtin_collaboration_mode_presets();
|
let presets = test_builtin_collaboration_mode_presets();
|
||||||
presets
|
presets
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|p| p.mode == Some(ModeKind::PairProgramming))
|
.find(|p| p.mode == Some(ModeKind::Default))
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds the code preset that the list response is expected to return.
|
|
||||||
fn code_preset() -> CollaborationModeMask {
|
|
||||||
let presets = test_builtin_collaboration_mode_presets();
|
|
||||||
presets
|
|
||||||
.into_iter()
|
|
||||||
.find(|p| p.mode == Some(ModeKind::Code))
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds the execute preset that the list response is expected to return.
|
|
||||||
///
|
|
||||||
/// The execute preset uses a different reasoning effort to capture the higher-effort
|
|
||||||
/// execution contract the server currently exposes.
|
|
||||||
fn execute_preset() -> CollaborationModeMask {
|
|
||||||
let presets = test_builtin_collaboration_mode_presets();
|
|
||||||
presets
|
|
||||||
.into_iter()
|
|
||||||
.find(|p| p.mode == Some(ModeKind::Execute))
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ async fn turn_start_accepts_collaboration_mode_override_v2() -> Result<()> {
|
|||||||
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(thread_resp)?;
|
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(thread_resp)?;
|
||||||
|
|
||||||
let collaboration_mode = CollaborationMode {
|
let collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model: "mock-model-collab".to_string(),
|
model: "mock-model-collab".to_string(),
|
||||||
reasoning_effort: Some(ReasoningEffort::High),
|
reasoning_effort: Some(ReasoningEffort::High),
|
||||||
|
|||||||
@@ -378,10 +378,7 @@
|
|||||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||||
"enum": [
|
"enum": [
|
||||||
"plan",
|
"plan",
|
||||||
"code",
|
"default"
|
||||||
"pair_programming",
|
|
||||||
"execute",
|
|
||||||
"custom"
|
|
||||||
],
|
],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -1021,7 +1018,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default": null,
|
"default": null,
|
||||||
"description": "Start the TUI in the specified collaboration mode (plan/execute/etc.). Defaults to unset."
|
"description": "Start the TUI in the specified collaboration mode (plan/default). Defaults to unset."
|
||||||
},
|
},
|
||||||
"notification_method": {
|
"notification_method": {
|
||||||
"allOf": [
|
"allOf": [
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ mod tests {
|
|||||||
async fn on_event_updates_status_from_task_started() {
|
async fn on_event_updates_status_from_task_started() {
|
||||||
let status = agent_status_from_event(&EventMsg::TurnStarted(TurnStartedEvent {
|
let status = agent_status_from_event(&EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}));
|
}));
|
||||||
assert_eq!(status, Some(AgentStatus::Running));
|
assert_eq!(status, Some(AgentStatus::Running));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ impl Codex {
|
|||||||
// TODO (aibrahim): Consolidate config.model and config.model_reasoning_effort into config.collaboration_mode
|
// TODO (aibrahim): Consolidate config.model and config.model_reasoning_effort into config.collaboration_mode
|
||||||
// to avoid extracting these fields separately and constructing CollaborationMode here.
|
// to avoid extracting these fields separately and constructing CollaborationMode here.
|
||||||
let collaboration_mode = CollaborationMode {
|
let collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model: model.clone(),
|
model: model.clone(),
|
||||||
reasoning_effort: config.model_reasoning_effort,
|
reasoning_effort: config.model_reasoning_effort,
|
||||||
@@ -2628,7 +2628,7 @@ mod handlers {
|
|||||||
} => {
|
} => {
|
||||||
let collaboration_mode = collaboration_mode.or_else(|| {
|
let collaboration_mode = collaboration_mode.or_else(|| {
|
||||||
Some(CollaborationMode {
|
Some(CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model: model.clone(),
|
model: model.clone(),
|
||||||
reasoning_effort: effort,
|
reasoning_effort: effort,
|
||||||
@@ -4942,7 +4942,7 @@ mod tests {
|
|||||||
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
|
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
|
||||||
let reasoning_effort = config.model_reasoning_effort;
|
let reasoning_effort = config.model_reasoning_effort;
|
||||||
let collaboration_mode = CollaborationMode {
|
let collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model,
|
model,
|
||||||
reasoning_effort,
|
reasoning_effort,
|
||||||
@@ -5025,7 +5025,7 @@ mod tests {
|
|||||||
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
|
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
|
||||||
let reasoning_effort = config.model_reasoning_effort;
|
let reasoning_effort = config.model_reasoning_effort;
|
||||||
let collaboration_mode = CollaborationMode {
|
let collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model,
|
model,
|
||||||
reasoning_effort,
|
reasoning_effort,
|
||||||
@@ -5292,7 +5292,7 @@ mod tests {
|
|||||||
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
|
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
|
||||||
let reasoning_effort = config.model_reasoning_effort;
|
let reasoning_effort = config.model_reasoning_effort;
|
||||||
let collaboration_mode = CollaborationMode {
|
let collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model,
|
model,
|
||||||
reasoning_effort,
|
reasoning_effort,
|
||||||
@@ -5412,7 +5412,7 @@ mod tests {
|
|||||||
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
|
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
|
||||||
let reasoning_effort = config.model_reasoning_effort;
|
let reasoning_effort = config.model_reasoning_effort;
|
||||||
let collaboration_mode = CollaborationMode {
|
let collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model,
|
model,
|
||||||
reasoning_effort,
|
reasoning_effort,
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ pub struct Config {
|
|||||||
/// Show startup tooltips in the TUI welcome screen.
|
/// Show startup tooltips in the TUI welcome screen.
|
||||||
pub show_tooltips: bool,
|
pub show_tooltips: bool,
|
||||||
|
|
||||||
/// Start the TUI in the specified collaboration mode (plan/execute/etc.).
|
/// Start the TUI in the specified collaboration mode (plan/default).
|
||||||
pub experimental_mode: Option<ModeKind>,
|
pub experimental_mode: Option<ModeKind>,
|
||||||
|
|
||||||
/// Controls whether the TUI uses the terminal's alternate screen buffer.
|
/// Controls whether the TUI uses the terminal's alternate screen buffer.
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ pub struct Tui {
|
|||||||
#[serde(default = "default_true")]
|
#[serde(default = "default_true")]
|
||||||
pub show_tooltips: bool,
|
pub show_tooltips: bool,
|
||||||
|
|
||||||
/// Start the TUI in the specified collaboration mode (plan/execute/etc.).
|
/// Start the TUI in the specified collaboration mode (plan/default).
|
||||||
/// Defaults to unset.
|
/// Defaults to unset.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub experimental_mode: Option<ModeKind>,
|
pub experimental_mode: Option<ModeKind>,
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ pub enum Feature {
|
|||||||
SkillEnvVarDependencyPrompt,
|
SkillEnvVarDependencyPrompt,
|
||||||
/// Steer feature flag - when enabled, Enter submits immediately instead of queuing.
|
/// Steer feature flag - when enabled, Enter submits immediately instead of queuing.
|
||||||
Steer,
|
Steer,
|
||||||
/// Enable collaboration modes (Plan, Code, Pair Programming, Execute).
|
/// Enable collaboration modes (Plan, Default).
|
||||||
CollaborationModes,
|
CollaborationModes,
|
||||||
/// Enable personality selection in the TUI.
|
/// Enable personality selection in the TUI.
|
||||||
Personality,
|
Personality,
|
||||||
|
|||||||
@@ -3,19 +3,11 @@ use codex_protocol::config_types::ModeKind;
|
|||||||
use codex_protocol::openai_models::ReasoningEffort;
|
use codex_protocol::openai_models::ReasoningEffort;
|
||||||
|
|
||||||
const COLLABORATION_MODE_PLAN: &str = include_str!("../../templates/collaboration_mode/plan.md");
|
const COLLABORATION_MODE_PLAN: &str = include_str!("../../templates/collaboration_mode/plan.md");
|
||||||
const COLLABORATION_MODE_CODE: &str = include_str!("../../templates/collaboration_mode/code.md");
|
const COLLABORATION_MODE_DEFAULT: &str =
|
||||||
const COLLABORATION_MODE_PAIR_PROGRAMMING: &str =
|
include_str!("../../templates/collaboration_mode/default.md");
|
||||||
include_str!("../../templates/collaboration_mode/pair_programming.md");
|
|
||||||
const COLLABORATION_MODE_EXECUTE: &str =
|
|
||||||
include_str!("../../templates/collaboration_mode/execute.md");
|
|
||||||
|
|
||||||
pub(super) fn builtin_collaboration_mode_presets() -> Vec<CollaborationModeMask> {
|
pub(super) fn builtin_collaboration_mode_presets() -> Vec<CollaborationModeMask> {
|
||||||
vec![
|
vec![plan_preset(), default_preset()]
|
||||||
plan_preset(),
|
|
||||||
code_preset(),
|
|
||||||
pair_programming_preset(),
|
|
||||||
execute_preset(),
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
@@ -33,32 +25,12 @@ fn plan_preset() -> CollaborationModeMask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn code_preset() -> CollaborationModeMask {
|
fn default_preset() -> CollaborationModeMask {
|
||||||
CollaborationModeMask {
|
CollaborationModeMask {
|
||||||
name: "Code".to_string(),
|
name: "Default".to_string(),
|
||||||
mode: Some(ModeKind::Code),
|
mode: Some(ModeKind::Default),
|
||||||
model: None,
|
model: None,
|
||||||
reasoning_effort: None,
|
reasoning_effort: None,
|
||||||
developer_instructions: Some(Some(COLLABORATION_MODE_CODE.to_string())),
|
developer_instructions: Some(Some(COLLABORATION_MODE_DEFAULT.to_string())),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pair_programming_preset() -> CollaborationModeMask {
|
|
||||||
CollaborationModeMask {
|
|
||||||
name: "Pair Programming".to_string(),
|
|
||||||
mode: Some(ModeKind::PairProgramming),
|
|
||||||
model: None,
|
|
||||||
reasoning_effort: Some(Some(ReasoningEffort::Medium)),
|
|
||||||
developer_instructions: Some(Some(COLLABORATION_MODE_PAIR_PROGRAMMING.to_string())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute_preset() -> CollaborationModeMask {
|
|
||||||
CollaborationModeMask {
|
|
||||||
name: "Execute".to_string(),
|
|
||||||
mode: Some(ModeKind::Execute),
|
|
||||||
model: None,
|
|
||||||
reasoning_effort: Some(Some(ReasoningEffort::High)),
|
|
||||||
developer_instructions: Some(Some(COLLABORATION_MODE_EXECUTE.to_string())),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,12 +37,10 @@ impl ToolHandler for RequestUserInputHandler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mode = session.collaboration_mode().await.mode;
|
let mode = session.collaboration_mode().await.mode;
|
||||||
if !matches!(mode, ModeKind::Plan | ModeKind::PairProgramming) {
|
if !matches!(mode, ModeKind::Plan) {
|
||||||
let mode_name = match mode {
|
let mode_name = match mode {
|
||||||
ModeKind::Code => "Code",
|
ModeKind::Default | ModeKind::PairProgramming | ModeKind::Execute => "Default",
|
||||||
ModeKind::Execute => "Execute",
|
ModeKind::Plan => unreachable!(),
|
||||||
ModeKind::Custom => "Custom",
|
|
||||||
ModeKind::Plan | ModeKind::PairProgramming => unreachable!(),
|
|
||||||
};
|
};
|
||||||
return Err(FunctionCallError::RespondToModel(format!(
|
return Err(FunctionCallError::RespondToModel(format!(
|
||||||
"request_user_input is unavailable in {mode_name} mode"
|
"request_user_input is unavailable in {mode_name} mode"
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
you are now in code mode.
|
|
||||||
1
codex-rs/core/templates/collaboration_mode/default.md
Normal file
1
codex-rs/core/templates/collaboration_mode/default.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
you are now in default mode.
|
||||||
@@ -824,7 +824,7 @@ async fn user_turn_collaboration_mode_overrides_model_and_effort() -> anyhow::Re
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let collaboration_mode = CollaborationMode {
|
let collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model: "gpt-5.1".to_string(),
|
model: "gpt-5.1".to_string(),
|
||||||
reasoning_effort: Some(ReasoningEffort::High),
|
reasoning_effort: Some(ReasoningEffort::High),
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ fn collab_mode_with_mode_and_instructions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn collab_mode_with_instructions(instructions: Option<&str>) -> CollaborationMode {
|
fn collab_mode_with_instructions(instructions: Option<&str>) -> CollaborationMode {
|
||||||
collab_mode_with_mode_and_instructions(ModeKind::Custom, instructions)
|
collab_mode_with_mode_and_instructions(ModeKind::Default, instructions)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn developer_texts(input: &[Value]) -> Vec<String> {
|
fn developer_texts(input: &[Value]) -> Vec<String> {
|
||||||
@@ -427,7 +427,7 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang
|
|||||||
let req2 = mount_sse_once(&server, sse_completed("resp-2")).await;
|
let req2 = mount_sse_once(&server, sse_completed("resp-2")).await;
|
||||||
|
|
||||||
let test = test_codex().build(&server).await?;
|
let test = test_codex().build(&server).await?;
|
||||||
let code_text = "code mode instructions";
|
let default_text = "default mode instructions";
|
||||||
let plan_text = "plan mode instructions";
|
let plan_text = "plan mode instructions";
|
||||||
|
|
||||||
test.codex
|
test.codex
|
||||||
@@ -440,8 +440,8 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang
|
|||||||
effort: None,
|
effort: None,
|
||||||
summary: None,
|
summary: None,
|
||||||
collaboration_mode: Some(collab_mode_with_mode_and_instructions(
|
collaboration_mode: Some(collab_mode_with_mode_and_instructions(
|
||||||
ModeKind::Code,
|
ModeKind::Default,
|
||||||
Some(code_text),
|
Some(default_text),
|
||||||
)),
|
)),
|
||||||
personality: None,
|
personality: None,
|
||||||
})
|
})
|
||||||
@@ -488,9 +488,9 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang
|
|||||||
|
|
||||||
let input = req2.single_request().input();
|
let input = req2.single_request().input();
|
||||||
let dev_texts = developer_texts(&input);
|
let dev_texts = developer_texts(&input);
|
||||||
let code_text = collab_xml(code_text);
|
let default_text = collab_xml(default_text);
|
||||||
let plan_text = collab_xml(plan_text);
|
let plan_text = collab_xml(plan_text);
|
||||||
assert_eq!(count_exact(&dev_texts, &code_text), 1);
|
assert_eq!(count_exact(&dev_texts, &default_text), 1);
|
||||||
assert_eq!(count_exact(&dev_texts, &plan_text), 1);
|
assert_eq!(count_exact(&dev_texts, &plan_text), 1);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -517,7 +517,7 @@ async fn collaboration_mode_update_noop_does_not_append_when_mode_is_unchanged()
|
|||||||
effort: None,
|
effort: None,
|
||||||
summary: None,
|
summary: None,
|
||||||
collaboration_mode: Some(collab_mode_with_mode_and_instructions(
|
collaboration_mode: Some(collab_mode_with_mode_and_instructions(
|
||||||
ModeKind::Code,
|
ModeKind::Default,
|
||||||
Some(collab_text),
|
Some(collab_text),
|
||||||
)),
|
)),
|
||||||
personality: None,
|
personality: None,
|
||||||
@@ -545,7 +545,7 @@ async fn collaboration_mode_update_noop_does_not_append_when_mode_is_unchanged()
|
|||||||
effort: None,
|
effort: None,
|
||||||
summary: None,
|
summary: None,
|
||||||
collaboration_mode: Some(collab_mode_with_mode_and_instructions(
|
collaboration_mode: Some(collab_mode_with_mode_and_instructions(
|
||||||
ModeKind::Code,
|
ModeKind::Default,
|
||||||
Some(collab_text),
|
Some(collab_text),
|
||||||
)),
|
)),
|
||||||
personality: None,
|
personality: None,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use tempfile::TempDir;
|
|||||||
|
|
||||||
fn collab_mode_with_instructions(instructions: Option<&str>) -> CollaborationMode {
|
fn collab_mode_with_instructions(instructions: Option<&str>) -> CollaborationMode {
|
||||||
CollaborationMode {
|
CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model: "gpt-5.1".to_string(),
|
model: "gpt-5.1".to_string(),
|
||||||
reasoning_effort: None,
|
reasoning_effort: None,
|
||||||
|
|||||||
@@ -412,7 +412,7 @@ async fn override_before_first_turn_emits_environment_context() -> anyhow::Resul
|
|||||||
let TestCodex { codex, .. } = test_codex().build(&server).await?;
|
let TestCodex { codex, .. } = test_codex().build(&server).await?;
|
||||||
|
|
||||||
let collaboration_mode = CollaborationMode {
|
let collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model: "gpt-5.1".to_string(),
|
model: "gpt-5.1".to_string(),
|
||||||
reasoning_effort: Some(ReasoningEffort::High),
|
reasoning_effort: Some(ReasoningEffort::High),
|
||||||
|
|||||||
@@ -273,8 +273,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn request_user_input_rejected_in_execute_mode() -> anyhow::Result<()> {
|
async fn request_user_input_rejected_in_legacy_execute_mode_alias() -> anyhow::Result<()> {
|
||||||
assert_request_user_input_rejected("Execute", |model| CollaborationMode {
|
assert_request_user_input_rejected("Default", |model| CollaborationMode {
|
||||||
mode: ModeKind::Execute,
|
mode: ModeKind::Execute,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model,
|
model,
|
||||||
@@ -286,22 +286,9 @@ async fn request_user_input_rejected_in_execute_mode() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn request_user_input_rejected_in_code_mode() -> anyhow::Result<()> {
|
async fn request_user_input_rejected_in_default_mode() -> anyhow::Result<()> {
|
||||||
assert_request_user_input_rejected("Code", |model| CollaborationMode {
|
assert_request_user_input_rejected("Default", |model| CollaborationMode {
|
||||||
mode: ModeKind::Code,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
|
||||||
model,
|
|
||||||
reasoning_effort: None,
|
|
||||||
developer_instructions: None,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
||||||
async fn request_user_input_rejected_in_custom_mode() -> anyhow::Result<()> {
|
|
||||||
assert_request_user_input_rejected("Custom", |model| CollaborationMode {
|
|
||||||
mode: ModeKind::Custom,
|
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model,
|
model,
|
||||||
reasoning_effort: None,
|
reasoning_effort: None,
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ fn task_started_produces_turn_started_event() {
|
|||||||
"t1",
|
"t1",
|
||||||
EventMsg::TurnStarted(codex_core::protocol::TurnStartedEvent {
|
EventMsg::TurnStarted(codex_core::protocol::TurnStartedEvent {
|
||||||
model_context_window: Some(32_000),
|
model_context_window: Some(32_000),
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|||||||
@@ -173,10 +173,23 @@ pub enum AltScreenMode {
|
|||||||
pub enum ModeKind {
|
pub enum ModeKind {
|
||||||
Plan,
|
Plan,
|
||||||
#[default]
|
#[default]
|
||||||
Code,
|
#[serde(
|
||||||
|
alias = "code",
|
||||||
|
alias = "pair_programming",
|
||||||
|
alias = "execute",
|
||||||
|
alias = "custom"
|
||||||
|
)]
|
||||||
|
Default,
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
|
#[schemars(skip)]
|
||||||
|
#[ts(skip)]
|
||||||
PairProgramming,
|
PairProgramming,
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
|
#[schemars(skip)]
|
||||||
|
#[ts(skip)]
|
||||||
Execute,
|
Execute,
|
||||||
Custom,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collaboration mode for a Codex session.
|
/// Collaboration mode for a Codex session.
|
||||||
@@ -276,7 +289,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn apply_mask_can_clear_optional_fields() {
|
fn apply_mask_can_clear_optional_fields() {
|
||||||
let mode = CollaborationMode {
|
let mode = CollaborationMode {
|
||||||
mode: ModeKind::Code,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model: "gpt-5.2-codex".to_string(),
|
model: "gpt-5.2-codex".to_string(),
|
||||||
reasoning_effort: Some(ReasoningEffort::High),
|
reasoning_effort: Some(ReasoningEffort::High),
|
||||||
@@ -292,7 +305,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let expected = CollaborationMode {
|
let expected = CollaborationMode {
|
||||||
mode: ModeKind::Code,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model: "gpt-5.2-codex".to_string(),
|
model: "gpt-5.2-codex".to_string(),
|
||||||
reasoning_effort: None,
|
reasoning_effort: None,
|
||||||
@@ -301,4 +314,13 @@ mod tests {
|
|||||||
};
|
};
|
||||||
assert_eq!(expected, mode.apply_mask(&mask));
|
assert_eq!(expected, mode.apply_mask(&mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mode_kind_deserializes_legacy_values_to_default() {
|
||||||
|
for legacy in ["code", "pair_programming", "execute", "custom"] {
|
||||||
|
let json = format!("\"{legacy}\"");
|
||||||
|
let mode: ModeKind = serde_json::from_str(&json).expect("deserialize mode");
|
||||||
|
assert_eq!(ModeKind::Default, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,8 +73,6 @@ pub(crate) struct FooterProps {
|
|||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
pub(crate) enum CollaborationModeIndicator {
|
pub(crate) enum CollaborationModeIndicator {
|
||||||
Plan,
|
Plan,
|
||||||
PairProgramming,
|
|
||||||
Execute,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const MODE_CYCLE_HINT: &str = "shift+tab to cycle";
|
const MODE_CYCLE_HINT: &str = "shift+tab to cycle";
|
||||||
@@ -89,10 +87,6 @@ impl CollaborationModeIndicator {
|
|||||||
};
|
};
|
||||||
match self {
|
match self {
|
||||||
CollaborationModeIndicator::Plan => format!("Plan mode{suffix}"),
|
CollaborationModeIndicator::Plan => format!("Plan mode{suffix}"),
|
||||||
CollaborationModeIndicator::PairProgramming => {
|
|
||||||
format!("Pair Programming mode{suffix}")
|
|
||||||
}
|
|
||||||
CollaborationModeIndicator::Execute => format!("Execute mode{suffix}"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,8 +94,6 @@ impl CollaborationModeIndicator {
|
|||||||
let label = self.label(show_cycle_hint);
|
let label = self.label(show_cycle_hint);
|
||||||
match self {
|
match self {
|
||||||
CollaborationModeIndicator::Plan => Span::from(label).magenta(),
|
CollaborationModeIndicator::Plan => Span::from(label).magenta(),
|
||||||
CollaborationModeIndicator::PairProgramming => Span::from(label).cyan(),
|
|
||||||
CollaborationModeIndicator::Execute => Span::from(label).dim(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ pub(crate) struct ChatWidget {
|
|||||||
/// where the overlay may briefly treat new tail content as already cached.
|
/// where the overlay may briefly treat new tail content as already cached.
|
||||||
active_cell_revision: u64,
|
active_cell_revision: u64,
|
||||||
config: Config,
|
config: Config,
|
||||||
/// The unmasked collaboration mode settings (always Custom mode).
|
/// The unmasked collaboration mode settings (always Default mode).
|
||||||
///
|
///
|
||||||
/// Masks are applied on top of this base mode to derive the effective mode.
|
/// Masks are applied on top of this base mode to derive the effective mode.
|
||||||
current_collaboration_mode: CollaborationMode,
|
current_collaboration_mode: CollaborationMode,
|
||||||
@@ -1108,8 +1108,8 @@ impl ChatWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_plan_implementation_prompt(&mut self) {
|
fn open_plan_implementation_prompt(&mut self) {
|
||||||
let code_mask = collaboration_modes::code_mask(self.models_manager.as_ref());
|
let default_mask = collaboration_modes::default_mode_mask(self.models_manager.as_ref());
|
||||||
let (implement_actions, implement_disabled_reason) = match code_mask {
|
let (implement_actions, implement_disabled_reason) = match default_mask {
|
||||||
Some(mask) => {
|
Some(mask) => {
|
||||||
let user_text = PLAN_IMPLEMENTATION_CODING_MESSAGE.to_string();
|
let user_text = PLAN_IMPLEMENTATION_CODING_MESSAGE.to_string();
|
||||||
let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
|
let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
|
||||||
@@ -1120,13 +1120,13 @@ impl ChatWidget {
|
|||||||
})];
|
})];
|
||||||
(actions, None)
|
(actions, None)
|
||||||
}
|
}
|
||||||
None => (Vec::new(), Some("Code mode unavailable".to_string())),
|
None => (Vec::new(), Some("Default mode unavailable".to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let items = vec![
|
let items = vec![
|
||||||
SelectionItem {
|
SelectionItem {
|
||||||
name: PLAN_IMPLEMENTATION_YES.to_string(),
|
name: PLAN_IMPLEMENTATION_YES.to_string(),
|
||||||
description: Some("Switch to Code and start coding.".to_string()),
|
description: Some("Switch to Default and start coding.".to_string()),
|
||||||
selected_description: None,
|
selected_description: None,
|
||||||
is_current: false,
|
is_current: false,
|
||||||
actions: implement_actions,
|
actions: implement_actions,
|
||||||
@@ -2216,15 +2216,15 @@ impl ChatWidget {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|mask| mask.model.clone())
|
.and_then(|mask| mask.model.clone())
|
||||||
.unwrap_or_else(|| model_for_header.clone());
|
.unwrap_or_else(|| model_for_header.clone());
|
||||||
let fallback_custom = Settings {
|
let fallback_default = Settings {
|
||||||
model: header_model.clone(),
|
model: header_model.clone(),
|
||||||
reasoning_effort: None,
|
reasoning_effort: None,
|
||||||
developer_instructions: None,
|
developer_instructions: None,
|
||||||
};
|
};
|
||||||
// Collaboration modes start in Custom mode (not activated).
|
// Collaboration modes start in Default mode.
|
||||||
let current_collaboration_mode = CollaborationMode {
|
let current_collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: fallback_custom,
|
settings: fallback_default,
|
||||||
};
|
};
|
||||||
|
|
||||||
let active_cell = Some(Self::placeholder_session_header_cell(&config));
|
let active_cell = Some(Self::placeholder_session_header_cell(&config));
|
||||||
@@ -2361,15 +2361,15 @@ impl ChatWidget {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|mask| mask.model.clone())
|
.and_then(|mask| mask.model.clone())
|
||||||
.unwrap_or_else(|| model_for_header.clone());
|
.unwrap_or_else(|| model_for_header.clone());
|
||||||
let fallback_custom = Settings {
|
let fallback_default = Settings {
|
||||||
model: header_model.clone(),
|
model: header_model.clone(),
|
||||||
reasoning_effort: None,
|
reasoning_effort: None,
|
||||||
developer_instructions: None,
|
developer_instructions: None,
|
||||||
};
|
};
|
||||||
// Collaboration modes start in Custom mode (not activated).
|
// Collaboration modes start in Default mode.
|
||||||
let current_collaboration_mode = CollaborationMode {
|
let current_collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: fallback_custom,
|
settings: fallback_default,
|
||||||
};
|
};
|
||||||
|
|
||||||
let active_cell = Some(Self::placeholder_session_header_cell(&config));
|
let active_cell = Some(Self::placeholder_session_header_cell(&config));
|
||||||
@@ -2497,15 +2497,15 @@ impl ChatWidget {
|
|||||||
let codex_op_tx =
|
let codex_op_tx =
|
||||||
spawn_agent_from_existing(conversation, session_configured, app_event_tx.clone());
|
spawn_agent_from_existing(conversation, session_configured, app_event_tx.clone());
|
||||||
|
|
||||||
let fallback_custom = Settings {
|
let fallback_default = Settings {
|
||||||
model: header_model.clone(),
|
model: header_model.clone(),
|
||||||
reasoning_effort: None,
|
reasoning_effort: None,
|
||||||
developer_instructions: None,
|
developer_instructions: None,
|
||||||
};
|
};
|
||||||
// Collaboration modes start in Custom mode (not activated).
|
// Collaboration modes start in Default mode.
|
||||||
let current_collaboration_mode = CollaborationMode {
|
let current_collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: fallback_custom,
|
settings: fallback_default,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut widget = Self {
|
let mut widget = Self {
|
||||||
@@ -5166,7 +5166,7 @@ impl ChatWidget {
|
|||||||
self.bottom_pane.set_collaboration_modes_enabled(enabled);
|
self.bottom_pane.set_collaboration_modes_enabled(enabled);
|
||||||
let settings = self.current_collaboration_mode.settings.clone();
|
let settings = self.current_collaboration_mode.settings.clone();
|
||||||
self.current_collaboration_mode = CollaborationMode {
|
self.current_collaboration_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings,
|
settings,
|
||||||
};
|
};
|
||||||
self.active_collaboration_mask = None;
|
self.active_collaboration_mask = None;
|
||||||
@@ -5319,7 +5319,7 @@ impl ChatWidget {
|
|||||||
self.active_collaboration_mask
|
self.active_collaboration_mask
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|mask| mask.mode)
|
.and_then(|mask| mask.mode)
|
||||||
.unwrap_or(ModeKind::Custom)
|
.unwrap_or(ModeKind::Default)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn effective_reasoning_effort(&self) -> Option<ReasoningEffortConfig> {
|
fn effective_reasoning_effort(&self) -> Option<ReasoningEffortConfig> {
|
||||||
@@ -5364,10 +5364,8 @@ impl ChatWidget {
|
|||||||
}
|
}
|
||||||
match self.active_mode_kind() {
|
match self.active_mode_kind() {
|
||||||
ModeKind::Plan => Some("Plan"),
|
ModeKind::Plan => Some("Plan"),
|
||||||
ModeKind::Code => Some("Code"),
|
ModeKind::Default => Some("Default"),
|
||||||
ModeKind::PairProgramming => Some("Pair Programming"),
|
ModeKind::PairProgramming | ModeKind::Execute => None,
|
||||||
ModeKind::Execute => Some("Execute"),
|
|
||||||
ModeKind::Custom => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5377,10 +5375,7 @@ impl ChatWidget {
|
|||||||
}
|
}
|
||||||
match self.active_mode_kind() {
|
match self.active_mode_kind() {
|
||||||
ModeKind::Plan => Some(CollaborationModeIndicator::Plan),
|
ModeKind::Plan => Some(CollaborationModeIndicator::Plan),
|
||||||
ModeKind::Code => None,
|
ModeKind::Default | ModeKind::PairProgramming | ModeKind::Execute => None,
|
||||||
ModeKind::PairProgramming => Some(CollaborationModeIndicator::PairProgramming),
|
|
||||||
ModeKind::Execute => Some(CollaborationModeIndicator::Execute),
|
|
||||||
ModeKind::Custom => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5403,7 +5398,7 @@ impl ChatWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cycle to the next collaboration mode variant (Plan -> Code -> Plan).
|
/// Cycle to the next collaboration mode variant (Plan -> Default -> Plan).
|
||||||
fn cycle_collaboration_mode(&mut self) {
|
fn cycle_collaboration_mode(&mut self) {
|
||||||
if !self.collaboration_modes_enabled() {
|
if !self.collaboration_modes_enabled() {
|
||||||
return;
|
return;
|
||||||
@@ -5419,7 +5414,7 @@ impl ChatWidget {
|
|||||||
|
|
||||||
/// Update the active collaboration mask.
|
/// Update the active collaboration mask.
|
||||||
///
|
///
|
||||||
/// When collaboration modes are enabled and a preset is selected (not Custom),
|
/// When collaboration modes are enabled and a preset is selected,
|
||||||
/// the current mode is attached to submissions as `Op::UserTurn { collaboration_mode: Some(...) }`.
|
/// the current mode is attached to submissions as `Op::UserTurn { collaboration_mode: Some(...) }`.
|
||||||
pub(crate) fn set_collaboration_mask(&mut self, mask: CollaborationModeMask) {
|
pub(crate) fn set_collaboration_mask(&mut self, mask: CollaborationModeMask) {
|
||||||
if !self.collaboration_modes_enabled() {
|
if !self.collaboration_modes_enabled() {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ expression: popup
|
|||||||
---
|
---
|
||||||
Implement this plan?
|
Implement this plan?
|
||||||
|
|
||||||
› 1. Yes, implement this plan Switch to Code and start coding.
|
› 1. Yes, implement this plan Switch to Default and start coding.
|
||||||
2. No, stay in Plan mode Continue planning with the model.
|
2. No, stay in Plan mode Continue planning with the model.
|
||||||
|
|
||||||
Press enter to confirm or esc to go back
|
Press enter to confirm or esc to go back
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ expression: popup
|
|||||||
---
|
---
|
||||||
Implement this plan?
|
Implement this plan?
|
||||||
|
|
||||||
1. Yes, implement this plan Switch to Code and start coding.
|
1. Yes, implement this plan Switch to Default and start coding.
|
||||||
› 2. No, stay in Plan mode Continue planning with the model.
|
› 2. No, stay in Plan mode Continue planning with the model.
|
||||||
|
|
||||||
Press enter to confirm or esc to go back
|
Press enter to confirm or esc to go back
|
||||||
|
|||||||
@@ -780,7 +780,7 @@ async fn make_chatwidget_manual(
|
|||||||
let models_manager = Arc::new(ModelsManager::new(codex_home, auth_manager.clone()));
|
let models_manager = Arc::new(ModelsManager::new(codex_home, auth_manager.clone()));
|
||||||
let reasoning_effort = None;
|
let reasoning_effort = None;
|
||||||
let base_mode = CollaborationMode {
|
let base_mode = CollaborationMode {
|
||||||
mode: ModeKind::Custom,
|
mode: ModeKind::Default,
|
||||||
settings: Settings {
|
settings: Settings {
|
||||||
model: resolved_model.clone(),
|
model: resolved_model.clone(),
|
||||||
reasoning_effort,
|
reasoning_effort,
|
||||||
@@ -1211,7 +1211,7 @@ async fn plan_implementation_popup_yes_emits_submit_message_event() {
|
|||||||
panic!("expected SubmitUserMessageWithMode, got {event:?}");
|
panic!("expected SubmitUserMessageWithMode, got {event:?}");
|
||||||
};
|
};
|
||||||
assert_eq!(text, PLAN_IMPLEMENTATION_CODING_MESSAGE);
|
assert_eq!(text, PLAN_IMPLEMENTATION_CODING_MESSAGE);
|
||||||
assert_eq!(collaboration_mode.mode, Some(ModeKind::Code));
|
assert_eq!(collaboration_mode.mode, Some(ModeKind::Default));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -1220,22 +1220,22 @@ async fn submit_user_message_with_mode_sets_coding_collaboration_mode() {
|
|||||||
chat.thread_id = Some(ThreadId::new());
|
chat.thread_id = Some(ThreadId::new());
|
||||||
chat.set_feature_enabled(Feature::CollaborationModes, true);
|
chat.set_feature_enabled(Feature::CollaborationModes, true);
|
||||||
|
|
||||||
let code_mode = collaboration_modes::code_mask(chat.models_manager.as_ref())
|
let default_mode = collaboration_modes::default_mode_mask(chat.models_manager.as_ref())
|
||||||
.expect("expected code collaboration mode");
|
.expect("expected default collaboration mode");
|
||||||
chat.submit_user_message_with_mode("Implement the plan.".to_string(), code_mode);
|
chat.submit_user_message_with_mode("Implement the plan.".to_string(), default_mode);
|
||||||
|
|
||||||
match next_submit_op(&mut op_rx) {
|
match next_submit_op(&mut op_rx) {
|
||||||
Op::UserTurn {
|
Op::UserTurn {
|
||||||
collaboration_mode:
|
collaboration_mode:
|
||||||
Some(CollaborationMode {
|
Some(CollaborationMode {
|
||||||
mode: ModeKind::Code,
|
mode: ModeKind::Default,
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
personality: None,
|
personality: None,
|
||||||
..
|
..
|
||||||
} => {}
|
} => {}
|
||||||
other => {
|
other => {
|
||||||
panic!("expected Op::UserTurn with code collab mode, got {other:?}")
|
panic!("expected Op::UserTurn with default collab mode, got {other:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1982,7 +1982,7 @@ async fn unified_exec_wait_after_final_agent_message_snapshot() {
|
|||||||
id: "turn-1".into(),
|
id: "turn-1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2017,7 +2017,7 @@ async fn unified_exec_wait_before_streamed_agent_message_snapshot() {
|
|||||||
id: "turn-1".into(),
|
id: "turn-1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2228,7 +2228,7 @@ async fn collab_mode_shift_tab_cycles_only_when_enabled_and_idle() {
|
|||||||
let initial = chat.current_collaboration_mode().clone();
|
let initial = chat.current_collaboration_mode().clone();
|
||||||
chat.handle_key_event(KeyEvent::from(KeyCode::BackTab));
|
chat.handle_key_event(KeyEvent::from(KeyCode::BackTab));
|
||||||
assert_eq!(chat.current_collaboration_mode(), &initial);
|
assert_eq!(chat.current_collaboration_mode(), &initial);
|
||||||
assert_eq!(chat.active_collaboration_mode_kind(), ModeKind::Custom);
|
assert_eq!(chat.active_collaboration_mode_kind(), ModeKind::Default);
|
||||||
|
|
||||||
chat.set_feature_enabled(Feature::CollaborationModes, true);
|
chat.set_feature_enabled(Feature::CollaborationModes, true);
|
||||||
|
|
||||||
@@ -2237,7 +2237,7 @@ async fn collab_mode_shift_tab_cycles_only_when_enabled_and_idle() {
|
|||||||
assert_eq!(chat.current_collaboration_mode(), &initial);
|
assert_eq!(chat.current_collaboration_mode(), &initial);
|
||||||
|
|
||||||
chat.handle_key_event(KeyEvent::from(KeyCode::BackTab));
|
chat.handle_key_event(KeyEvent::from(KeyCode::BackTab));
|
||||||
assert_eq!(chat.active_collaboration_mode_kind(), ModeKind::Code);
|
assert_eq!(chat.active_collaboration_mode_kind(), ModeKind::Default);
|
||||||
assert_eq!(chat.current_collaboration_mode(), &initial);
|
assert_eq!(chat.current_collaboration_mode(), &initial);
|
||||||
|
|
||||||
chat.on_task_started();
|
chat.on_task_started();
|
||||||
@@ -2273,7 +2273,7 @@ async fn collab_slash_command_opens_picker_and_updates_mode() {
|
|||||||
Op::UserTurn {
|
Op::UserTurn {
|
||||||
collaboration_mode:
|
collaboration_mode:
|
||||||
Some(CollaborationMode {
|
Some(CollaborationMode {
|
||||||
mode: ModeKind::Code,
|
mode: ModeKind::Default,
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
personality: None,
|
personality: None,
|
||||||
@@ -2291,7 +2291,7 @@ async fn collab_slash_command_opens_picker_and_updates_mode() {
|
|||||||
Op::UserTurn {
|
Op::UserTurn {
|
||||||
collaboration_mode:
|
collaboration_mode:
|
||||||
Some(CollaborationMode {
|
Some(CollaborationMode {
|
||||||
mode: ModeKind::Code,
|
mode: ModeKind::Default,
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
personality: None,
|
personality: None,
|
||||||
@@ -2395,7 +2395,7 @@ async fn collaboration_modes_defaults_to_code_on_startup() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let chat = ChatWidget::new(init, thread_manager);
|
let chat = ChatWidget::new(init, thread_manager);
|
||||||
assert_eq!(chat.active_collaboration_mode_kind(), ModeKind::Code);
|
assert_eq!(chat.active_collaboration_mode_kind(), ModeKind::Default);
|
||||||
assert_eq!(chat.current_model(), resolved_model);
|
assert_eq!(chat.current_model(), resolved_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2501,8 +2501,8 @@ async fn collab_mode_is_not_sent_until_selected() {
|
|||||||
async fn collab_mode_enabling_keeps_custom_until_selected() {
|
async fn collab_mode_enabling_keeps_custom_until_selected() {
|
||||||
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
|
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
|
||||||
chat.set_feature_enabled(Feature::CollaborationModes, true);
|
chat.set_feature_enabled(Feature::CollaborationModes, true);
|
||||||
assert_eq!(chat.active_collaboration_mode_kind(), ModeKind::Custom);
|
assert_eq!(chat.active_collaboration_mode_kind(), ModeKind::Default);
|
||||||
assert_eq!(chat.current_collaboration_mode().mode, ModeKind::Custom);
|
assert_eq!(chat.current_collaboration_mode().mode, ModeKind::Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -2850,7 +2850,7 @@ async fn interrupted_turn_error_message_snapshot() {
|
|||||||
id: "task-1".into(),
|
id: "task-1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -3865,7 +3865,7 @@ async fn interrupt_clears_unified_exec_wait_streak_snapshot() {
|
|||||||
id: "turn-1".into(),
|
id: "turn-1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -3939,7 +3939,7 @@ async fn ui_snapshots_small_heights_task_running() {
|
|||||||
id: "task-1".into(),
|
id: "task-1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
chat.handle_codex_event(Event {
|
chat.handle_codex_event(Event {
|
||||||
@@ -3971,7 +3971,7 @@ async fn status_widget_and_approval_modal_snapshot() {
|
|||||||
id: "task-1".into(),
|
id: "task-1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
// Provide a deterministic header for the status line.
|
// Provide a deterministic header for the status line.
|
||||||
@@ -4024,7 +4024,7 @@ async fn status_widget_active_snapshot() {
|
|||||||
id: "task-1".into(),
|
id: "task-1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
// Provide a deterministic header via a bold reasoning chunk.
|
// Provide a deterministic header via a bold reasoning chunk.
|
||||||
@@ -4074,7 +4074,7 @@ async fn mcp_startup_complete_does_not_clear_running_task() {
|
|||||||
id: "task-1".into(),
|
id: "task-1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -4631,7 +4631,7 @@ async fn stream_recovery_restores_previous_status_header() {
|
|||||||
id: "task".into(),
|
id: "task".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
drain_insert_history(&mut rx);
|
drain_insert_history(&mut rx);
|
||||||
@@ -4669,7 +4669,7 @@ async fn multiple_agent_messages_in_single_turn_emit_multiple_headers() {
|
|||||||
id: "s1".into(),
|
id: "s1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -4864,7 +4864,7 @@ async fn chatwidget_exec_and_status_layout_vt100_snapshot() {
|
|||||||
id: "t1".into(),
|
id: "t1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
chat.handle_codex_event(Event {
|
chat.handle_codex_event(Event {
|
||||||
@@ -4912,7 +4912,7 @@ async fn chatwidget_markdown_code_blocks_vt100_snapshot() {
|
|||||||
id: "t1".into(),
|
id: "t1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
// Build a vt100 visual from the history insertions only (no UI overlay)
|
// Build a vt100 visual from the history insertions only (no UI overlay)
|
||||||
@@ -5002,7 +5002,7 @@ async fn chatwidget_tall() {
|
|||||||
id: "t1".into(),
|
id: "t1".into(),
|
||||||
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
msg: EventMsg::TurnStarted(TurnStartedEvent {
|
||||||
model_context_window: None,
|
model_context_window: None,
|
||||||
collaboration_mode_kind: ModeKind::Custom,
|
collaboration_mode_kind: ModeKind::Default,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
for i in 0..30 {
|
for i in 0..30 {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use codex_protocol::config_types::CollaborationModeMask;
|
|||||||
use codex_protocol::config_types::ModeKind;
|
use codex_protocol::config_types::ModeKind;
|
||||||
|
|
||||||
fn is_tui_mode(kind: ModeKind) -> bool {
|
fn is_tui_mode(kind: ModeKind) -> bool {
|
||||||
matches!(kind, ModeKind::Plan | ModeKind::Code)
|
matches!(kind, ModeKind::Plan | ModeKind::Default)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filtered_presets(models_manager: &ModelsManager) -> Vec<CollaborationModeMask> {
|
fn filtered_presets(models_manager: &ModelsManager) -> Vec<CollaborationModeMask> {
|
||||||
@@ -22,7 +22,7 @@ pub(crate) fn default_mask(models_manager: &ModelsManager) -> Option<Collaborati
|
|||||||
let presets = filtered_presets(models_manager);
|
let presets = filtered_presets(models_manager);
|
||||||
presets
|
presets
|
||||||
.iter()
|
.iter()
|
||||||
.find(|mask| mask.mode == Some(ModeKind::Code))
|
.find(|mask| mask.mode == Some(ModeKind::Default))
|
||||||
.cloned()
|
.cloned()
|
||||||
.or_else(|| presets.into_iter().next())
|
.or_else(|| presets.into_iter().next())
|
||||||
}
|
}
|
||||||
@@ -56,8 +56,8 @@ pub(crate) fn next_mask(
|
|||||||
presets.get(next_index).cloned()
|
presets.get(next_index).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn code_mask(models_manager: &ModelsManager) -> Option<CollaborationModeMask> {
|
pub(crate) fn default_mode_mask(models_manager: &ModelsManager) -> Option<CollaborationModeMask> {
|
||||||
mask_for_kind(models_manager, ModeKind::Code)
|
mask_for_kind(models_manager, ModeKind::Default)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn plan_mask(models_manager: &ModelsManager) -> Option<CollaborationModeMask> {
|
pub(crate) fn plan_mask(models_manager: &ModelsManager) -> Option<CollaborationModeMask> {
|
||||||
|
|||||||
Reference in New Issue
Block a user