feat(tui): add markdown rendering support and toggle command
- Introduce new `owlen-markdown` crate that converts Markdown strings to `ratatui::Text` with headings, lists, bold/italic, and inline code. - Add `render_markdown` config option (default true) and expose it via `app.render_markdown_enabled()`. - Implement `:markdown [on|off]` command to toggle markdown rendering. - Update help overlay to document the new markdown toggle. - Adjust UI rendering to conditionally apply markdown styling based on the markdown flag and code mode. - Wire the new crate into `owlen-tui` Cargo.toml.
This commit is contained in:
@@ -53,8 +53,8 @@ fn extract_resource_content(value: &Value) -> Option<String> {
|
||||
Value::Array(items) => {
|
||||
let mut segments = Vec::new();
|
||||
for item in items {
|
||||
if let Some(segment) = extract_resource_content(item)
|
||||
&& !segment.is_empty()
|
||||
if let Some(segment) =
|
||||
extract_resource_content(item).filter(|segment| !segment.is_empty())
|
||||
{
|
||||
segments.push(segment);
|
||||
}
|
||||
@@ -69,17 +69,19 @@ fn extract_resource_content(value: &Value) -> Option<String> {
|
||||
const PREFERRED_FIELDS: [&str; 6] =
|
||||
["content", "contents", "text", "value", "body", "data"];
|
||||
for key in PREFERRED_FIELDS.iter() {
|
||||
if let Some(inner) = map.get(*key)
|
||||
&& let Some(text) = extract_resource_content(inner)
|
||||
&& !text.is_empty()
|
||||
if let Some(text) = map
|
||||
.get(*key)
|
||||
.and_then(extract_resource_content)
|
||||
.filter(|text| !text.is_empty())
|
||||
{
|
||||
return Some(text);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(inner) = map.get("chunks")
|
||||
&& let Some(text) = extract_resource_content(inner)
|
||||
&& !text.is_empty()
|
||||
if let Some(text) = map
|
||||
.get("chunks")
|
||||
.and_then(extract_resource_content)
|
||||
.filter(|text| !text.is_empty())
|
||||
{
|
||||
return Some(text);
|
||||
}
|
||||
@@ -566,9 +568,10 @@ impl SessionController {
|
||||
.expect("Consent manager mutex poisoned");
|
||||
consent.grant_consent(tool_name, data_types, endpoints);
|
||||
|
||||
if let Some(vault) = &self.vault
|
||||
&& let Err(e) = consent.persist_to_vault(vault)
|
||||
{
|
||||
let Some(vault) = &self.vault else {
|
||||
return;
|
||||
};
|
||||
if let Err(e) = consent.persist_to_vault(vault) {
|
||||
eprintln!("Warning: Failed to persist consent to vault: {}", e);
|
||||
}
|
||||
}
|
||||
@@ -588,10 +591,13 @@ impl SessionController {
|
||||
consent.grant_consent_with_scope(tool_name, data_types, endpoints, scope);
|
||||
|
||||
// Only persist to vault for permanent consent
|
||||
if is_permanent
|
||||
&& let Some(vault) = &self.vault
|
||||
&& let Err(e) = consent.persist_to_vault(vault)
|
||||
{
|
||||
if !is_permanent {
|
||||
return;
|
||||
}
|
||||
let Some(vault) = &self.vault else {
|
||||
return;
|
||||
};
|
||||
if let Err(e) = consent.persist_to_vault(vault) {
|
||||
eprintln!("Warning: Failed to persist consent to vault: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user