mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
This PR replicates the `tui` code directory and creates a temporary parallel `tui_app_server` directory. It also implements a new feature flag `tui_app_server` to select between the two tui implementations. Once the new app-server-based TUI is stabilized, we'll delete the old `tui` directory and feature flag.
123 lines
5.2 KiB
Rust
123 lines
5.2 KiB
Rust
use codex_core::models_manager::collaboration_mode_presets::CollaborationModesConfig;
|
|
use codex_protocol::config_types::CollaborationModeMask;
|
|
use codex_protocol::config_types::ModeKind;
|
|
use codex_protocol::config_types::TUI_VISIBLE_COLLABORATION_MODES;
|
|
use codex_protocol::openai_models::ModelPreset;
|
|
use codex_protocol::openai_models::ReasoningEffort;
|
|
use std::convert::Infallible;
|
|
|
|
const COLLABORATION_MODE_PLAN: &str =
|
|
include_str!("../../core/templates/collaboration_mode/plan.md");
|
|
const COLLABORATION_MODE_DEFAULT: &str =
|
|
include_str!("../../core/templates/collaboration_mode/default.md");
|
|
const KNOWN_MODE_NAMES_PLACEHOLDER: &str = "{{KNOWN_MODE_NAMES}}";
|
|
const REQUEST_USER_INPUT_AVAILABILITY_PLACEHOLDER: &str = "{{REQUEST_USER_INPUT_AVAILABILITY}}";
|
|
const ASKING_QUESTIONS_GUIDANCE_PLACEHOLDER: &str = "{{ASKING_QUESTIONS_GUIDANCE}}";
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub(crate) struct ModelCatalog {
|
|
models: Vec<ModelPreset>,
|
|
collaboration_modes_config: CollaborationModesConfig,
|
|
}
|
|
|
|
impl ModelCatalog {
|
|
pub(crate) fn new(
|
|
models: Vec<ModelPreset>,
|
|
collaboration_modes_config: CollaborationModesConfig,
|
|
) -> Self {
|
|
Self {
|
|
models,
|
|
collaboration_modes_config,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn try_list_models(&self) -> Result<Vec<ModelPreset>, Infallible> {
|
|
Ok(self.models.clone())
|
|
}
|
|
|
|
pub(crate) fn list_collaboration_modes(&self) -> Vec<CollaborationModeMask> {
|
|
builtin_collaboration_mode_presets(self.collaboration_modes_config)
|
|
}
|
|
}
|
|
|
|
fn builtin_collaboration_mode_presets(
|
|
collaboration_modes_config: CollaborationModesConfig,
|
|
) -> Vec<CollaborationModeMask> {
|
|
vec![plan_preset(), default_preset(collaboration_modes_config)]
|
|
}
|
|
|
|
fn plan_preset() -> CollaborationModeMask {
|
|
CollaborationModeMask {
|
|
name: ModeKind::Plan.display_name().to_string(),
|
|
mode: Some(ModeKind::Plan),
|
|
model: None,
|
|
reasoning_effort: Some(Some(ReasoningEffort::Medium)),
|
|
developer_instructions: Some(Some(COLLABORATION_MODE_PLAN.to_string())),
|
|
}
|
|
}
|
|
|
|
fn default_preset(collaboration_modes_config: CollaborationModesConfig) -> CollaborationModeMask {
|
|
CollaborationModeMask {
|
|
name: ModeKind::Default.display_name().to_string(),
|
|
mode: Some(ModeKind::Default),
|
|
model: None,
|
|
reasoning_effort: None,
|
|
developer_instructions: Some(Some(default_mode_instructions(collaboration_modes_config))),
|
|
}
|
|
}
|
|
|
|
fn default_mode_instructions(collaboration_modes_config: CollaborationModesConfig) -> String {
|
|
let known_mode_names = format_mode_names(&TUI_VISIBLE_COLLABORATION_MODES);
|
|
let request_user_input_availability = request_user_input_availability_message(
|
|
ModeKind::Default,
|
|
collaboration_modes_config.default_mode_request_user_input,
|
|
);
|
|
let asking_questions_guidance = asking_questions_guidance_message(
|
|
collaboration_modes_config.default_mode_request_user_input,
|
|
);
|
|
COLLABORATION_MODE_DEFAULT
|
|
.replace(KNOWN_MODE_NAMES_PLACEHOLDER, &known_mode_names)
|
|
.replace(
|
|
REQUEST_USER_INPUT_AVAILABILITY_PLACEHOLDER,
|
|
&request_user_input_availability,
|
|
)
|
|
.replace(
|
|
ASKING_QUESTIONS_GUIDANCE_PLACEHOLDER,
|
|
&asking_questions_guidance,
|
|
)
|
|
}
|
|
|
|
fn format_mode_names(modes: &[ModeKind]) -> String {
|
|
let mode_names: Vec<&str> = modes.iter().map(|mode| mode.display_name()).collect();
|
|
match mode_names.as_slice() {
|
|
[] => "none".to_string(),
|
|
[mode_name] => (*mode_name).to_string(),
|
|
[first, second] => format!("{first} and {second}"),
|
|
[..] => mode_names.join(", "),
|
|
}
|
|
}
|
|
|
|
fn request_user_input_availability_message(
|
|
mode: ModeKind,
|
|
default_mode_request_user_input: bool,
|
|
) -> String {
|
|
let mode_name = mode.display_name();
|
|
if mode.allows_request_user_input()
|
|
|| (default_mode_request_user_input && mode == ModeKind::Default)
|
|
{
|
|
format!("The `request_user_input` tool is available in {mode_name} mode.")
|
|
} else {
|
|
format!(
|
|
"The `request_user_input` tool is unavailable in {mode_name} mode. If you call it while in {mode_name} mode, it will return an error."
|
|
)
|
|
}
|
|
}
|
|
|
|
fn asking_questions_guidance_message(default_mode_request_user_input: bool) -> String {
|
|
if default_mode_request_user_input {
|
|
"In Default mode, strongly prefer making reasonable assumptions and executing the user's request rather than stopping to ask questions. If you absolutely must ask a question because the answer cannot be discovered from local context and a reasonable assumption would be risky, prefer using the `request_user_input` tool rather than writing a multiple choice question as a textual assistant message. Never write a multiple choice question as a textual assistant message.".to_string()
|
|
} else {
|
|
"In Default mode, strongly prefer making reasonable assumptions and executing the user's request rather than stopping to ask questions. If you absolutely must ask a question because the answer cannot be discovered from local context and a reasonable assumption would be risky, ask the user directly with a concise plain-text question. Never write a multiple choice question as a textual assistant message.".to_string()
|
|
}
|
|
}
|