Move Perplexity extension to dedicated repository (#34070)
Move Perplexity extension to: https://github.com/zed-extensions/perplexity Release Notes: - N/A
This commit is contained in:
parent
263080c4c4
commit
684e14e55b
8 changed files with 0 additions and 241 deletions
|
@ -33,7 +33,6 @@ workspace-members = [
|
|||
"zed_emmet",
|
||||
"zed_glsl",
|
||||
"zed_html",
|
||||
"perplexity",
|
||||
"zed_proto",
|
||||
"zed_ruff",
|
||||
"slash_commands_example",
|
||||
|
|
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -11350,14 +11350,6 @@ version = "2.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "perplexity"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"zed_extension_api 0.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.8.0"
|
||||
|
|
|
@ -189,7 +189,6 @@ members = [
|
|||
"extensions/emmet",
|
||||
"extensions/glsl",
|
||||
"extensions/html",
|
||||
"extensions/perplexity",
|
||||
"extensions/proto",
|
||||
"extensions/ruff",
|
||||
"extensions/slash-commands-example",
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
[package]
|
||||
name = "perplexity"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
license = "Apache-2.0"
|
||||
|
||||
[lib]
|
||||
path = "src/perplexity.rs"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde = "1"
|
||||
zed_extension_api = { path = "../../crates/extension_api" }
|
|
@ -1 +0,0 @@
|
|||
../../LICENSE-APACHE
|
|
@ -1,43 +0,0 @@
|
|||
# Zed Perplexity Extension
|
||||
|
||||
This example extension adds the `/perplexity` [slash command](https://zed.dev/docs/assistant/commands) to the Zed AI assistant.
|
||||
|
||||
## Usage
|
||||
|
||||
Open the AI Assistant panel (`cmd-r` or `ctrl-r`) and enter:
|
||||
|
||||
```
|
||||
/perplexity What's the weather in Boulder, CO tomorrow evening?
|
||||
```
|
||||
|
||||
## Development Setup
|
||||
|
||||
1. Install the Rust toolchain and clone the zed repo:
|
||||
|
||||
```
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
|
||||
mkdir -p ~/code
|
||||
cd ~/code
|
||||
git clone https://github.com/zed-industries/zed
|
||||
```
|
||||
|
||||
1. Open Zed
|
||||
1. Open Zed Extensions (`cmd-shift-x` / `ctrl-shift-x`)
|
||||
1. Click "Install Dev Extension"
|
||||
1. Navigate to the "extensions/perplexity" folder inside the zed git repo.
|
||||
1. Ensure your `PERPLEXITY_API_KEY` environment variable is set (instructions below)
|
||||
|
||||
```sh
|
||||
env | grep PERPLEXITY_API_KEY
|
||||
```
|
||||
|
||||
1. Quit and relaunch Zed
|
||||
|
||||
## PERPLEXITY_API_KEY
|
||||
|
||||
This extension requires a Perplexity API key to be available via the `PERPLEXITY_API_KEY` environment variable.
|
||||
|
||||
To obtain a Perplexity.ai API token, login to your Perplexity.ai account and go [Settings->API](https://www.perplexity.ai/settings/api) and under "API Keys" click "Generate". This will require you to have [Perplexity Pro](https://www.perplexity.ai/pro) or to buy API credits. By default the extension uses `llama-3.1-sonar-small-128k-online`, currently cheapest model available which is roughly half a penny per request + a penny per 50,000 tokens. So most requests will cost less than $0.01 USD.
|
||||
|
||||
Take your API key and add it to your environment by adding `export PERPLEXITY_API_KEY="pplx-0123456789abcdef..."` to your `~/.zshrc` or `~/.bashrc`. Reload close and reopen your terminal session. Check with `env |grep PERPLEXITY_API_KEY`.
|
|
@ -1,12 +0,0 @@
|
|||
id = "perplexity"
|
||||
name = "Perplexity"
|
||||
version = "0.1.0"
|
||||
description = "Ask questions to Perplexity AI directly from Zed"
|
||||
authors = ["Zed Industries <support@zed.dev>"]
|
||||
repository = "https://github.com/zed-industries/zed"
|
||||
schema_version = 1
|
||||
|
||||
[slash_commands.perplexity]
|
||||
description = "Ask a question to Perplexity AI"
|
||||
requires_argument = true
|
||||
tooltip_text = "Ask Perplexity"
|
|
@ -1,158 +0,0 @@
|
|||
use zed::{
|
||||
http_client::HttpMethod,
|
||||
http_client::HttpRequest,
|
||||
serde_json::{self, json},
|
||||
};
|
||||
use zed_extension_api::{self as zed, Result, http_client::RedirectPolicy};
|
||||
|
||||
struct Perplexity;
|
||||
|
||||
impl zed::Extension for Perplexity {
|
||||
fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn run_slash_command(
|
||||
&self,
|
||||
command: zed::SlashCommand,
|
||||
argument: Vec<String>,
|
||||
worktree: Option<&zed::Worktree>,
|
||||
) -> zed::Result<zed::SlashCommandOutput> {
|
||||
// Check if the command is 'perplexity'
|
||||
if command.name != "perplexity" {
|
||||
return Err("Invalid command. Expected 'perplexity'.".into());
|
||||
}
|
||||
|
||||
let worktree = worktree.ok_or("Worktree is required")?;
|
||||
// Join arguments with space as the query
|
||||
let query = argument.join(" ");
|
||||
if query.is_empty() {
|
||||
return Ok(zed::SlashCommandOutput {
|
||||
text: "Error: Query not provided. Please enter a question or topic.".to_string(),
|
||||
sections: vec![],
|
||||
});
|
||||
}
|
||||
|
||||
// Get the API key from the environment
|
||||
let env_vars = worktree.shell_env();
|
||||
let api_key = env_vars
|
||||
.iter()
|
||||
.find(|(key, _)| key == "PERPLEXITY_API_KEY")
|
||||
.map(|(_, value)| value.clone())
|
||||
.ok_or("PERPLEXITY_API_KEY not found in environment")?;
|
||||
|
||||
// Prepare the request
|
||||
let request = HttpRequest {
|
||||
method: HttpMethod::Post,
|
||||
url: "https://api.perplexity.ai/chat/completions".to_string(),
|
||||
headers: vec![
|
||||
("Authorization".to_string(), format!("Bearer {}", api_key)),
|
||||
("Content-Type".to_string(), "application/json".to_string()),
|
||||
],
|
||||
body: Some(
|
||||
serde_json::to_vec(&json!({
|
||||
"model": "llama-3.1-sonar-small-128k-online",
|
||||
"messages": [{"role": "user", "content": query}],
|
||||
"stream": true,
|
||||
}))
|
||||
.unwrap(),
|
||||
),
|
||||
redirect_policy: RedirectPolicy::FollowAll,
|
||||
};
|
||||
|
||||
// Make the HTTP request
|
||||
match zed::http_client::fetch_stream(&request) {
|
||||
Ok(stream) => {
|
||||
let mut full_content = String::new();
|
||||
let mut buffer = String::new();
|
||||
while let Ok(Some(chunk)) = stream.next_chunk() {
|
||||
buffer.push_str(&String::from_utf8_lossy(&chunk));
|
||||
for line in buffer.lines() {
|
||||
if let Some(json) = line.strip_prefix("data: ") {
|
||||
if let Ok(event) = serde_json::from_str::<StreamEvent>(json) {
|
||||
if let Some(choice) = event.choices.first() {
|
||||
full_content.push_str(&choice.delta.content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer.clear();
|
||||
}
|
||||
Ok(zed::SlashCommandOutput {
|
||||
text: full_content,
|
||||
sections: vec![],
|
||||
})
|
||||
}
|
||||
Err(e) => Ok(zed::SlashCommandOutput {
|
||||
text: format!("API request failed. Error: {}. API Key: {}", e, api_key),
|
||||
sections: vec![],
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn complete_slash_command_argument(
|
||||
&self,
|
||||
_command: zed::SlashCommand,
|
||||
query: Vec<String>,
|
||||
) -> zed::Result<Vec<zed::SlashCommandArgumentCompletion>> {
|
||||
let suggestions = vec!["How do I develop a Zed extension?"];
|
||||
let query = query.join(" ").to_lowercase();
|
||||
|
||||
Ok(suggestions
|
||||
.into_iter()
|
||||
.filter(|suggestion| suggestion.to_lowercase().contains(&query))
|
||||
.map(|suggestion| zed::SlashCommandArgumentCompletion {
|
||||
label: suggestion.to_string(),
|
||||
new_text: suggestion.to_string(),
|
||||
run_command: true,
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
fn language_server_command(
|
||||
&mut self,
|
||||
_language_server_id: &zed_extension_api::LanguageServerId,
|
||||
_worktree: &zed_extension_api::Worktree,
|
||||
) -> Result<zed_extension_api::Command> {
|
||||
Err("Not implemented".into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct StreamEvent {
|
||||
id: String,
|
||||
model: String,
|
||||
created: u64,
|
||||
usage: Usage,
|
||||
object: String,
|
||||
choices: Vec<Choice>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Usage {
|
||||
prompt_tokens: u32,
|
||||
completion_tokens: u32,
|
||||
total_tokens: u32,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Choice {
|
||||
index: u32,
|
||||
finish_reason: Option<String>,
|
||||
message: Message,
|
||||
delta: Delta,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Message {
|
||||
role: String,
|
||||
content: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Delta {
|
||||
role: String,
|
||||
content: String,
|
||||
}
|
||||
|
||||
zed::register_extension!(Perplexity);
|
Loading…
Add table
Add a link
Reference in a new issue