Detailed changes
@@ -20,7 +20,6 @@ Other platforms are not yet available:
- [Building Zed for macOS](./docs/src/development/macos.md)
- [Building Zed for Linux](./docs/src/development/linux.md)
- [Building Zed for Windows](./docs/src/development/windows.md)
-- [Running Collaboration Locally](./docs/src/development/local-collaboration.md)
### Contributing
@@ -1,7 +1,7 @@
use crate::acp::AcpThreadView;
use crate::{AgentPanel, RemoveHistory, RemoveSelectedThread};
use agent::{HistoryEntry, HistoryStore};
-use chrono::{Datelike as _, Local, NaiveDate, TimeDelta};
+use chrono::{Datelike as _, Local, NaiveDate, TimeDelta, Utc};
use editor::{Editor, EditorEvent};
use fuzzy::StringMatchCandidate;
use gpui::{
@@ -402,7 +402,22 @@ impl AcpThreadHistory {
let selected = ix == self.selected_index;
let hovered = Some(ix) == self.hovered_index;
let timestamp = entry.updated_at().timestamp();
- let thread_timestamp = format.format_timestamp(timestamp, self.local_timezone);
+
+ let display_text = match format {
+ EntryTimeFormat::DateAndTime => {
+ let entry_time = entry.updated_at();
+ let now = Utc::now();
+ let duration = now.signed_duration_since(entry_time);
+ let days = duration.num_days();
+
+ format!("{}d", days)
+ }
+ EntryTimeFormat::TimeOnly => format.format_timestamp(timestamp, self.local_timezone),
+ };
+
+ let title = entry.title().clone();
+ let full_date =
+ EntryTimeFormat::DateAndTime.format_timestamp(timestamp, self.local_timezone);
h_flex()
.w_full()
@@ -423,11 +438,14 @@ impl AcpThreadHistory {
.truncate(),
)
.child(
- Label::new(thread_timestamp)
+ Label::new(display_text)
.color(Color::Muted)
.size(LabelSize::XSmall),
),
)
+ .tooltip(move |_, cx| {
+ Tooltip::with_meta(title.clone(), None, full_date.clone(), cx)
+ })
.on_hover(cx.listener(move |this, is_hovered, _window, cx| {
if *is_hovered {
this.hovered_index = Some(ix);
@@ -1,5 +1,5 @@
use agent::{HistoryEntry, HistoryStore};
-use chrono::{Datelike as _, Local, NaiveDate, TimeDelta};
+use chrono::{Datelike as _, Local, NaiveDate, TimeDelta, Utc};
use editor::{Editor, EditorEvent};
use fuzzy::StringMatchCandidate;
use gpui::{
@@ -411,7 +411,22 @@ impl AcpThreadHistory {
let selected = ix == self.selected_index;
let hovered = Some(ix) == self.hovered_index;
let timestamp = entry.updated_at().timestamp();
- let thread_timestamp = format.format_timestamp(timestamp, self.local_timezone);
+
+ let display_text = match format {
+ EntryTimeFormat::DateAndTime => {
+ let entry_time = entry.updated_at();
+ let now = Utc::now();
+ let duration = now.signed_duration_since(entry_time);
+ let days = duration.num_days();
+
+ format!("{}d", days)
+ }
+ EntryTimeFormat::TimeOnly => format.format_timestamp(timestamp, self.local_timezone),
+ };
+
+ let title = entry.title().clone();
+ let full_date =
+ EntryTimeFormat::DateAndTime.format_timestamp(timestamp, self.local_timezone);
h_flex()
.w_full()
@@ -432,11 +447,14 @@ impl AcpThreadHistory {
.truncate(),
)
.child(
- Label::new(thread_timestamp)
+ Label::new(display_text)
.color(Color::Muted)
.size(LabelSize::XSmall),
),
)
+ .tooltip(move |_, cx| {
+ Tooltip::with_meta(title.clone(), None, full_date.clone(), cx)
+ })
.on_hover(cx.listener(move |this, is_hovered, _window, cx| {
if *is_hovered {
this.hovered_index = Some(ix);
@@ -249,33 +249,7 @@ impl LanguageModelProvider for OllamaLanguageModelProvider {
}
// Override with available models from settings
- for setting_model in &OllamaLanguageModelProvider::settings(cx).available_models {
- let setting_base = setting_model.name.split(':').next().unwrap();
- if let Some(model) = models
- .values_mut()
- .find(|m| m.name.split(':').next().unwrap() == setting_base)
- {
- model.max_tokens = setting_model.max_tokens;
- model.display_name = setting_model.display_name.clone();
- model.keep_alive = setting_model.keep_alive.clone();
- model.supports_tools = setting_model.supports_tools;
- model.supports_vision = setting_model.supports_images;
- model.supports_thinking = setting_model.supports_thinking;
- } else {
- models.insert(
- setting_model.name.clone(),
- ollama::Model {
- name: setting_model.name.clone(),
- display_name: setting_model.display_name.clone(),
- max_tokens: setting_model.max_tokens,
- keep_alive: setting_model.keep_alive.clone(),
- supports_tools: setting_model.supports_tools,
- supports_vision: setting_model.supports_images,
- supports_thinking: setting_model.supports_thinking,
- },
- );
- }
- }
+ merge_settings_into_models(&mut models, &settings.available_models);
let mut models = models
.into_values()
@@ -921,6 +895,35 @@ impl Render for ConfigurationView {
}
}
+fn merge_settings_into_models(
+ models: &mut HashMap<String, ollama::Model>,
+ available_models: &[AvailableModel],
+) {
+ for setting_model in available_models {
+ if let Some(model) = models.get_mut(&setting_model.name) {
+ model.max_tokens = setting_model.max_tokens;
+ model.display_name = setting_model.display_name.clone();
+ model.keep_alive = setting_model.keep_alive.clone();
+ model.supports_tools = setting_model.supports_tools;
+ model.supports_vision = setting_model.supports_images;
+ model.supports_thinking = setting_model.supports_thinking;
+ } else {
+ models.insert(
+ setting_model.name.clone(),
+ ollama::Model {
+ name: setting_model.name.clone(),
+ display_name: setting_model.display_name.clone(),
+ max_tokens: setting_model.max_tokens,
+ keep_alive: setting_model.keep_alive.clone(),
+ supports_tools: setting_model.supports_tools,
+ supports_vision: setting_model.supports_images,
+ supports_thinking: setting_model.supports_thinking,
+ },
+ );
+ }
+ }
+}
+
fn tool_into_ollama(tool: LanguageModelRequestTool) -> ollama::OllamaTool {
ollama::OllamaTool::Function {
function: OllamaFunctionTool {
@@ -930,3 +933,83 @@ fn tool_into_ollama(tool: LanguageModelRequestTool) -> ollama::OllamaTool {
},
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_merge_settings_preserves_display_names_for_similar_models() {
+ // Regression test for https://github.com/zed-industries/zed/issues/43646
+ // When multiple models share the same base name (e.g., qwen2.5-coder:1.5b and qwen2.5-coder:3b),
+ // each model should get its own display_name from settings, not a random one.
+
+ let mut models: HashMap<String, ollama::Model> = HashMap::new();
+ models.insert(
+ "qwen2.5-coder:1.5b".to_string(),
+ ollama::Model {
+ name: "qwen2.5-coder:1.5b".to_string(),
+ display_name: None,
+ max_tokens: 4096,
+ keep_alive: None,
+ supports_tools: None,
+ supports_vision: None,
+ supports_thinking: None,
+ },
+ );
+ models.insert(
+ "qwen2.5-coder:3b".to_string(),
+ ollama::Model {
+ name: "qwen2.5-coder:3b".to_string(),
+ display_name: None,
+ max_tokens: 4096,
+ keep_alive: None,
+ supports_tools: None,
+ supports_vision: None,
+ supports_thinking: None,
+ },
+ );
+
+ let available_models = vec![
+ AvailableModel {
+ name: "qwen2.5-coder:1.5b".to_string(),
+ display_name: Some("QWEN2.5 Coder 1.5B".to_string()),
+ max_tokens: 5000,
+ keep_alive: None,
+ supports_tools: Some(true),
+ supports_images: None,
+ supports_thinking: None,
+ },
+ AvailableModel {
+ name: "qwen2.5-coder:3b".to_string(),
+ display_name: Some("QWEN2.5 Coder 3B".to_string()),
+ max_tokens: 6000,
+ keep_alive: None,
+ supports_tools: Some(true),
+ supports_images: None,
+ supports_thinking: None,
+ },
+ ];
+
+ merge_settings_into_models(&mut models, &available_models);
+
+ let model_1_5b = models
+ .get("qwen2.5-coder:1.5b")
+ .expect("1.5b model missing");
+ let model_3b = models.get("qwen2.5-coder:3b").expect("3b model missing");
+
+ assert_eq!(
+ model_1_5b.display_name,
+ Some("QWEN2.5 Coder 1.5B".to_string()),
+ "1.5b model should have its own display_name"
+ );
+ assert_eq!(model_1_5b.max_tokens, 5000);
+
+ assert_eq!(
+ model_3b.display_name,
+ Some("QWEN2.5 Coder 3B".to_string()),
+ "3b model should have its own display_name"
+ );
+ assert_eq!(model_3b.max_tokens, 6000);
+ }
+}
@@ -191,7 +191,6 @@
- [Linux](./development/linux.md)
- [Windows](./development/windows.md)
- [FreeBSD](./development/freebsd.md)
- - [Local Collaboration](./development/local-collaboration.md)
- [Using Debuggers](./development/debuggers.md)
- [Performance](./performance.md)
- [Glossary](./development/glossary.md)
@@ -6,10 +6,6 @@ See the platform-specific instructions for building Zed from source:
- [Linux](./development/linux.md)
- [Windows](./development/windows.md)
-If you'd like to develop collaboration features, additionally see:
-
-- [Local Collaboration](./development/local-collaboration.md)
-
## Keychain access
Zed stores secrets in the system keychain.
@@ -16,10 +16,6 @@ Clone down the [Zed repository](https://github.com/zed-industries/zed).
If you prefer to install the system libraries manually, you can find the list of required packages in the `script/linux` file.
-### Backend Dependencies (optional) {#backend-dependencies}
-
-If you are looking to develop Zed collaboration features using a local collaboration server, please see: [Local Collaboration](./local-collaboration.md) docs.
-
### Linkers {#linker}
On Linux, Rust's default linker is [LLVM's `lld`](https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/). Alternative linkers, especially [Wild](https://github.com/davidlattimore/wild) and [Mold](https://github.com/rui314/mold) can significantly improve clean and incremental build time.
@@ -1,207 +0,0 @@
-# Local Collaboration
-
-1. Ensure you have access to our cloud infrastructure. If you don't have access, you can't collaborate locally at this time.
-
-2. Make sure you've installed Zed's dependencies for your platform:
-
-- [macOS](#macos)
-- [Linux](#linux)
-- [Windows](#backend-windows)
-
-Note that `collab` can be compiled only with MSVC toolchain on Windows
-
-3. Clone down our cloud repository and follow the instructions in the cloud README
-
-4. Setup the local database for your platform:
-
-- [macOS & Linux](#database-unix)
-- [Windows](#database-windows)
-
-5. Run collab:
-
-- [macOS & Linux](#run-collab-unix)
-- [Windows](#run-collab-windows)
-
-## Backend Dependencies
-
-If you are developing collaborative features of Zed, you'll need to install the dependencies of zed's `collab` server:
-
-- PostgreSQL
-- LiveKit
-- Foreman
-
-You can install these dependencies natively or run them under Docker.
-
-### macOS
-
-1. Install [Postgres.app](https://postgresapp.com) or [postgresql via homebrew](https://formulae.brew.sh/formula/postgresql@15):
-
- ```sh
- brew install postgresql@15
- ```
-
-2. Install [Livekit](https://formulae.brew.sh/formula/livekit) and [Foreman](https://formulae.brew.sh/formula/foreman)
-
- ```sh
- brew install livekit foreman
- ```
-
-- Follow the steps in the [collab README](https://github.com/zed-industries/zed/blob/main/crates/collab/README.md) to configure the Postgres database for integration tests
-
-Alternatively, if you have [Docker](https://www.docker.com/) installed you can bring up all the `collab` dependencies using Docker Compose.
-
-### Linux
-
-1. Install [Postgres](https://www.postgresql.org/download/linux/)
-
- ```sh
- sudo apt-get install postgresql # Ubuntu/Debian
- sudo pacman -S postgresql # Arch Linux
- sudo dnf install postgresql postgresql-server # RHEL/Fedora
- sudo zypper install postgresql postgresql-server # OpenSUSE
- ```
-
-2. Install [Livekit](https://github.com/livekit/livekit-cli)
-
- ```sh
- curl -sSL https://get.livekit.io/cli | bash
- ```
-
-3. Install [Foreman](https://theforeman.org/manuals/3.15/quickstart_guide.html)
-
-### Windows {#backend-windows}
-
-> This section is still in development. The instructions are not yet complete.
-
-- Install [Postgres](https://www.postgresql.org/download/windows/)
-- Install [Livekit](https://github.com/livekit/livekit), optionally you can add the `livekit-server` binary to your `PATH`.
-
-Alternatively, if you have [Docker](https://www.docker.com/) installed you can bring up all the `collab` dependencies using Docker Compose.
-
-### Docker {#Docker}
-
-If you have docker or podman available, you can run the backend dependencies inside containers with Docker Compose:
-
-```sh
-docker compose up -d
-```
-
-## Database setup
-
-Before you can run the `collab` server locally, you'll need to set up a `zed` Postgres database.
-
-### On macOS and Linux {#database-unix}
-
-```sh
-script/bootstrap
-```
-
-This script will set up the `zed` Postgres database, and populate it with some users. It requires internet access, because it fetches some users from the GitHub API.
-
-The script will seed the database with various content defined by:
-
-```sh
-cat crates/collab/seed.default.json
-```
-
-To use a different set of admin users, you can create your own version of that json file and export the `SEED_PATH` environment variable. Note that the usernames listed in the admins list currently must correspond to valid GitHub users.
-
-```json [settings]
-{
- "admins": ["admin1", "admin2"],
- "channels": ["zed"]
-}
-```
-
-### On Windows {#database-windows}
-
-```powershell
-.\script\bootstrap.ps1
-```
-
-## Testing collaborative features locally
-
-### On macOS and Linux {#run-collab-unix}
-
-Ensure that Postgres is configured and running, then run Zed's collaboration server and the `livekit` dev server:
-
-```sh
-foreman start
-# OR
-docker compose up
-```
-
-Alternatively, if you're not testing voice and screenshare, you can just run `collab` and `cloud`, and not the `livekit` dev server:
-
-```sh
-cargo run -p collab -- serve all
-```
-
-```sh
-cd ../cloud; cargo make dev
-```
-
-In a new terminal, run two or more instances of Zed.
-
-```sh
-script/zed-local -3
-```
-
-This script starts one to four instances of Zed, depending on the `-2`, `-3` or `-4` flags. Each instance will be connected to the local `collab` server, signed in as a different user from `.admins.json` or `.admins.default.json`.
-
-### On Windows {#run-collab-windows}
-
-Since `foreman` is not available on Windows, you can run the following commands in separate terminals:
-
-```powershell
-cargo run --package=collab -- serve all
-```
-
-If you have added the `livekit-server` binary to your `PATH`, you can run:
-
-```powershell
-livekit-server --dev
-```
-
-Otherwise,
-
-```powershell
-.\path\to\livekit-serve.exe --dev
-```
-
-You'll also need to start the cloud server:
-
-```powershell
-cd ..\cloud; cargo make dev
-```
-
-In a new terminal, run two or more instances of Zed.
-
-```powershell
-node .\script\zed-local -2
-```
-
-Note that this requires `node.exe` to be in your `PATH`.
-
-## Running a local collab server
-
-> [!NOTE]
-> Because of recent changes to our authentication system, Zed will not be able to authenticate itself with, and therefore use, a local collab server.
-
-If you want to run your own version of the zed collaboration service, you can, but note that this is still under development, and there is no support for authentication nor extensions.
-
-Configuration is done through environment variables. By default it will read the configuration from [`.env.toml`](https://github.com/zed-industries/zed/blob/main/crates/collab/.env.toml) and you should use that as a guide for setting this up.
-
-By default Zed assumes that the DATABASE_URL is a Postgres database, but you can make it use Sqlite by compiling with `--features sqlite` and using a sqlite DATABASE_URL with `?mode=rwc`.
-
-To authenticate you must first configure the server by creating a seed.json file that contains at a minimum your github handle. This will be used to create the user on demand.
-
-```json [settings]
-{
- "admins": ["nathansobo"]
-}
-```
-
-By default the collab server will seed the database when first creating it, but if you want to add more users you can explicitly reseed them with `SEED_PATH=./seed.json cargo run -p collab seed`
-
-Then when running the zed client you must specify two environment variables, `ZED_ADMIN_API_TOKEN` (which should match the value of `API_TOKEN` in .env.toml) and `ZED_IMPERSONATE` (which should match one of the users in your seed.json)
@@ -31,10 +31,6 @@ Clone down the [Zed repository](https://github.com/zed-industries/zed).
brew install cmake
```
-### Backend Dependencies (optional) {#backend-dependencies}
-
-If you are looking to develop Zed collaboration features using a local collaboration server, please see: [Local Collaboration](./local-collaboration.md) docs.
-
## Building Zed from Source
Once you have the dependencies installed, you can build Zed using [Cargo](https://doc.rust-lang.org/cargo/).
@@ -66,10 +66,6 @@ The list can be obtained as follows:
- Click on `More` in the `Installed` tab
- Click on `Export configuration`
-### Backend Dependencies (optional) {#backend-dependencies}
-
-If you are looking to develop Zed collaboration features using a local collaboration server, please see: [Local Collaboration](./local-collaboration.md) docs.
-
### Notes
You should modify the `pg_hba.conf` file in the `data` directory to use `trust` instead of `scram-sha-256` for the `host` method. Otherwise, the connection will fail with the error `password authentication failed`. The `pg_hba.conf` file typically locates at `C:\Program Files\PostgreSQL\17\data\pg_hba.conf`. After the modification, the file should look like this:
@@ -8,6 +8,6 @@
},
"devDependencies": {
"danger": "13.0.4",
- "danger-plugin-pr-hygiene": "0.7.0"
+ "danger-plugin-pr-hygiene": "0.7.1"
}
}
@@ -12,8 +12,8 @@ importers:
specifier: 13.0.4
version: 13.0.4
danger-plugin-pr-hygiene:
- specifier: 0.7.0
- version: 0.7.0
+ specifier: 0.7.1
+ version: 0.7.1
packages:
@@ -134,8 +134,8 @@ packages:
core-js@3.45.1:
resolution: {integrity: sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg==}
- danger-plugin-pr-hygiene@0.7.0:
- resolution: {integrity: sha512-YDWhEodP0fg/t9YO3SxufWS9j1Rcxbig+1flTlUlojBDFiKQyVmaj8PIvnJxJItjHWTlNKI9wMSRq5vUql6zyA==}
+ danger-plugin-pr-hygiene@0.7.1:
+ resolution: {integrity: sha512-ll070nNaL3OeO2nooYWflPE/CRKLeq8GiH2C68u5zM3gW4gepH89GhVv0sYNNGLx4cYwa1zZ/TuiYYhC49z06Q==}
danger@13.0.4:
resolution: {integrity: sha512-IAdQ5nSJyIs4zKj6AN35ixt2B0Ce3WZUm3IFe/CMnL/Op7wV7IGg4D348U0EKNaNPP58QgXbdSk9pM+IXP1QXg==}
@@ -573,7 +573,7 @@ snapshots:
core-js@3.45.1: {}
- danger-plugin-pr-hygiene@0.7.0: {}
+ danger-plugin-pr-hygiene@0.7.1: {}
danger@13.0.4:
dependencies: