assistant: Improve JSON handling in /fetch
command (#12864)
This PR improves the `/fetch` command with better support for URLs that return JSON content. JSON response bodies will now be pretty-printed and placed within a Markdown code block: <img width="690" alt="Screenshot 2024-06-10 at 3 39 52 PM" src="https://github.com/zed-industries/zed/assets/1486634/4a7c1cb7-9f5b-4a63-9e8e-5168bf9a6625"> Release Notes: - Improved the handling of JSON response bodies in the `/fetch` command in the Assistant.
This commit is contained in:
parent
8078e58494
commit
2509af723f
1 changed files with 49 additions and 16 deletions
|
@ -11,6 +11,13 @@ use language::LspAdapterDelegate;
|
||||||
use ui::{prelude::*, ButtonLike, ElevationIndex};
|
use ui::{prelude::*, ButtonLike, ElevationIndex};
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||||
|
enum ContentType {
|
||||||
|
Html,
|
||||||
|
Plaintext,
|
||||||
|
Json,
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct FetchSlashCommand;
|
pub(crate) struct FetchSlashCommand;
|
||||||
|
|
||||||
impl FetchSlashCommand {
|
impl FetchSlashCommand {
|
||||||
|
@ -37,24 +44,50 @@ impl FetchSlashCommand {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut handlers: Vec<Box<dyn HandleTag>> = vec![
|
let Some(content_type) = response.headers().get("content-type") else {
|
||||||
Box::new(markdown::ParagraphHandler),
|
bail!("missing Content-Type header");
|
||||||
Box::new(markdown::HeadingHandler),
|
};
|
||||||
Box::new(markdown::ListHandler),
|
let content_type = content_type
|
||||||
Box::new(markdown::TableHandler::new()),
|
.to_str()
|
||||||
Box::new(markdown::StyledTextHandler),
|
.context("invalid Content-Type header")?;
|
||||||
];
|
let content_type = match content_type {
|
||||||
if url.contains("wikipedia.org") {
|
"text/html" => ContentType::Html,
|
||||||
use html_to_markdown::structure::wikipedia;
|
"text/plain" => ContentType::Plaintext,
|
||||||
|
"application/json" => ContentType::Json,
|
||||||
|
_ => ContentType::Html,
|
||||||
|
};
|
||||||
|
|
||||||
handlers.push(Box::new(wikipedia::WikipediaChromeRemover));
|
match content_type {
|
||||||
handlers.push(Box::new(wikipedia::WikipediaInfoboxHandler));
|
ContentType::Html => {
|
||||||
handlers.push(Box::new(wikipedia::WikipediaCodeHandler::new()));
|
let mut handlers: Vec<Box<dyn HandleTag>> = vec![
|
||||||
} else {
|
Box::new(markdown::ParagraphHandler),
|
||||||
handlers.push(Box::new(markdown::CodeHandler));
|
Box::new(markdown::HeadingHandler),
|
||||||
|
Box::new(markdown::ListHandler),
|
||||||
|
Box::new(markdown::TableHandler::new()),
|
||||||
|
Box::new(markdown::StyledTextHandler),
|
||||||
|
];
|
||||||
|
if url.contains("wikipedia.org") {
|
||||||
|
use html_to_markdown::structure::wikipedia;
|
||||||
|
|
||||||
|
handlers.push(Box::new(wikipedia::WikipediaChromeRemover));
|
||||||
|
handlers.push(Box::new(wikipedia::WikipediaInfoboxHandler));
|
||||||
|
handlers.push(Box::new(wikipedia::WikipediaCodeHandler::new()));
|
||||||
|
} else {
|
||||||
|
handlers.push(Box::new(markdown::CodeHandler));
|
||||||
|
}
|
||||||
|
|
||||||
|
convert_html_to_markdown(&body[..], handlers)
|
||||||
|
}
|
||||||
|
ContentType::Plaintext => Ok(std::str::from_utf8(&body)?.to_owned()),
|
||||||
|
ContentType::Json => {
|
||||||
|
let json: serde_json::Value = serde_json::from_slice(&body)?;
|
||||||
|
|
||||||
|
Ok(format!(
|
||||||
|
"```json\n{}\n```",
|
||||||
|
serde_json::to_string_pretty(&json)?
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
convert_html_to_markdown(&body[..], handlers)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue