mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
Merge branch 'merge/code-branch-20250916-121527' into main
This commit is contained in:
@@ -98,8 +98,8 @@ impl AgentEditorView {
|
||||
let mut v = Self {
|
||||
name,
|
||||
enabled,
|
||||
params_ro: FormTextField::new_single_line(),
|
||||
params_wr: FormTextField::new_single_line(),
|
||||
params_ro: FormTextField::new_multi_line(),
|
||||
params_wr: FormTextField::new_multi_line(),
|
||||
instr: FormTextField::new_multi_line(),
|
||||
field: 0,
|
||||
complete: false,
|
||||
@@ -124,41 +124,39 @@ impl AgentEditorView {
|
||||
}
|
||||
|
||||
fn layout(&self, content_width: u16, max_height: Option<u16>) -> AgentEditorLayout {
|
||||
let single_box_h: u16 = 3;
|
||||
let instr_inner_width = content_width.saturating_sub(4);
|
||||
let desired_instr_inner = self.instr.desired_height(instr_inner_width).min(8);
|
||||
let mut instr_box_h = desired_instr_inner.saturating_add(2);
|
||||
|
||||
let ro_inner_width = content_width.saturating_sub(4);
|
||||
let desired_ro_inner = self.params_ro.desired_height(ro_inner_width).min(6);
|
||||
let ro_box_h = desired_ro_inner.saturating_add(2);
|
||||
let desired_wr_inner = self.params_wr.desired_height(ro_inner_width).min(6);
|
||||
let wr_box_h = desired_wr_inner.saturating_add(2);
|
||||
|
||||
let top_block: u16 = 3; // blank, title, blank
|
||||
let enabled_block: u16 = 2; // row + spacer
|
||||
let ro_label: u16 = 1;
|
||||
let ro_spacer: u16 = 1;
|
||||
let wr_label: u16 = 1;
|
||||
let wr_spacer: u16 = 1;
|
||||
let instr_label: u16 = 1;
|
||||
let enabled_block: u16 = 2; // toggle row + spacer
|
||||
let instr_desc_lines: u16 = 1; // description row after box
|
||||
let spacer_before_buttons: u16 = 1;
|
||||
let buttons_block: u16 = 1;
|
||||
let footer_lines_default: u16 = 2;
|
||||
let footer_lines_default: u16 = 0;
|
||||
|
||||
let base_fixed_top = top_block
|
||||
+ enabled_block
|
||||
+ ro_label
|
||||
+ single_box_h
|
||||
+ ro_spacer
|
||||
+ wr_label
|
||||
+ single_box_h
|
||||
+ wr_spacer
|
||||
+ instr_label;
|
||||
+ ro_box_h
|
||||
+ 1 // blank after read-only box
|
||||
+ wr_box_h
|
||||
+ 1; // blank after write box
|
||||
|
||||
let mut footer_lines = footer_lines_default;
|
||||
let mut spacer_after_instr = spacer_before_buttons;
|
||||
let mut include_gap_before_buttons = spacer_before_buttons > 0;
|
||||
|
||||
if let Some(height) = max_height {
|
||||
let mut fixed_after_box = spacer_before_buttons + buttons_block + footer_lines;
|
||||
let mut fixed_after_box = instr_desc_lines + spacer_before_buttons + buttons_block + footer_lines;
|
||||
if base_fixed_top.saturating_add(instr_box_h).saturating_add(fixed_after_box) > height {
|
||||
footer_lines = 0;
|
||||
}
|
||||
fixed_after_box = spacer_before_buttons + buttons_block + footer_lines;
|
||||
fixed_after_box = instr_desc_lines + spacer_before_buttons + buttons_block + footer_lines;
|
||||
if base_fixed_top.saturating_add(instr_box_h).saturating_add(fixed_after_box) > height {
|
||||
let min_ih: u16 = 3;
|
||||
let available_for_box = height
|
||||
@@ -166,9 +164,9 @@ impl AgentEditorView {
|
||||
.saturating_sub(fixed_after_box);
|
||||
instr_box_h = instr_box_h.min(available_for_box).max(min_ih);
|
||||
}
|
||||
fixed_after_box = spacer_before_buttons + buttons_block + footer_lines;
|
||||
fixed_after_box = instr_desc_lines + spacer_before_buttons + buttons_block + footer_lines;
|
||||
if base_fixed_top.saturating_add(instr_box_h).saturating_add(fixed_after_box) > height {
|
||||
spacer_after_instr = 0;
|
||||
include_gap_before_buttons = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,22 +179,12 @@ impl AgentEditorView {
|
||||
Style::default()
|
||||
}
|
||||
};
|
||||
let label = |idx: usize| {
|
||||
if self.field == idx {
|
||||
Style::default()
|
||||
.fg(crate::colors::primary())
|
||||
.add_modifier(Modifier::BOLD)
|
||||
} else {
|
||||
Style::default()
|
||||
}
|
||||
};
|
||||
|
||||
let mut lines: Vec<Line<'static>> = Vec::new();
|
||||
let mut cursor: u16 = 0;
|
||||
let desc_style = Style::default().fg(crate::colors::text_dim());
|
||||
|
||||
// Top spacer, title, spacer
|
||||
lines.push(Line::from(""));
|
||||
cursor = cursor.saturating_add(1);
|
||||
// Title, spacer
|
||||
lines.push(Line::from(Span::styled(
|
||||
format!("Agents » Edit Agent » {}", self.name),
|
||||
Style::default().add_modifier(Modifier::BOLD),
|
||||
@@ -206,53 +194,74 @@ impl AgentEditorView {
|
||||
cursor = cursor.saturating_add(1);
|
||||
|
||||
// Enabled toggle + spacer
|
||||
let chk = if self.enabled { "[on ]" } else { "[off]" };
|
||||
let enabled_style = if self.enabled {
|
||||
Style::default()
|
||||
.fg(crate::colors::success())
|
||||
.add_modifier(Modifier::BOLD)
|
||||
} else {
|
||||
Style::default().fg(crate::colors::text_dim())
|
||||
};
|
||||
let disabled_style = if self.enabled {
|
||||
Style::default().fg(crate::colors::text_dim())
|
||||
} else {
|
||||
Style::default()
|
||||
.fg(crate::colors::error())
|
||||
.add_modifier(Modifier::BOLD)
|
||||
};
|
||||
let label_style = if self.field == 0 {
|
||||
Style::default()
|
||||
.fg(crate::colors::primary())
|
||||
.add_modifier(Modifier::BOLD)
|
||||
} else {
|
||||
Style::default().fg(crate::colors::text())
|
||||
};
|
||||
let enabled_text = format!("[{}] Enabled", if self.enabled { 'x' } else { ' ' });
|
||||
let disabled_text = format!("[{}] Disabled", if self.enabled { ' ' } else { 'x' });
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled("Enabled:", label(0)),
|
||||
Span::styled("Status:", label_style),
|
||||
Span::raw(" "),
|
||||
Span::styled(chk, sel(0)),
|
||||
Span::styled(enabled_text, enabled_style),
|
||||
Span::raw(" "),
|
||||
Span::styled(disabled_text, disabled_style),
|
||||
]));
|
||||
cursor = cursor.saturating_add(1);
|
||||
lines.push(Line::from(""));
|
||||
cursor = cursor.saturating_add(1);
|
||||
|
||||
// Read-only params label and box
|
||||
lines.push(Line::from(Span::styled("Read-only Params", label(1))));
|
||||
cursor = cursor.saturating_add(1);
|
||||
// Read-only params box
|
||||
let ro_offset = cursor;
|
||||
for _ in 0..single_box_h {
|
||||
for _ in 0..ro_box_h {
|
||||
lines.push(Line::from(""));
|
||||
cursor = cursor.saturating_add(1);
|
||||
}
|
||||
lines.push(Line::from(""));
|
||||
cursor = cursor.saturating_add(1);
|
||||
|
||||
// Write params label and box
|
||||
lines.push(Line::from(Span::styled("Write Params", label(2))));
|
||||
cursor = cursor.saturating_add(1);
|
||||
// Write params box
|
||||
let wr_offset = cursor;
|
||||
for _ in 0..single_box_h {
|
||||
for _ in 0..wr_box_h {
|
||||
lines.push(Line::from(""));
|
||||
cursor = cursor.saturating_add(1);
|
||||
}
|
||||
lines.push(Line::from(""));
|
||||
cursor = cursor.saturating_add(1);
|
||||
|
||||
// Instructions label and box
|
||||
lines.push(Line::from(Span::styled("Instructions", label(3))));
|
||||
cursor = cursor.saturating_add(1);
|
||||
// Instructions box
|
||||
let instr_offset = cursor;
|
||||
for _ in 0..instr_box_h {
|
||||
lines.push(Line::from(""));
|
||||
cursor = cursor.saturating_add(1);
|
||||
}
|
||||
|
||||
if spacer_after_instr > 0 {
|
||||
lines.push(Line::from(""));
|
||||
cursor = cursor.saturating_add(1);
|
||||
}
|
||||
lines.push(Line::from(Span::styled(
|
||||
"Optional guidance prepended to every request sent to the agent.",
|
||||
desc_style,
|
||||
)));
|
||||
lines.push(Line::from(""));
|
||||
|
||||
// Buttons row
|
||||
if include_gap_before_buttons {
|
||||
lines.push(Line::from(""));
|
||||
}
|
||||
let save_style = sel(4).fg(crate::colors::success());
|
||||
let cancel_style = sel(5).fg(crate::colors::text());
|
||||
lines.push(Line::from(vec![
|
||||
@@ -260,21 +269,18 @@ impl AgentEditorView {
|
||||
Span::raw(" "),
|
||||
Span::styled("[ Cancel ]", cancel_style),
|
||||
]));
|
||||
cursor = cursor.saturating_add(1);
|
||||
|
||||
if footer_lines > 0 {
|
||||
lines.push(Line::from(""));
|
||||
cursor = cursor.saturating_add(1);
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled("↑↓", Style::default().fg(crate::colors::function())),
|
||||
Span::styled(" Navigate ", Style::default().fg(crate::colors::text_dim())),
|
||||
Span::styled("Enter", Style::default().fg(crate::colors::success())),
|
||||
Span::styled(" Save/Close ", Style::default().fg(crate::colors::text_dim())),
|
||||
Span::styled("Esc", Style::default().fg(crate::colors::error())),
|
||||
Span::styled(" Cancel", Style::default().fg(crate::colors::text_dim())),
|
||||
]));
|
||||
cursor = cursor.saturating_add(1);
|
||||
// Trim any trailing blank rows so the button row hugs the bottom border
|
||||
while lines
|
||||
.last()
|
||||
.map(|line| line.spans.iter().all(|s| s.content.trim().is_empty()))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
lines.pop();
|
||||
}
|
||||
cursor = lines.len() as u16;
|
||||
|
||||
// No footer hints in the editor form
|
||||
|
||||
debug_assert_eq!(cursor as usize, lines.len());
|
||||
|
||||
@@ -283,8 +289,8 @@ impl AgentEditorView {
|
||||
ro_offset,
|
||||
wr_offset,
|
||||
instr_offset,
|
||||
ro_height: single_box_h,
|
||||
wr_height: single_box_h,
|
||||
ro_height: ro_box_h,
|
||||
wr_height: wr_box_h,
|
||||
instr_height: instr_box_h,
|
||||
}
|
||||
}
|
||||
@@ -303,7 +309,10 @@ impl<'a> BottomPaneView<'a> for AgentEditorView {
|
||||
KeyEvent { code: KeyCode::Esc, .. } => { self.complete = true; self.app_event_tx.send(AppEvent::ShowAgentsOverview); },
|
||||
KeyEvent { code: KeyCode::Up, .. } => { if self.field > 0 { self.field -= 1; } },
|
||||
KeyEvent { code: KeyCode::Down, .. } => { self.field = (self.field + 1).min(5); },
|
||||
KeyEvent { code: KeyCode::Left | KeyCode::Right, .. } if self.field == 0 => { self.enabled = !self.enabled; },
|
||||
KeyEvent { code: KeyCode::Left, .. } if self.field == 0 => { self.enabled = true; },
|
||||
KeyEvent { code: KeyCode::Right, .. } if self.field == 0 => { self.enabled = false; },
|
||||
KeyEvent { code: KeyCode::Left, .. } if self.field == 5 => { self.field = 4; },
|
||||
KeyEvent { code: KeyCode::Right, .. } if self.field == 4 => { self.field = 5; },
|
||||
KeyEvent { code: KeyCode::Char(' '), .. } if self.field == 0 => { self.enabled = !self.enabled; },
|
||||
ev @ KeyEvent { .. } if self.field == 1 => { let _ = self.params_ro.handle_key(ev); },
|
||||
ev @ KeyEvent { .. } if self.field == 2 => { let _ = self.params_wr.handle_key(ev); },
|
||||
@@ -335,7 +344,7 @@ impl<'a> BottomPaneView<'a> for AgentEditorView {
|
||||
fn desired_height(&self, width: u16) -> u16 {
|
||||
let content_width = width.saturating_sub(4).max(1);
|
||||
let layout = self.layout(content_width, None);
|
||||
layout.lines.len().saturating_add(2) as u16
|
||||
layout.lines.len().saturating_add(1) as u16
|
||||
}
|
||||
|
||||
fn render(&self, area: Rect, buf: &mut Buffer) {
|
||||
@@ -408,8 +417,10 @@ impl<'a> BottomPaneView<'a> for AgentEditorView {
|
||||
|
||||
// Instructions (multi-line; height consistent with reserved space above)
|
||||
let instr_rect = Rect { x: content.x, y: content.y.saturating_add(instr_offset), width: content.width, height: instr_height };
|
||||
let instr_block = Block::default().borders(Borders::ALL).border_style(if self.field == 3 { Style::default().fg(crate::colors::primary()).add_modifier(Modifier::BOLD) } else { Style::default().fg(crate::colors::border()) });
|
||||
let instr_block = instr_block.title(Line::from(" Instructions "));
|
||||
let instr_block = Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.title(Line::from(" Instructions "))
|
||||
.border_style(if self.field == 3 { Style::default().fg(crate::colors::primary()).add_modifier(Modifier::BOLD) } else { Style::default().fg(crate::colors::border()) });
|
||||
let instr_inner_rect = instr_block.inner(instr_rect);
|
||||
let instr_inner = instr_inner_rect.inner(Margin::new(1, 0));
|
||||
instr_block.render(instr_rect, buf);
|
||||
|
||||
@@ -36,21 +36,33 @@ impl AgentsOverviewView {
|
||||
|
||||
// Agents section
|
||||
lines.push(Line::from(Span::styled("Agents", Style::default().add_modifier(Modifier::BOLD))));
|
||||
let max_name_len = self
|
||||
.agents
|
||||
.iter()
|
||||
.map(|(name, _, _, _)| name.len())
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
for (i, (name, enabled, installed, _cmd)) in self.agents.iter().enumerate() {
|
||||
let sel = i == self.selected;
|
||||
let dot_style = Style::default().fg(if !*enabled {
|
||||
crate::colors::error()
|
||||
let (status_text, status_color) = if !*enabled {
|
||||
("disabled", crate::colors::error())
|
||||
} else if !*installed {
|
||||
crate::colors::warning()
|
||||
("not installed", crate::colors::warning())
|
||||
} else {
|
||||
crate::colors::success()
|
||||
});
|
||||
("enabled", crate::colors::success())
|
||||
};
|
||||
let dot_style = Style::default().fg(status_color);
|
||||
let name_style = if sel { Style::default().fg(crate::colors::primary()).add_modifier(Modifier::BOLD) } else { Style::default() };
|
||||
let mut spans = vec![
|
||||
Span::styled(if sel { "› " } else { " " }, if sel { Style::default().fg(crate::colors::primary()) } else { Style::default() }),
|
||||
Span::styled(
|
||||
format!("{name:<width$}", name = name, width = max_name_len),
|
||||
name_style,
|
||||
),
|
||||
Span::raw(" "),
|
||||
Span::styled("•", dot_style),
|
||||
Span::raw(" "),
|
||||
Span::styled(name.clone(), name_style),
|
||||
Span::styled(status_text.to_string(), Style::default().fg(status_color)),
|
||||
];
|
||||
if sel {
|
||||
spans.push(Span::raw(" "));
|
||||
|
||||
@@ -226,24 +226,20 @@ impl<'a> BottomPaneView<'a> for SubagentEditorView {
|
||||
let name_box_h: u16 = 3;
|
||||
// Orchestrator inner width accounts for borders (2) and left/right padding (2)
|
||||
let orch_inner_w = (content_w as u16).saturating_sub(4);
|
||||
// Show up to 8 rows initially; allow scrolling inside the field for more
|
||||
let desired_orch_inner = self.orch_field.desired_height(orch_inner_w);
|
||||
let orch_inner_capped = desired_orch_inner.min(8);
|
||||
let orch_box_h = orch_inner_capped.saturating_add(2);
|
||||
let content_rows: u16 = 1 // top spacer
|
||||
+ 1 // title
|
||||
let desired_orch_inner = self.orch_field.desired_height(orch_inner_w).max(1);
|
||||
let orch_box_h = desired_orch_inner.min(8).saturating_add(2).max(3);
|
||||
let base_rows: u16 = 1 // title
|
||||
+ 1 // spacer after title
|
||||
+ name_box_h
|
||||
+ 1 // spacer
|
||||
+ 1 // mode row
|
||||
+ 1 // spacer
|
||||
+ 1 // spacer before agents
|
||||
+ 1 // agents row
|
||||
+ 1 // spacer
|
||||
+ orch_box_h // orchestrator box
|
||||
+ 1 // spacer
|
||||
+ 1 // buttons
|
||||
+ 1; // bottom spacer
|
||||
(content_rows + 2).clamp(8, 50)
|
||||
+ 1; // spacer before instructions box
|
||||
let rows_after_orch: u16 = 1 // spacer after instructions box
|
||||
+ 1; // buttons row
|
||||
let total_rows = base_rows + orch_box_h + rows_after_orch;
|
||||
total_rows.saturating_add(2).clamp(8, 50)
|
||||
}
|
||||
|
||||
fn render(&self, area: Rect, buf: &mut Buffer) {
|
||||
@@ -263,8 +259,6 @@ impl<'a> BottomPaneView<'a> for SubagentEditorView {
|
||||
let sel = |idx: usize| if self.field == idx { Style::default().bg(crate::colors::selection()).add_modifier(Modifier::BOLD) } else { Style::default() };
|
||||
let label = |idx: usize| if self.field == idx { Style::default().fg(crate::colors::primary()).add_modifier(Modifier::BOLD) } else { Style::default() };
|
||||
|
||||
// Top spacer
|
||||
lines.push(Line::from(""));
|
||||
// Bold title
|
||||
lines.push(Line::from(Span::styled("Agents » Edit Command", Style::default().add_modifier(Modifier::BOLD))));
|
||||
// Spacer after title
|
||||
@@ -313,17 +307,10 @@ impl<'a> BottomPaneView<'a> for SubagentEditorView {
|
||||
|
||||
// Spacer between inputs
|
||||
lines.push(Line::from(""));
|
||||
// Reserve rows for the orchestrator box (height = inner + borders)
|
||||
// Clamp to available height so we never overflow the buffer.
|
||||
let desired_orch_inner_h = self
|
||||
.orch_field
|
||||
.desired_height(content_rect.width.saturating_sub(4));
|
||||
// Cap visible inner height to 8 rows; overflow is scrollable via caret moves
|
||||
let desired_orch_box_h = desired_orch_inner_h.min(8).saturating_add(2);
|
||||
let available_h = content_rect.height; // total rows available for all content
|
||||
let base_rows_without_orch: u16 = 14; // all rows except the orch box
|
||||
let max_orch_box_h = available_h.saturating_sub(base_rows_without_orch);
|
||||
let orch_box_h_reserved = desired_orch_box_h.min(max_orch_box_h);
|
||||
// Reserve rows for the instructions box (height = inner + borders)
|
||||
let orch_inner_w = content_rect.width.saturating_sub(4);
|
||||
let desired_orch_inner = self.orch_field.desired_height(orch_inner_w).max(1);
|
||||
let orch_box_h_reserved = desired_orch_inner.min(8).saturating_add(2).max(3);
|
||||
for _ in 0..orch_box_h_reserved { lines.push(Line::from("")); }
|
||||
// Spacer between inputs
|
||||
lines.push(Line::from(""));
|
||||
@@ -358,8 +345,14 @@ impl<'a> BottomPaneView<'a> for SubagentEditorView {
|
||||
btn_spans.push(Span::styled("[ Cancel ]", cancel_style));
|
||||
lines.push(Line::from(btn_spans));
|
||||
}
|
||||
// Bottom spacer
|
||||
lines.push(Line::from(""));
|
||||
// Remove any trailing blank lines so buttons hug the bottom frame
|
||||
while lines
|
||||
.last()
|
||||
.map(|line| line.spans.iter().all(|s| s.content.trim().is_empty()))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
lines.pop();
|
||||
}
|
||||
|
||||
let paragraph = Paragraph::new(lines)
|
||||
.alignment(Alignment::Left)
|
||||
@@ -371,8 +364,8 @@ impl<'a> BottomPaneView<'a> for SubagentEditorView {
|
||||
let content_w = content_rect.width;
|
||||
let mut y = content_rect.y;
|
||||
|
||||
// Skip top spacer + title + spacer
|
||||
y = y.saturating_add(3);
|
||||
// Skip title + spacer
|
||||
y = y.saturating_add(2);
|
||||
// Row: Name box with title; height fixed (3)
|
||||
let name_box_rect = Rect { x: content_rect.x, y, width: content_w, height: name_box_h };
|
||||
let name_border = if self.field == 0 { Style::default().fg(crate::colors::primary()).add_modifier(Modifier::BOLD) } else { Style::default().fg(crate::colors::border()) };
|
||||
|
||||
@@ -165,17 +165,17 @@ impl BottomPane<'_> {
|
||||
.map(|r| r.desired_height(width))
|
||||
.unwrap_or(0);
|
||||
|
||||
let view_height = if let Some(view) = self.active_view.as_ref() {
|
||||
view.desired_height(width)
|
||||
let (view_height, pad_lines) = if let Some(view) = self.active_view.as_ref() {
|
||||
(view.desired_height(width), 0)
|
||||
} else {
|
||||
// Optionally add 1 for the empty line above the composer
|
||||
let spacer = if self.top_spacer_enabled { 1 } else { 0 };
|
||||
spacer + self.composer.desired_height(width)
|
||||
(spacer + self.composer.desired_height(width), Self::BOTTOM_PAD_LINES)
|
||||
};
|
||||
|
||||
ring_h
|
||||
.saturating_add(view_height)
|
||||
.saturating_add(Self::BOTTOM_PAD_LINES)
|
||||
.saturating_add(pad_lines)
|
||||
}
|
||||
|
||||
pub fn cursor_pos(&self, area: Rect) -> Option<(u16, u16)> {
|
||||
@@ -735,7 +735,11 @@ impl WidgetRef for &BottomPane<'_> {
|
||||
if y_offset < area.height {
|
||||
// Reserve bottom padding lines; keep at least 1 line for the view.
|
||||
let avail = area.height - y_offset;
|
||||
let pad = BottomPane::BOTTOM_PAD_LINES.min(avail.saturating_sub(1));
|
||||
let pad = if self.active_view.is_some() {
|
||||
0
|
||||
} else {
|
||||
BottomPane::BOTTOM_PAD_LINES.min(avail.saturating_sub(1))
|
||||
};
|
||||
// Add horizontal padding (2 chars on each side) for views
|
||||
let horizontal_padding = 1u16;
|
||||
let view_rect = Rect {
|
||||
|
||||
@@ -15,6 +15,7 @@ use codex_common::model_presets::ModelPreset;
|
||||
use codex_common::model_presets::builtin_model_presets;
|
||||
use codex_core::ConversationManager;
|
||||
use codex_core::config::Config;
|
||||
use codex_core::config_types::AgentConfig;
|
||||
use codex_core::config_types::ReasoningEffort;
|
||||
use codex_core::config_types::TextVerbosity;
|
||||
use codex_core::model_family::derive_default_model_family;
|
||||
@@ -4720,6 +4721,7 @@ impl ChatWidget<'_> {
|
||||
args_wr: Option<Vec<String>>,
|
||||
instr: Option<String>,
|
||||
) {
|
||||
let mut updated_existing = false;
|
||||
if let Some(slot) = self
|
||||
.config
|
||||
.agents
|
||||
@@ -4730,6 +4732,23 @@ impl ChatWidget<'_> {
|
||||
slot.args_read_only = args_ro.clone();
|
||||
slot.args_write = args_wr.clone();
|
||||
slot.instructions = instr.clone();
|
||||
updated_existing = true;
|
||||
}
|
||||
|
||||
if !updated_existing {
|
||||
let new_cfg = AgentConfig {
|
||||
name: name.to_string(),
|
||||
command: name.to_string(),
|
||||
args: Vec::new(),
|
||||
read_only: false,
|
||||
enabled,
|
||||
description: None,
|
||||
env: None,
|
||||
args_read_only: args_ro.clone(),
|
||||
args_write: args_wr.clone(),
|
||||
instructions: instr.clone(),
|
||||
};
|
||||
self.config.agents.push(new_cfg);
|
||||
}
|
||||
// Persist asynchronously
|
||||
if let Ok(home) = codex_core::config::find_codex_home() {
|
||||
|
||||
Reference in New Issue
Block a user