logiguard fork v3: full patch set on verified 8c74db0 tree

Includes prior-session patches (carry forward so the app compiles):
  - crates/gpui/build.rs: cross-compile manifest fix
  - crates/gpui/src/platform.rs: PlatformWindow::activate_with_token trait method
  - crates/gpui/src/window.rs: Window::activate_with_token public API
  - crates/gpui_linux/src/linux/wayland/window.rs: WaylandWindow::activate_with_token + activate() keyboard-serial fix

Plus the focus-serial fix:
  - serial.rs: SerialKind::KeyboardEnter
  - client.rs: store wl_keyboard.enter serial; latest_serial_of()

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Mohamad Khani
2026-07-14 01:52:12 +03:30
commit b9819977a5
3984 changed files with 1487015 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
[package]
name = "web_search_providers"
version = "0.1.0"
edition.workspace = true
publish.workspace = true
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/web_search_providers.rs"
[dependencies]
anyhow.workspace = true
client.workspace = true
cloud_api_client.workspace = true
cloud_api_types.workspace = true
cloud_llm_client.workspace = true
futures.workspace = true
gpui.workspace = true
http_client.workspace = true
language_model.workspace = true
serde.workspace = true
serde_json.workspace = true
web_search.workspace = true

View File

@@ -0,0 +1 @@
../../LICENSE-GPL

View File

@@ -0,0 +1,95 @@
use std::sync::Arc;
use anyhow::Result;
use client::{Client, UserStore, global_llm_token};
use cloud_api_client::LlmApiToken;
use cloud_api_types::OrganizationId;
use cloud_llm_client::{WebSearchBody, WebSearchResponse};
use futures::AsyncReadExt as _;
use gpui::{App, AppContext, Context, Entity, Task};
use http_client::Method;
use web_search::{WebSearchProvider, WebSearchProviderId};
pub struct CloudWebSearchProvider {
state: Entity<State>,
}
impl CloudWebSearchProvider {
pub fn new(client: Arc<Client>, user_store: Entity<UserStore>, cx: &mut App) -> Self {
let state = cx.new(|cx| State::new(client, user_store, cx));
Self { state }
}
}
pub struct State {
client: Arc<Client>,
user_store: Entity<UserStore>,
llm_api_token: LlmApiToken,
}
impl State {
pub fn new(client: Arc<Client>, user_store: Entity<UserStore>, cx: &mut Context<Self>) -> Self {
let llm_api_token = global_llm_token(cx);
Self {
client,
user_store,
llm_api_token,
}
}
}
pub const ZED_WEB_SEARCH_PROVIDER_ID: &str = "zed.dev";
impl WebSearchProvider for CloudWebSearchProvider {
fn id(&self) -> WebSearchProviderId {
WebSearchProviderId(ZED_WEB_SEARCH_PROVIDER_ID.into())
}
fn search(&self, query: String, cx: &mut App) -> Task<Result<WebSearchResponse>> {
let state = self.state.read(cx);
let client = state.client.clone();
let llm_api_token = state.llm_api_token.clone();
let organization_id = state
.user_store
.read(cx)
.current_organization()
.map(|organization| organization.id.clone());
let body = WebSearchBody { query };
cx.background_spawn(async move {
perform_web_search(client, llm_api_token, organization_id, body).await
})
}
}
async fn perform_web_search(
client: Arc<Client>,
llm_api_token: LlmApiToken,
organization_id: Option<OrganizationId>,
body: WebSearchBody,
) -> Result<WebSearchResponse> {
let url = client.http_client().build_zed_llm_url("/web_search", &[])?;
let body = serde_json::to_string(&body)?;
let mut response = client
.authenticated_llm_request(&llm_api_token, organization_id, |token| {
Ok(http_client::Request::builder()
.method(Method::POST)
.uri(url.as_ref())
.header("Content-Type", "application/json")
.header("Authorization", format!("Bearer {token}"))
.body(body.clone().into())?)
})
.await?;
if response.status().is_success() {
let mut body = String::new();
response.body_mut().read_to_string(&mut body).await?;
Ok(serde_json::from_str(&body)?)
} else {
let status = response.status();
let mut body = String::new();
response.body_mut().read_to_string(&mut body).await?;
anyhow::bail!("error performing web search.\nStatus: {status:?}\nBody: {body}");
}
}

View File

@@ -0,0 +1,68 @@
mod cloud;
use client::{Client, UserStore};
use gpui::{App, Context, Entity};
use language_model::LanguageModelRegistry;
use std::sync::Arc;
use web_search::{WebSearchProviderId, WebSearchRegistry};
pub fn init(client: Arc<Client>, user_store: Entity<UserStore>, cx: &mut App) {
let registry = WebSearchRegistry::global(cx);
registry.update(cx, |registry, cx| {
register_web_search_providers(registry, client, user_store, cx);
});
}
fn register_web_search_providers(
registry: &mut WebSearchRegistry,
client: Arc<Client>,
user_store: Entity<UserStore>,
cx: &mut Context<WebSearchRegistry>,
) {
register_zed_web_search_provider(
registry,
client.clone(),
user_store.clone(),
&LanguageModelRegistry::global(cx),
cx,
);
cx.subscribe(
&LanguageModelRegistry::global(cx),
move |this, registry, event, cx| {
if let language_model::Event::DefaultModelChanged = event {
register_zed_web_search_provider(
this,
client.clone(),
user_store.clone(),
&registry,
cx,
)
}
},
)
.detach();
}
fn register_zed_web_search_provider(
registry: &mut WebSearchRegistry,
client: Arc<Client>,
user_store: Entity<UserStore>,
language_model_registry: &Entity<LanguageModelRegistry>,
cx: &mut Context<WebSearchRegistry>,
) {
let using_zed_provider = language_model_registry
.read(cx)
.default_model()
.is_some_and(|default| default.is_provided_by_zed());
if using_zed_provider {
registry.register_provider(
cloud::CloudWebSearchProvider::new(client, user_store, cx),
cx,
)
} else {
registry.unregister_provider(WebSearchProviderId(
cloud::ZED_WEB_SEARCH_PROVIDER_ID.into(),
));
}
}