use crate::config_edit::RealFileIo;
use crate::config_edit::brazen::{
BUILT_IN_ROWS_HINT, BrazenEditor, BrazenPaths, BzRunner, ProviderRow, RealBzRunner, row_views,
};
use crate::theme;
use crate::xdg::Env;
use super::RELOAD_HINT;
use super::status::{describe_applied, reload_status, status_line};
const NO_WALL_HINT: &str = "focus a workspace to edit its providers — brazen's config, sign-ins and \
model cache live inside a workspace, not on the machine";
pub struct BrazenPane {
io: RealFileIo,
bz: RealBzRunner,
pub(crate) editor: Option<BrazenEditor>,
pub(crate) status: String,
effective: String,
pub(crate) providers: Vec<ProviderRow>,
creds: Vec<(String, bool)>,
}
impl BrazenPane {
pub fn new(wall: &Env) -> Self {
let io = RealFileIo;
Self {
io,
bz: RealBzRunner::resolve(wall),
editor: BrazenPaths::of(wall).and_then(|paths| BrazenEditor::load(paths, &io).ok()),
status: String::new(),
effective: String::new(),
providers: Vec::new(),
creds: Vec::new(),
}
}
pub(crate) fn open(&mut self) {
if let Some(editor) = self.editor.as_mut() {
let _ = editor.refresh(&self.io);
}
self.providers = self.bz.providers();
self.creds = self
.editor
.as_ref()
.map(|e| e.credential_presence(&self.providers, &self.io))
.unwrap_or_default();
}
}
pub(crate) fn render(ui: &mut egui::Ui, pane: &mut BrazenPane) {
ui.heading(egui::RichText::new("brazen config.toml").color(theme::integration_hue("bz")));
if pane.editor.is_none() {
ui.weak(NO_WALL_HINT);
return;
}
provider_table(ui, pane);
ui.weak(BUILT_IN_ROWS_HINT);
egui::CollapsingHeader::new("raw config.toml — validated by bz before it lands")
.show(ui, |ui| {
let Some(editor) = pane.editor.as_mut() else {
return;
};
super::form_ui::raw_editor(ui, editor.draft_mut());
ui.horizontal(|ui| {
if ui
.button("Apply")
.on_hover_text(
"Hand this TOML to bz to validate, and write it to config.toml \
only if bz accepts it. A file changed underneath you is \
refused, not overwritten. Typed, it is `/config brazen \
<text…>`.",
)
.clicked()
{
pane.status = describe_applied(editor.apply(&pane.bz, &pane.io));
}
if ui.button("Reload").on_hover_text(RELOAD_HINT).clicked() {
pane.status = reload_status(editor.reload(&pane.io));
}
if ui
.button("Effective (bz --dump-config)")
.on_hover_text(
"Ask bz what configuration it actually ends up with once every \
layer and built-in is folded in, and print it below. Reachable \
by Tab, pressed with Space.",
)
.clicked()
{
pane.effective = editor.effective(&pane.bz).stdout;
}
});
status_line(ui, &pane.status);
if !pane.effective.is_empty() {
ui.monospace(&pane.effective);
}
})
.header_response
.on_hover_text(
"Open brazen's config.toml raw — the providers and credentials every \
model call is routed through. Editing there changes nothing until Apply. \
Reachable by Tab, pressed with Space.",
);
}
fn provider_table(ui: &mut egui::Ui, pane: &BrazenPane) {
if pane.providers.is_empty() {
ui.weak("brazen listed no provider rows — reopen the pane to ask again");
return;
}
for row in row_views(&pane.providers, &pane.creds) {
ui.horizontal(|ui| {
super::super::row::bounded(ui);
ui.monospace(&row.name);
ui.weak(&row.fact);
});
if let Some(why) = &row.blocked {
ui.scope(|ui| {
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Wrap);
ui.colored_label(theme::ASH, why);
});
}
}
}