Extract an agent_ui crate from agent (#33284)
This PR moves the UI-dependent logic in the `agent` crate into its own crate, `agent_ui`. The remaining `agent` crate no longer depends on `editor`, `picker`, `ui`, `workspace`, etc. This has compile time benefits, but the main motivation is to isolate our core agentic logic, so that we can make agents more pluggable/configurable. Release Notes: - N/A
This commit is contained in:
parent
371b7355d3
commit
2283ec5de2
62 changed files with 865 additions and 752 deletions
121
Cargo.lock
generated
121
Cargo.lock
generated
|
@ -56,49 +56,28 @@ dependencies = [
|
||||||
"agent_settings",
|
"agent_settings",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"assistant_context_editor",
|
"assistant_context_editor",
|
||||||
"assistant_slash_command",
|
|
||||||
"assistant_slash_commands",
|
|
||||||
"assistant_tool",
|
"assistant_tool",
|
||||||
"assistant_tools",
|
"assistant_tools",
|
||||||
"audio",
|
|
||||||
"buffer_diff",
|
|
||||||
"chrono",
|
"chrono",
|
||||||
"client",
|
"client",
|
||||||
"collections",
|
"collections",
|
||||||
"component",
|
"component",
|
||||||
"context_server",
|
"context_server",
|
||||||
"convert_case 0.8.0",
|
"convert_case 0.8.0",
|
||||||
"db",
|
|
||||||
"editor",
|
|
||||||
"extension",
|
|
||||||
"extension_host",
|
|
||||||
"feature_flags",
|
"feature_flags",
|
||||||
"file_icons",
|
|
||||||
"fs",
|
"fs",
|
||||||
"futures 0.3.31",
|
"futures 0.3.31",
|
||||||
"fuzzy",
|
|
||||||
"git",
|
"git",
|
||||||
"gpui",
|
"gpui",
|
||||||
"heed",
|
"heed",
|
||||||
"html_to_markdown",
|
|
||||||
"http_client",
|
"http_client",
|
||||||
"indexed_docs",
|
"icons",
|
||||||
"indoc",
|
"indoc",
|
||||||
"inventory",
|
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"jsonschema",
|
|
||||||
"language",
|
"language",
|
||||||
"language_model",
|
"language_model",
|
||||||
"log",
|
"log",
|
||||||
"lsp",
|
|
||||||
"markdown",
|
|
||||||
"menu",
|
|
||||||
"multi_buffer",
|
|
||||||
"notifications",
|
|
||||||
"ordered-float 2.10.1",
|
|
||||||
"parking_lot",
|
|
||||||
"paths",
|
"paths",
|
||||||
"picker",
|
|
||||||
"postage",
|
"postage",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"project",
|
"project",
|
||||||
|
@ -106,35 +85,22 @@ dependencies = [
|
||||||
"proto",
|
"proto",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"ref-cast",
|
"ref-cast",
|
||||||
"release_channel",
|
|
||||||
"rope",
|
"rope",
|
||||||
"rules_library",
|
|
||||||
"schemars",
|
"schemars",
|
||||||
"search",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_json_lenient",
|
|
||||||
"settings",
|
"settings",
|
||||||
"smol",
|
"smol",
|
||||||
"sqlez",
|
"sqlez",
|
||||||
"streaming_diff",
|
|
||||||
"telemetry",
|
"telemetry",
|
||||||
"telemetry_events",
|
|
||||||
"terminal",
|
|
||||||
"terminal_view",
|
|
||||||
"text",
|
"text",
|
||||||
"theme",
|
"theme",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"time",
|
"time",
|
||||||
"time_format",
|
|
||||||
"ui",
|
|
||||||
"urlencoding",
|
|
||||||
"util",
|
"util",
|
||||||
"uuid",
|
"uuid",
|
||||||
"watch",
|
|
||||||
"workspace",
|
"workspace",
|
||||||
"workspace-hack",
|
"workspace-hack",
|
||||||
"zed_actions",
|
|
||||||
"zed_llm_client",
|
"zed_llm_client",
|
||||||
"zstd",
|
"zstd",
|
||||||
]
|
]
|
||||||
|
@ -165,6 +131,89 @@ dependencies = [
|
||||||
"zed_llm_client",
|
"zed_llm_client",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "agent_ui"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"agent",
|
||||||
|
"agent_settings",
|
||||||
|
"anyhow",
|
||||||
|
"assistant_context_editor",
|
||||||
|
"assistant_slash_command",
|
||||||
|
"assistant_slash_commands",
|
||||||
|
"assistant_tool",
|
||||||
|
"assistant_tools",
|
||||||
|
"audio",
|
||||||
|
"buffer_diff",
|
||||||
|
"chrono",
|
||||||
|
"client",
|
||||||
|
"collections",
|
||||||
|
"component",
|
||||||
|
"context_server",
|
||||||
|
"db",
|
||||||
|
"editor",
|
||||||
|
"extension",
|
||||||
|
"extension_host",
|
||||||
|
"feature_flags",
|
||||||
|
"file_icons",
|
||||||
|
"fs",
|
||||||
|
"futures 0.3.31",
|
||||||
|
"fuzzy",
|
||||||
|
"gpui",
|
||||||
|
"html_to_markdown",
|
||||||
|
"http_client",
|
||||||
|
"indexed_docs",
|
||||||
|
"indoc",
|
||||||
|
"inventory",
|
||||||
|
"itertools 0.14.0",
|
||||||
|
"jsonschema",
|
||||||
|
"language",
|
||||||
|
"language_model",
|
||||||
|
"log",
|
||||||
|
"lsp",
|
||||||
|
"markdown",
|
||||||
|
"menu",
|
||||||
|
"multi_buffer",
|
||||||
|
"notifications",
|
||||||
|
"ordered-float 2.10.1",
|
||||||
|
"parking_lot",
|
||||||
|
"paths",
|
||||||
|
"picker",
|
||||||
|
"pretty_assertions",
|
||||||
|
"project",
|
||||||
|
"prompt_store",
|
||||||
|
"proto",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"release_channel",
|
||||||
|
"rope",
|
||||||
|
"rules_library",
|
||||||
|
"schemars",
|
||||||
|
"search",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_json_lenient",
|
||||||
|
"settings",
|
||||||
|
"smol",
|
||||||
|
"streaming_diff",
|
||||||
|
"telemetry",
|
||||||
|
"telemetry_events",
|
||||||
|
"terminal",
|
||||||
|
"terminal_view",
|
||||||
|
"text",
|
||||||
|
"theme",
|
||||||
|
"time",
|
||||||
|
"time_format",
|
||||||
|
"ui",
|
||||||
|
"urlencoding",
|
||||||
|
"util",
|
||||||
|
"uuid",
|
||||||
|
"watch",
|
||||||
|
"workspace",
|
||||||
|
"workspace-hack",
|
||||||
|
"zed_actions",
|
||||||
|
"zed_llm_client",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.7.8"
|
version = "0.7.8"
|
||||||
|
@ -5062,6 +5111,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"agent",
|
"agent",
|
||||||
"agent_settings",
|
"agent_settings",
|
||||||
|
"agent_ui",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"assistant_tool",
|
"assistant_tool",
|
||||||
"assistant_tools",
|
"assistant_tools",
|
||||||
|
@ -19868,6 +19918,7 @@ dependencies = [
|
||||||
"activity_indicator",
|
"activity_indicator",
|
||||||
"agent",
|
"agent",
|
||||||
"agent_settings",
|
"agent_settings",
|
||||||
|
"agent_ui",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"ashpd",
|
"ashpd",
|
||||||
"askpass",
|
"askpass",
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"crates/activity_indicator",
|
"crates/activity_indicator",
|
||||||
|
"crates/agent_ui",
|
||||||
"crates/agent",
|
"crates/agent",
|
||||||
"crates/agent_settings",
|
"crates/agent_settings",
|
||||||
"crates/anthropic",
|
"crates/anthropic",
|
||||||
|
@ -214,6 +215,7 @@ edition = "2024"
|
||||||
|
|
||||||
activity_indicator = { path = "crates/activity_indicator" }
|
activity_indicator = { path = "crates/activity_indicator" }
|
||||||
agent = { path = "crates/agent" }
|
agent = { path = "crates/agent" }
|
||||||
|
agent_ui = { path = "crates/agent_ui" }
|
||||||
agent_settings = { path = "crates/agent_settings" }
|
agent_settings = { path = "crates/agent_settings" }
|
||||||
ai = { path = "crates/ai" }
|
ai = { path = "crates/ai" }
|
||||||
anthropic = { path = "crates/anthropic" }
|
anthropic = { path = "crates/anthropic" }
|
||||||
|
|
|
@ -22,93 +22,57 @@ test-support = [
|
||||||
agent_settings.workspace = true
|
agent_settings.workspace = true
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
assistant_context_editor.workspace = true
|
assistant_context_editor.workspace = true
|
||||||
assistant_slash_command.workspace = true
|
|
||||||
assistant_slash_commands.workspace = true
|
|
||||||
assistant_tool.workspace = true
|
assistant_tool.workspace = true
|
||||||
audio.workspace = true
|
|
||||||
buffer_diff.workspace = true
|
|
||||||
chrono.workspace = true
|
chrono.workspace = true
|
||||||
client.workspace = true
|
client.workspace = true
|
||||||
collections.workspace = true
|
collections.workspace = true
|
||||||
component.workspace = true
|
component.workspace = true
|
||||||
context_server.workspace = true
|
context_server.workspace = true
|
||||||
convert_case.workspace = true
|
convert_case.workspace = true
|
||||||
db.workspace = true
|
|
||||||
editor.workspace = true
|
|
||||||
extension.workspace = true
|
|
||||||
extension_host.workspace = true
|
|
||||||
feature_flags.workspace = true
|
feature_flags.workspace = true
|
||||||
file_icons.workspace = true
|
|
||||||
fs.workspace = true
|
fs.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
fuzzy.workspace = true
|
|
||||||
git.workspace = true
|
git.workspace = true
|
||||||
gpui.workspace = true
|
gpui.workspace = true
|
||||||
heed.workspace = true
|
heed.workspace = true
|
||||||
html_to_markdown.workspace = true
|
icons.workspace = true
|
||||||
indoc.workspace = true
|
indoc.workspace = true
|
||||||
http_client.workspace = true
|
http_client.workspace = true
|
||||||
indexed_docs.workspace = true
|
|
||||||
inventory.workspace = true
|
|
||||||
itertools.workspace = true
|
itertools.workspace = true
|
||||||
jsonschema.workspace = true
|
|
||||||
language.workspace = true
|
language.workspace = true
|
||||||
language_model.workspace = true
|
language_model.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
lsp.workspace = true
|
|
||||||
markdown.workspace = true
|
|
||||||
menu.workspace = true
|
|
||||||
multi_buffer.workspace = true
|
|
||||||
notifications.workspace = true
|
|
||||||
ordered-float.workspace = true
|
|
||||||
parking_lot.workspace = true
|
|
||||||
paths.workspace = true
|
paths.workspace = true
|
||||||
picker.workspace = true
|
|
||||||
postage.workspace = true
|
postage.workspace = true
|
||||||
project.workspace = true
|
project.workspace = true
|
||||||
prompt_store.workspace = true
|
prompt_store.workspace = true
|
||||||
proto.workspace = true
|
proto.workspace = true
|
||||||
ref-cast.workspace = true
|
ref-cast.workspace = true
|
||||||
release_channel.workspace = true
|
|
||||||
rope.workspace = true
|
rope.workspace = true
|
||||||
rules_library.workspace = true
|
|
||||||
schemars.workspace = true
|
schemars.workspace = true
|
||||||
search.workspace = true
|
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
serde_json_lenient.workspace = true
|
|
||||||
settings.workspace = true
|
settings.workspace = true
|
||||||
smol.workspace = true
|
smol.workspace = true
|
||||||
sqlez.workspace = true
|
sqlez.workspace = true
|
||||||
streaming_diff.workspace = true
|
|
||||||
telemetry.workspace = true
|
telemetry.workspace = true
|
||||||
telemetry_events.workspace = true
|
|
||||||
terminal.workspace = true
|
|
||||||
terminal_view.workspace = true
|
|
||||||
text.workspace = true
|
text.workspace = true
|
||||||
theme.workspace = true
|
theme.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
time.workspace = true
|
time.workspace = true
|
||||||
time_format.workspace = true
|
|
||||||
ui.workspace = true
|
|
||||||
urlencoding.workspace = true
|
|
||||||
util.workspace = true
|
util.workspace = true
|
||||||
uuid.workspace = true
|
uuid.workspace = true
|
||||||
watch.workspace = true
|
|
||||||
workspace-hack.workspace = true
|
workspace-hack.workspace = true
|
||||||
workspace.workspace = true
|
|
||||||
zed_actions.workspace = true
|
|
||||||
zed_llm_client.workspace = true
|
zed_llm_client.workspace = true
|
||||||
zstd.workspace = true
|
zstd.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assistant_tools.workspace = true
|
assistant_tools.workspace = true
|
||||||
buffer_diff = { workspace = true, features = ["test-support"] }
|
|
||||||
editor = { workspace = true, features = ["test-support"] }
|
|
||||||
gpui = { workspace = true, "features" = ["test-support"] }
|
gpui = { workspace = true, "features" = ["test-support"] }
|
||||||
indoc.workspace = true
|
indoc.workspace = true
|
||||||
language = { workspace = true, "features" = ["test-support"] }
|
language = { workspace = true, "features" = ["test-support"] }
|
||||||
language_model = { workspace = true, "features" = ["test-support"] }
|
language_model = { workspace = true, "features" = ["test-support"] }
|
||||||
pretty_assertions.workspace = true
|
pretty_assertions.workspace = true
|
||||||
project = { workspace = true, features = ["test-support"] }
|
project = { workspace = true, features = ["test-support"] }
|
||||||
|
workspace = { workspace = true, features = ["test-support"] }
|
||||||
rand.workspace = true
|
rand.workspace = true
|
||||||
|
|
|
@ -1,297 +1,20 @@
|
||||||
mod active_thread;
|
pub mod agent_profile;
|
||||||
mod agent_configuration;
|
pub mod context;
|
||||||
mod agent_diff;
|
pub mod context_server_tool;
|
||||||
mod agent_model_selector;
|
pub mod context_store;
|
||||||
mod agent_panel;
|
pub mod history_store;
|
||||||
mod agent_profile;
|
pub mod thread;
|
||||||
mod buffer_codegen;
|
pub mod thread_store;
|
||||||
mod context;
|
pub mod tool_use;
|
||||||
mod context_picker;
|
|
||||||
mod context_server_configuration;
|
|
||||||
mod context_server_tool;
|
|
||||||
mod context_store;
|
|
||||||
mod context_strip;
|
|
||||||
mod debug;
|
|
||||||
mod history_store;
|
|
||||||
mod inline_assistant;
|
|
||||||
mod inline_prompt_editor;
|
|
||||||
mod message_editor;
|
|
||||||
mod profile_selector;
|
|
||||||
mod slash_command_settings;
|
|
||||||
mod terminal_codegen;
|
|
||||||
mod terminal_inline_assistant;
|
|
||||||
mod thread;
|
|
||||||
mod thread_history;
|
|
||||||
mod thread_store;
|
|
||||||
mod tool_compatibility;
|
|
||||||
mod tool_use;
|
|
||||||
mod ui;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
pub use context::{AgentContext, ContextId, ContextLoadResult};
|
||||||
|
|
||||||
use agent_settings::{AgentProfileId, AgentSettings, LanguageModelSelection};
|
|
||||||
use assistant_slash_command::SlashCommandRegistry;
|
|
||||||
use client::Client;
|
|
||||||
use feature_flags::FeatureFlagAppExt as _;
|
|
||||||
use fs::Fs;
|
|
||||||
use gpui::{App, Entity, actions, impl_actions};
|
|
||||||
use language::LanguageRegistry;
|
|
||||||
use language_model::{
|
|
||||||
ConfiguredModel, LanguageModel, LanguageModelId, LanguageModelProviderId, LanguageModelRegistry,
|
|
||||||
};
|
|
||||||
use prompt_store::PromptBuilder;
|
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use settings::{Settings as _, SettingsStore};
|
|
||||||
use thread::ThreadId;
|
|
||||||
|
|
||||||
pub use crate::active_thread::ActiveThread;
|
|
||||||
use crate::agent_configuration::{ConfigureContextServerModal, ManageProfilesModal};
|
|
||||||
pub use crate::agent_panel::{AgentPanel, ConcreteAssistantPanelDelegate};
|
|
||||||
pub use crate::context::{ContextLoadResult, LoadedContext};
|
|
||||||
pub use crate::inline_assistant::InlineAssistant;
|
|
||||||
use crate::slash_command_settings::SlashCommandSettings;
|
|
||||||
pub use crate::thread::{Message, MessageSegment, Thread, ThreadEvent};
|
|
||||||
pub use crate::thread_store::{SerializedThread, TextThreadStore, ThreadStore};
|
|
||||||
pub use agent_diff::{AgentDiffPane, AgentDiffToolbar};
|
|
||||||
pub use context_store::ContextStore;
|
pub use context_store::ContextStore;
|
||||||
pub use ui::preview::{all_agent_previews, get_agent_preview};
|
pub use thread::{
|
||||||
|
LastRestoreCheckpoint, Message, MessageCrease, MessageId, MessageSegment, Thread, ThreadError,
|
||||||
|
ThreadEvent, ThreadFeedback, ThreadId, ThreadSummary, TokenUsageRatio,
|
||||||
|
};
|
||||||
|
pub use thread_store::{SerializedThread, TextThreadStore, ThreadStore};
|
||||||
|
|
||||||
actions!(
|
pub fn init(cx: &mut gpui::App) {
|
||||||
agent,
|
|
||||||
[
|
|
||||||
NewTextThread,
|
|
||||||
ToggleContextPicker,
|
|
||||||
ToggleNavigationMenu,
|
|
||||||
ToggleOptionsMenu,
|
|
||||||
DeleteRecentlyOpenThread,
|
|
||||||
ToggleProfileSelector,
|
|
||||||
RemoveAllContext,
|
|
||||||
ExpandMessageEditor,
|
|
||||||
OpenHistory,
|
|
||||||
AddContextServer,
|
|
||||||
RemoveSelectedThread,
|
|
||||||
Chat,
|
|
||||||
ChatWithFollow,
|
|
||||||
CycleNextInlineAssist,
|
|
||||||
CyclePreviousInlineAssist,
|
|
||||||
FocusUp,
|
|
||||||
FocusDown,
|
|
||||||
FocusLeft,
|
|
||||||
FocusRight,
|
|
||||||
RemoveFocusedContext,
|
|
||||||
AcceptSuggestedContext,
|
|
||||||
OpenActiveThreadAsMarkdown,
|
|
||||||
OpenAgentDiff,
|
|
||||||
Keep,
|
|
||||||
Reject,
|
|
||||||
RejectAll,
|
|
||||||
KeepAll,
|
|
||||||
Follow,
|
|
||||||
ResetTrialUpsell,
|
|
||||||
ResetTrialEndUpsell,
|
|
||||||
ContinueThread,
|
|
||||||
ContinueWithBurnMode,
|
|
||||||
ToggleBurnMode,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Default, Clone, PartialEq, Deserialize, JsonSchema)]
|
|
||||||
pub struct NewThread {
|
|
||||||
#[serde(default)]
|
|
||||||
from_thread_id: Option<ThreadId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
|
||||||
pub struct ManageProfiles {
|
|
||||||
#[serde(default)]
|
|
||||||
pub customize_tools: Option<AgentProfileId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ManageProfiles {
|
|
||||||
pub fn customize_tools(profile_id: AgentProfileId) -> Self {
|
|
||||||
Self {
|
|
||||||
customize_tools: Some(profile_id),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_actions!(agent, [NewThread, ManageProfiles]);
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub(crate) enum ModelUsageContext {
|
|
||||||
Thread(Entity<Thread>),
|
|
||||||
InlineAssistant,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ModelUsageContext {
|
|
||||||
pub fn configured_model(&self, cx: &App) -> Option<ConfiguredModel> {
|
|
||||||
match self {
|
|
||||||
Self::Thread(thread) => thread.read(cx).configured_model(),
|
|
||||||
Self::InlineAssistant => {
|
|
||||||
LanguageModelRegistry::read_global(cx).inline_assistant_model()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn language_model(&self, cx: &App) -> Option<Arc<dyn LanguageModel>> {
|
|
||||||
self.configured_model(cx)
|
|
||||||
.map(|configured_model| configured_model.model)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initializes the `agent` crate.
|
|
||||||
pub fn init(
|
|
||||||
fs: Arc<dyn Fs>,
|
|
||||||
client: Arc<Client>,
|
|
||||||
prompt_builder: Arc<PromptBuilder>,
|
|
||||||
language_registry: Arc<LanguageRegistry>,
|
|
||||||
is_eval: bool,
|
|
||||||
cx: &mut App,
|
|
||||||
) {
|
|
||||||
AgentSettings::register(cx);
|
|
||||||
SlashCommandSettings::register(cx);
|
|
||||||
|
|
||||||
assistant_context_editor::init(client.clone(), cx);
|
|
||||||
rules_library::init(cx);
|
|
||||||
if !is_eval {
|
|
||||||
// Initializing the language model from the user settings messes with the eval, so we only initialize them when
|
|
||||||
// we're not running inside of the eval.
|
|
||||||
init_language_model_settings(cx);
|
|
||||||
}
|
|
||||||
assistant_slash_command::init(cx);
|
|
||||||
thread_store::init(cx);
|
thread_store::init(cx);
|
||||||
agent_panel::init(cx);
|
|
||||||
context_server_configuration::init(language_registry.clone(), fs.clone(), cx);
|
|
||||||
|
|
||||||
register_slash_commands(cx);
|
|
||||||
inline_assistant::init(
|
|
||||||
fs.clone(),
|
|
||||||
prompt_builder.clone(),
|
|
||||||
client.telemetry().clone(),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
terminal_inline_assistant::init(
|
|
||||||
fs.clone(),
|
|
||||||
prompt_builder.clone(),
|
|
||||||
client.telemetry().clone(),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
indexed_docs::init(cx);
|
|
||||||
cx.observe_new(move |workspace, window, cx| {
|
|
||||||
ConfigureContextServerModal::register(workspace, language_registry.clone(), window, cx)
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
cx.observe_new(ManageProfilesModal::register).detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_language_model_settings(cx: &mut App) {
|
|
||||||
update_active_language_model_from_settings(cx);
|
|
||||||
|
|
||||||
cx.observe_global::<SettingsStore>(update_active_language_model_from_settings)
|
|
||||||
.detach();
|
|
||||||
cx.subscribe(
|
|
||||||
&LanguageModelRegistry::global(cx),
|
|
||||||
|_, event: &language_model::Event, cx| match event {
|
|
||||||
language_model::Event::ProviderStateChanged
|
|
||||||
| language_model::Event::AddedProvider(_)
|
|
||||||
| language_model::Event::RemovedProvider(_) => {
|
|
||||||
update_active_language_model_from_settings(cx);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_active_language_model_from_settings(cx: &mut App) {
|
|
||||||
let settings = AgentSettings::get_global(cx);
|
|
||||||
|
|
||||||
fn to_selected_model(selection: &LanguageModelSelection) -> language_model::SelectedModel {
|
|
||||||
language_model::SelectedModel {
|
|
||||||
provider: LanguageModelProviderId::from(selection.provider.0.clone()),
|
|
||||||
model: LanguageModelId::from(selection.model.clone()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let default = to_selected_model(&settings.default_model);
|
|
||||||
let inline_assistant = settings
|
|
||||||
.inline_assistant_model
|
|
||||||
.as_ref()
|
|
||||||
.map(to_selected_model);
|
|
||||||
let commit_message = settings
|
|
||||||
.commit_message_model
|
|
||||||
.as_ref()
|
|
||||||
.map(to_selected_model);
|
|
||||||
let thread_summary = settings
|
|
||||||
.thread_summary_model
|
|
||||||
.as_ref()
|
|
||||||
.map(to_selected_model);
|
|
||||||
let inline_alternatives = settings
|
|
||||||
.inline_alternatives
|
|
||||||
.iter()
|
|
||||||
.map(to_selected_model)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
LanguageModelRegistry::global(cx).update(cx, |registry, cx| {
|
|
||||||
registry.select_default_model(Some(&default), cx);
|
|
||||||
registry.select_inline_assistant_model(inline_assistant.as_ref(), cx);
|
|
||||||
registry.select_commit_message_model(commit_message.as_ref(), cx);
|
|
||||||
registry.select_thread_summary_model(thread_summary.as_ref(), cx);
|
|
||||||
registry.select_inline_alternative_models(inline_alternatives, cx);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn register_slash_commands(cx: &mut App) {
|
|
||||||
let slash_command_registry = SlashCommandRegistry::global(cx);
|
|
||||||
|
|
||||||
slash_command_registry.register_command(assistant_slash_commands::FileSlashCommand, true);
|
|
||||||
slash_command_registry.register_command(assistant_slash_commands::DeltaSlashCommand, true);
|
|
||||||
slash_command_registry.register_command(assistant_slash_commands::OutlineSlashCommand, true);
|
|
||||||
slash_command_registry.register_command(assistant_slash_commands::TabSlashCommand, true);
|
|
||||||
slash_command_registry
|
|
||||||
.register_command(assistant_slash_commands::CargoWorkspaceSlashCommand, true);
|
|
||||||
slash_command_registry.register_command(assistant_slash_commands::PromptSlashCommand, true);
|
|
||||||
slash_command_registry.register_command(assistant_slash_commands::SelectionCommand, true);
|
|
||||||
slash_command_registry.register_command(assistant_slash_commands::DefaultSlashCommand, false);
|
|
||||||
slash_command_registry.register_command(assistant_slash_commands::NowSlashCommand, false);
|
|
||||||
slash_command_registry
|
|
||||||
.register_command(assistant_slash_commands::DiagnosticsSlashCommand, true);
|
|
||||||
slash_command_registry.register_command(assistant_slash_commands::FetchSlashCommand, true);
|
|
||||||
|
|
||||||
cx.observe_flag::<assistant_slash_commands::StreamingExampleSlashCommandFeatureFlag, _>({
|
|
||||||
let slash_command_registry = slash_command_registry.clone();
|
|
||||||
move |is_enabled, _cx| {
|
|
||||||
if is_enabled {
|
|
||||||
slash_command_registry.register_command(
|
|
||||||
assistant_slash_commands::StreamingExampleSlashCommand,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
|
|
||||||
update_slash_commands_from_settings(cx);
|
|
||||||
cx.observe_global::<SettingsStore>(update_slash_commands_from_settings)
|
|
||||||
.detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_slash_commands_from_settings(cx: &mut App) {
|
|
||||||
let slash_command_registry = SlashCommandRegistry::global(cx);
|
|
||||||
let settings = SlashCommandSettings::get_global(cx);
|
|
||||||
|
|
||||||
if settings.docs.enabled {
|
|
||||||
slash_command_registry.register_command(assistant_slash_commands::DocsSlashCommand, true);
|
|
||||||
} else {
|
|
||||||
slash_command_registry.unregister_command(assistant_slash_commands::DocsSlashCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
if settings.cargo_workspace.enabled {
|
|
||||||
slash_command_registry
|
|
||||||
.register_command(assistant_slash_commands::CargoWorkspaceSlashCommand, true);
|
|
||||||
} else {
|
|
||||||
slash_command_registry
|
|
||||||
.unregister_command(assistant_slash_commands::CargoWorkspaceSlashCommand);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,8 @@ use assistant_tool::{Tool, ToolSource, ToolWorkingSet};
|
||||||
use collections::IndexMap;
|
use collections::IndexMap;
|
||||||
use convert_case::{Case, Casing};
|
use convert_case::{Case, Casing};
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use gpui::{App, Entity};
|
use gpui::{App, Entity, SharedString};
|
||||||
use settings::{Settings, update_settings_file};
|
use settings::{Settings, update_settings_file};
|
||||||
use ui::SharedString;
|
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -108,11 +107,11 @@ mod tests {
|
||||||
use agent_settings::ContextServerPreset;
|
use agent_settings::ContextServerPreset;
|
||||||
use assistant_tool::ToolRegistry;
|
use assistant_tool::ToolRegistry;
|
||||||
use collections::IndexMap;
|
use collections::IndexMap;
|
||||||
|
use gpui::SharedString;
|
||||||
use gpui::{AppContext, TestAppContext};
|
use gpui::{AppContext, TestAppContext};
|
||||||
use http_client::FakeHttpClient;
|
use http_client::FakeHttpClient;
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use settings::{Settings, SettingsStore};
|
use settings::{Settings, SettingsStore};
|
||||||
use ui::SharedString;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -302,7 +301,7 @@ mod tests {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon(&self) -> ui::IconName {
|
fn icon(&self) -> icons::IconName {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,25 @@
|
||||||
use std::fmt::{self, Display, Formatter, Write as _};
|
use crate::thread::Thread;
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::{ops::Range, path::Path, sync::Arc};
|
|
||||||
|
|
||||||
use assistant_context_editor::AssistantContext;
|
use assistant_context_editor::AssistantContext;
|
||||||
use assistant_tool::outline;
|
use assistant_tool::outline;
|
||||||
use collections::{HashMap, HashSet};
|
use collections::HashSet;
|
||||||
use editor::display_map::CreaseId;
|
|
||||||
use editor::{Addon, Editor};
|
|
||||||
use futures::future;
|
use futures::future;
|
||||||
use futures::{FutureExt, future::Shared};
|
use futures::{FutureExt, future::Shared};
|
||||||
use gpui::{App, AppContext as _, Entity, SharedString, Subscription, Task};
|
use gpui::{App, AppContext as _, ElementId, Entity, SharedString, Task};
|
||||||
|
use icons::IconName;
|
||||||
use language::{Buffer, ParseStatus};
|
use language::{Buffer, ParseStatus};
|
||||||
use language_model::{LanguageModelImage, LanguageModelRequestMessage, MessageContent};
|
use language_model::{LanguageModelImage, LanguageModelRequestMessage, MessageContent};
|
||||||
use project::{Project, ProjectEntryId, ProjectPath, Worktree};
|
use project::{Project, ProjectEntryId, ProjectPath, Worktree};
|
||||||
use prompt_store::{PromptStore, UserPromptId};
|
use prompt_store::{PromptStore, UserPromptId};
|
||||||
use ref_cast::RefCast;
|
use ref_cast::RefCast;
|
||||||
use rope::Point;
|
use rope::Point;
|
||||||
|
use std::fmt::{self, Display, Formatter, Write as _};
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::{ops::Range, path::Path, sync::Arc};
|
||||||
use text::{Anchor, OffsetRangeExt as _};
|
use text::{Anchor, OffsetRangeExt as _};
|
||||||
use ui::{Context, ElementId, IconName};
|
|
||||||
use util::markdown::MarkdownCodeBlock;
|
use util::markdown::MarkdownCodeBlock;
|
||||||
use util::{ResultExt as _, post_inc};
|
use util::{ResultExt as _, post_inc};
|
||||||
|
|
||||||
use crate::context_store::{ContextStore, ContextStoreEvent};
|
|
||||||
use crate::thread::Thread;
|
|
||||||
|
|
||||||
pub const RULES_ICON: IconName = IconName::Context;
|
pub const RULES_ICON: IconName = IconName::Context;
|
||||||
|
|
||||||
pub enum ContextKind {
|
pub enum ContextKind {
|
||||||
|
@ -1117,69 +1112,6 @@ impl Hash for AgentContextKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct ContextCreasesAddon {
|
|
||||||
creases: HashMap<AgentContextKey, Vec<(CreaseId, SharedString)>>,
|
|
||||||
_subscription: Option<Subscription>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Addon for ContextCreasesAddon {
|
|
||||||
fn to_any(&self) -> &dyn std::any::Any {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_any_mut(&mut self) -> Option<&mut dyn std::any::Any> {
|
|
||||||
Some(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ContextCreasesAddon {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
creases: HashMap::default(),
|
|
||||||
_subscription: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_creases(
|
|
||||||
&mut self,
|
|
||||||
context_store: &Entity<ContextStore>,
|
|
||||||
key: AgentContextKey,
|
|
||||||
creases: impl IntoIterator<Item = (CreaseId, SharedString)>,
|
|
||||||
cx: &mut Context<Editor>,
|
|
||||||
) {
|
|
||||||
self.creases.entry(key).or_default().extend(creases);
|
|
||||||
self._subscription = Some(cx.subscribe(
|
|
||||||
&context_store,
|
|
||||||
|editor, _, event, cx| match event {
|
|
||||||
ContextStoreEvent::ContextRemoved(key) => {
|
|
||||||
let Some(this) = editor.addon_mut::<Self>() else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let (crease_ids, replacement_texts): (Vec<_>, Vec<_>) = this
|
|
||||||
.creases
|
|
||||||
.remove(key)
|
|
||||||
.unwrap_or_default()
|
|
||||||
.into_iter()
|
|
||||||
.unzip();
|
|
||||||
let ranges = editor
|
|
||||||
.remove_creases(crease_ids, cx)
|
|
||||||
.into_iter()
|
|
||||||
.map(|(_, range)| range)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
editor.unfold_ranges(&ranges, false, false, cx);
|
|
||||||
editor.edit(ranges.into_iter().zip(replacement_texts), cx);
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_inner(self) -> HashMap<AgentContextKey, Vec<(CreaseId, SharedString)>> {
|
|
||||||
self.creases
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -4,9 +4,9 @@ use anyhow::{Result, anyhow, bail};
|
||||||
use assistant_tool::{ActionLog, Tool, ToolResult, ToolSource};
|
use assistant_tool::{ActionLog, Tool, ToolResult, ToolSource};
|
||||||
use context_server::{ContextServerId, types};
|
use context_server::{ContextServerId, types};
|
||||||
use gpui::{AnyWindowHandle, App, Entity, Task};
|
use gpui::{AnyWindowHandle, App, Entity, Task};
|
||||||
|
use icons::IconName;
|
||||||
use language_model::{LanguageModel, LanguageModelRequest, LanguageModelToolSchemaFormat};
|
use language_model::{LanguageModel, LanguageModelRequest, LanguageModelToolSchemaFormat};
|
||||||
use project::{Project, context_server_store::ContextServerStore};
|
use project::{Project, context_server_store::ContextServerStore};
|
||||||
use ui::IconName;
|
|
||||||
|
|
||||||
pub struct ContextServerTool {
|
pub struct ContextServerTool {
|
||||||
store: Entity<ContextServerStore>,
|
store: Entity<ContextServerStore>,
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
use std::ops::Range;
|
use crate::{
|
||||||
use std::path::{Path, PathBuf};
|
context::{
|
||||||
use std::sync::Arc;
|
AgentContextHandle, AgentContextKey, ContextId, ContextKind, DirectoryContextHandle,
|
||||||
|
FetchedUrlContext, FileContextHandle, ImageContext, RulesContextHandle,
|
||||||
|
SelectionContextHandle, SymbolContextHandle, TextThreadContextHandle, ThreadContextHandle,
|
||||||
|
},
|
||||||
|
thread::{MessageId, Thread, ThreadId},
|
||||||
|
thread_store::ThreadStore,
|
||||||
|
};
|
||||||
use anyhow::{Context as _, Result, anyhow};
|
use anyhow::{Context as _, Result, anyhow};
|
||||||
use assistant_context_editor::AssistantContext;
|
use assistant_context_editor::AssistantContext;
|
||||||
use collections::{HashSet, IndexSet};
|
use collections::{HashSet, IndexSet};
|
||||||
|
@ -9,20 +14,15 @@ use futures::{self, FutureExt};
|
||||||
use gpui::{App, Context, Entity, EventEmitter, Image, SharedString, Task, WeakEntity};
|
use gpui::{App, Context, Entity, EventEmitter, Image, SharedString, Task, WeakEntity};
|
||||||
use language::{Buffer, File as _};
|
use language::{Buffer, File as _};
|
||||||
use language_model::LanguageModelImage;
|
use language_model::LanguageModelImage;
|
||||||
use project::image_store::is_image_file;
|
use project::{Project, ProjectItem, ProjectPath, Symbol, image_store::is_image_file};
|
||||||
use project::{Project, ProjectItem, ProjectPath, Symbol};
|
|
||||||
use prompt_store::UserPromptId;
|
use prompt_store::UserPromptId;
|
||||||
use ref_cast::RefCast as _;
|
use ref_cast::RefCast as _;
|
||||||
use text::{Anchor, OffsetRangeExt};
|
use std::{
|
||||||
|
ops::Range,
|
||||||
use crate::ThreadStore;
|
path::{Path, PathBuf},
|
||||||
use crate::context::{
|
sync::Arc,
|
||||||
AgentContextHandle, AgentContextKey, ContextId, DirectoryContextHandle, FetchedUrlContext,
|
|
||||||
FileContextHandle, ImageContext, RulesContextHandle, SelectionContextHandle,
|
|
||||||
SymbolContextHandle, TextThreadContextHandle, ThreadContextHandle,
|
|
||||||
};
|
};
|
||||||
use crate::context_strip::SuggestedContext;
|
use text::{Anchor, OffsetRangeExt};
|
||||||
use crate::thread::{MessageId, Thread, ThreadId};
|
|
||||||
|
|
||||||
pub struct ContextStore {
|
pub struct ContextStore {
|
||||||
project: WeakEntity<Project>,
|
project: WeakEntity<Project>,
|
||||||
|
@ -561,6 +561,49 @@ impl ContextStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum SuggestedContext {
|
||||||
|
File {
|
||||||
|
name: SharedString,
|
||||||
|
icon_path: Option<SharedString>,
|
||||||
|
buffer: WeakEntity<Buffer>,
|
||||||
|
},
|
||||||
|
Thread {
|
||||||
|
name: SharedString,
|
||||||
|
thread: WeakEntity<Thread>,
|
||||||
|
},
|
||||||
|
TextThread {
|
||||||
|
name: SharedString,
|
||||||
|
context: WeakEntity<AssistantContext>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SuggestedContext {
|
||||||
|
pub fn name(&self) -> &SharedString {
|
||||||
|
match self {
|
||||||
|
Self::File { name, .. } => name,
|
||||||
|
Self::Thread { name, .. } => name,
|
||||||
|
Self::TextThread { name, .. } => name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_path(&self) -> Option<SharedString> {
|
||||||
|
match self {
|
||||||
|
Self::File { icon_path, .. } => icon_path.clone(),
|
||||||
|
Self::Thread { .. } => None,
|
||||||
|
Self::TextThread { .. } => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kind(&self) -> ContextKind {
|
||||||
|
match self {
|
||||||
|
Self::File { .. } => ContextKind::File,
|
||||||
|
Self::Thread { .. } => ContextKind::Thread,
|
||||||
|
Self::TextThread { .. } => ContextKind::TextThread,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum FileInclusion {
|
pub enum FileInclusion {
|
||||||
Direct,
|
Direct,
|
||||||
InDirectory { full_path: PathBuf },
|
InDirectory { full_path: PathBuf },
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
use std::{collections::VecDeque, path::Path, sync::Arc};
|
use crate::{
|
||||||
|
ThreadId,
|
||||||
|
thread_store::{SerializedThreadMetadata, ThreadStore},
|
||||||
|
};
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
use assistant_context_editor::SavedContextMetadata;
|
use assistant_context_editor::SavedContextMetadata;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use gpui::{AsyncApp, Entity, SharedString, Task, prelude::*};
|
use gpui::{App, AsyncApp, Entity, SharedString, Task, prelude::*};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use paths::contexts_dir;
|
use paths::contexts_dir;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::{collections::VecDeque, path::Path, sync::Arc, time::Duration};
|
||||||
use ui::App;
|
|
||||||
use util::ResultExt as _;
|
use util::ResultExt as _;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
thread::ThreadId,
|
|
||||||
thread_store::{SerializedThreadMetadata, ThreadStore},
|
|
||||||
};
|
|
||||||
|
|
||||||
const MAX_RECENTLY_OPENED_ENTRIES: usize = 6;
|
const MAX_RECENTLY_OPENED_ENTRIES: usize = 6;
|
||||||
const NAVIGATION_HISTORY_PATH: &str = "agent-navigation-history.json";
|
const NAVIGATION_HISTORY_PATH: &str = "agent-navigation-history.json";
|
||||||
const SAVE_RECENTLY_OPENED_ENTRIES_DEBOUNCE: Duration = Duration::from_millis(50);
|
const SAVE_RECENTLY_OPENED_ENTRIES_DEBOUNCE: Duration = Duration::from_millis(50);
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
use std::io::Write;
|
use crate::{
|
||||||
use std::ops::Range;
|
agent_profile::AgentProfile,
|
||||||
use std::sync::Arc;
|
context::{AgentContext, AgentContextHandle, ContextLoadResult, LoadedContext},
|
||||||
use std::time::Instant;
|
thread_store::{
|
||||||
|
SerializedCrease, SerializedLanguageModel, SerializedMessage, SerializedMessageSegment,
|
||||||
|
SerializedThread, SerializedToolResult, SerializedToolUse, SharedProjectContext,
|
||||||
|
ThreadStore,
|
||||||
|
},
|
||||||
|
tool_use::{PendingToolUse, ToolUse, ToolUseMetadata, ToolUseState},
|
||||||
|
};
|
||||||
use agent_settings::{AgentProfileId, AgentSettings, CompletionMode};
|
use agent_settings::{AgentProfileId, AgentSettings, CompletionMode};
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use assistant_tool::{ActionLog, AnyToolCard, Tool, ToolWorkingSet};
|
use assistant_tool::{ActionLog, AnyToolCard, Tool, ToolWorkingSet};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use client::{ModelRequestUsage, RequestUsage};
|
use client::{ModelRequestUsage, RequestUsage};
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
use editor::display_map::CreaseMetadata;
|
|
||||||
use feature_flags::{self, FeatureFlagAppExt};
|
use feature_flags::{self, FeatureFlagAppExt};
|
||||||
use futures::future::Shared;
|
use futures::{FutureExt, StreamExt as _, future::Shared};
|
||||||
use futures::{FutureExt, StreamExt as _};
|
|
||||||
use git::repository::DiffType;
|
use git::repository::DiffType;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AnyWindowHandle, App, AppContext, AsyncApp, Context, Entity, EventEmitter, SharedString, Task,
|
AnyWindowHandle, App, AppContext, AsyncApp, Context, Entity, EventEmitter, SharedString, Task,
|
||||||
WeakEntity,
|
WeakEntity, Window,
|
||||||
};
|
};
|
||||||
use language_model::{
|
use language_model::{
|
||||||
ConfiguredModel, LanguageModel, LanguageModelCompletionError, LanguageModelCompletionEvent,
|
ConfiguredModel, LanguageModel, LanguageModelCompletionError, LanguageModelCompletionEvent,
|
||||||
|
@ -27,29 +30,21 @@ use language_model::{
|
||||||
TokenUsage,
|
TokenUsage,
|
||||||
};
|
};
|
||||||
use postage::stream::Stream as _;
|
use postage::stream::Stream as _;
|
||||||
use project::Project;
|
use project::{
|
||||||
use project::git_store::{GitStore, GitStoreCheckpoint, RepositoryState};
|
Project,
|
||||||
|
git_store::{GitStore, GitStoreCheckpoint, RepositoryState},
|
||||||
|
};
|
||||||
use prompt_store::{ModelContext, PromptBuilder};
|
use prompt_store::{ModelContext, PromptBuilder};
|
||||||
use proto::Plan;
|
use proto::Plan;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
|
use std::{io::Write, ops::Range, sync::Arc, time::Instant};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use ui::Window;
|
|
||||||
use util::{ResultExt as _, post_inc};
|
use util::{ResultExt as _, post_inc};
|
||||||
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use zed_llm_client::{CompletionIntent, CompletionRequestStatus, UsageLimit};
|
use zed_llm_client::{CompletionIntent, CompletionRequestStatus, UsageLimit};
|
||||||
|
|
||||||
use crate::ThreadStore;
|
|
||||||
use crate::agent_profile::AgentProfile;
|
|
||||||
use crate::context::{AgentContext, AgentContextHandle, ContextLoadResult, LoadedContext};
|
|
||||||
use crate::thread_store::{
|
|
||||||
SerializedCrease, SerializedLanguageModel, SerializedMessage, SerializedMessageSegment,
|
|
||||||
SerializedThread, SerializedToolResult, SerializedToolUse, SharedProjectContext,
|
|
||||||
};
|
|
||||||
use crate::tool_use::{PendingToolUse, ToolUse, ToolUseMetadata, ToolUseState};
|
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize, JsonSchema,
|
Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize, JsonSchema,
|
||||||
)]
|
)]
|
||||||
|
@ -98,13 +93,18 @@ impl MessageId {
|
||||||
fn post_inc(&mut self) -> Self {
|
fn post_inc(&mut self) -> Self {
|
||||||
Self(post_inc(&mut self.0))
|
Self(post_inc(&mut self.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_usize(&self) -> usize {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stored information that can be used to resurrect a context crease when creating an editor for a past message.
|
/// Stored information that can be used to resurrect a context crease when creating an editor for a past message.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MessageCrease {
|
pub struct MessageCrease {
|
||||||
pub range: Range<usize>,
|
pub range: Range<usize>,
|
||||||
pub metadata: CreaseMetadata,
|
pub icon_path: SharedString,
|
||||||
|
pub label: SharedString,
|
||||||
/// None for a deserialized message, Some otherwise.
|
/// None for a deserialized message, Some otherwise.
|
||||||
pub context: Option<AgentContextHandle>,
|
pub context: Option<AgentContextHandle>,
|
||||||
}
|
}
|
||||||
|
@ -540,10 +540,8 @@ impl Thread {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|crease| MessageCrease {
|
.map(|crease| MessageCrease {
|
||||||
range: crease.start..crease.end,
|
range: crease.start..crease.end,
|
||||||
metadata: CreaseMetadata {
|
icon_path: crease.icon_path,
|
||||||
icon_path: crease.icon_path,
|
label: crease.label,
|
||||||
label: crease.label,
|
|
||||||
},
|
|
||||||
context: None,
|
context: None,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -1170,8 +1168,8 @@ impl Thread {
|
||||||
.map(|crease| SerializedCrease {
|
.map(|crease| SerializedCrease {
|
||||||
start: crease.range.start,
|
start: crease.range.start,
|
||||||
end: crease.range.end,
|
end: crease.range.end,
|
||||||
icon_path: crease.metadata.icon_path.clone(),
|
icon_path: crease.icon_path.clone(),
|
||||||
label: crease.metadata.label.clone(),
|
label: crease.label.clone(),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
is_hidden: message.is_hidden,
|
is_hidden: message.is_hidden,
|
||||||
|
@ -2997,11 +2995,13 @@ fn resolve_tool_name_conflicts(tools: &[Arc<dyn Tool>]) -> Vec<(String, Arc<dyn
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{ThreadStore, context::load_context, context_store::ContextStore, thread_store};
|
use crate::{
|
||||||
|
context::load_context, context_store::ContextStore, thread_store, thread_store::ThreadStore,
|
||||||
|
};
|
||||||
use agent_settings::{AgentProfileId, AgentSettings, LanguageModelParameters};
|
use agent_settings::{AgentProfileId, AgentSettings, LanguageModelParameters};
|
||||||
use assistant_tool::ToolRegistry;
|
use assistant_tool::ToolRegistry;
|
||||||
use editor::EditorSettings;
|
|
||||||
use gpui::TestAppContext;
|
use gpui::TestAppContext;
|
||||||
|
use icons::IconName;
|
||||||
use language_model::fake_provider::{FakeLanguageModel, FakeLanguageModelProvider};
|
use language_model::fake_provider::{FakeLanguageModel, FakeLanguageModelProvider};
|
||||||
use project::{FakeFs, Project};
|
use project::{FakeFs, Project};
|
||||||
use prompt_store::PromptBuilder;
|
use prompt_store::PromptBuilder;
|
||||||
|
@ -3009,7 +3009,6 @@ mod tests {
|
||||||
use settings::{Settings, SettingsStore};
|
use settings::{Settings, SettingsStore};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use theme::ThemeSettings;
|
use theme::ThemeSettings;
|
||||||
use ui::IconName;
|
|
||||||
use util::path;
|
use util::path;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
|
@ -3837,7 +3836,6 @@ fn main() {{
|
||||||
workspace::init_settings(cx);
|
workspace::init_settings(cx);
|
||||||
language_model::init_settings(cx);
|
language_model::init_settings(cx);
|
||||||
ThemeSettings::register(cx);
|
ThemeSettings::register(cx);
|
||||||
EditorSettings::register(cx);
|
|
||||||
ToolRegistry::default_global(cx);
|
ToolRegistry::default_global(cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
use std::cell::{Ref, RefCell};
|
use crate::{
|
||||||
use std::path::{Path, PathBuf};
|
context_server_tool::ContextServerTool,
|
||||||
use std::rc::Rc;
|
thread::{
|
||||||
use std::sync::{Arc, Mutex};
|
DetailedSummaryState, ExceededWindowError, MessageId, ProjectSnapshot, Thread, ThreadId,
|
||||||
|
},
|
||||||
|
};
|
||||||
use agent_settings::{AgentProfileId, CompletionMode};
|
use agent_settings::{AgentProfileId, CompletionMode};
|
||||||
use anyhow::{Context as _, Result, anyhow};
|
use anyhow::{Context as _, Result, anyhow};
|
||||||
use assistant_tool::{ToolId, ToolWorkingSet};
|
use assistant_tool::{ToolId, ToolWorkingSet};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use context_server::ContextServerId;
|
use context_server::ContextServerId;
|
||||||
use futures::channel::{mpsc, oneshot};
|
use futures::{
|
||||||
use futures::future::{self, BoxFuture, Shared};
|
FutureExt as _, StreamExt as _,
|
||||||
use futures::{FutureExt as _, StreamExt as _};
|
channel::{mpsc, oneshot},
|
||||||
|
future::{self, BoxFuture, Shared},
|
||||||
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, BackgroundExecutor, Context, Entity, EventEmitter, Global, ReadGlobal, SharedString,
|
App, BackgroundExecutor, Context, Entity, EventEmitter, Global, ReadGlobal, SharedString,
|
||||||
Subscription, Task, prelude::*,
|
Subscription, Task, Window, prelude::*,
|
||||||
};
|
};
|
||||||
|
use indoc::indoc;
|
||||||
use language_model::{LanguageModelToolResultContent, LanguageModelToolUseId, Role, TokenUsage};
|
use language_model::{LanguageModelToolResultContent, LanguageModelToolUseId, Role, TokenUsage};
|
||||||
use project::context_server_store::{ContextServerStatus, ContextServerStore};
|
use project::context_server_store::{ContextServerStatus, ContextServerStore};
|
||||||
use project::{Project, ProjectItem, ProjectPath, Worktree};
|
use project::{Project, ProjectItem, ProjectPath, Worktree};
|
||||||
|
@ -25,19 +28,18 @@ use prompt_store::{
|
||||||
UserRulesContext, WorktreeContext,
|
UserRulesContext, WorktreeContext,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ui::Window;
|
|
||||||
use util::ResultExt as _;
|
|
||||||
|
|
||||||
use crate::context_server_tool::ContextServerTool;
|
|
||||||
use crate::thread::{
|
|
||||||
DetailedSummaryState, ExceededWindowError, MessageId, ProjectSnapshot, Thread, ThreadId,
|
|
||||||
};
|
|
||||||
use indoc::indoc;
|
|
||||||
use sqlez::{
|
use sqlez::{
|
||||||
bindable::{Bind, Column},
|
bindable::{Bind, Column},
|
||||||
connection::Connection,
|
connection::Connection,
|
||||||
statement::Statement,
|
statement::Statement,
|
||||||
};
|
};
|
||||||
|
use std::{
|
||||||
|
cell::{Ref, RefCell},
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
rc::Rc,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
};
|
||||||
|
use util::ResultExt as _;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum DataType {
|
pub enum DataType {
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
use std::sync::Arc;
|
use crate::{
|
||||||
|
thread::{MessageId, PromptId, ThreadId},
|
||||||
|
thread_store::SerializedMessage,
|
||||||
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use assistant_tool::{
|
use assistant_tool::{
|
||||||
AnyToolCard, Tool, ToolResultContent, ToolResultOutput, ToolUseStatus, ToolWorkingSet,
|
AnyToolCard, Tool, ToolResultContent, ToolResultOutput, ToolUseStatus, ToolWorkingSet,
|
||||||
};
|
};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use futures::FutureExt as _;
|
use futures::{FutureExt as _, future::Shared};
|
||||||
use futures::future::Shared;
|
use gpui::{App, Entity, SharedString, Task, Window};
|
||||||
use gpui::{App, Entity, SharedString, Task};
|
use icons::IconName;
|
||||||
use language_model::{
|
use language_model::{
|
||||||
ConfiguredModel, LanguageModel, LanguageModelRequest, LanguageModelToolResult,
|
ConfiguredModel, LanguageModel, LanguageModelRequest, LanguageModelToolResult,
|
||||||
LanguageModelToolResultContent, LanguageModelToolUse, LanguageModelToolUseId, Role,
|
LanguageModelToolResultContent, LanguageModelToolUse, LanguageModelToolUseId, Role,
|
||||||
};
|
};
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use ui::{IconName, Window};
|
use std::sync::Arc;
|
||||||
use util::truncate_lines_to_byte_limit;
|
use util::truncate_lines_to_byte_limit;
|
||||||
|
|
||||||
use crate::thread::{MessageId, PromptId, ThreadId};
|
|
||||||
use crate::thread_store::SerializedMessage;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ToolUse {
|
pub struct ToolUse {
|
||||||
pub id: LanguageModelToolUseId,
|
pub id: LanguageModelToolUseId,
|
||||||
|
@ -26,7 +25,7 @@ pub struct ToolUse {
|
||||||
pub ui_text: SharedString,
|
pub ui_text: SharedString,
|
||||||
pub status: ToolUseStatus,
|
pub status: ToolUseStatus,
|
||||||
pub input: serde_json::Value,
|
pub input: serde_json::Value,
|
||||||
pub icon: ui::IconName,
|
pub icon: icons::IconName,
|
||||||
pub needs_confirmation: bool,
|
pub needs_confirmation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
107
crates/agent_ui/Cargo.toml
Normal file
107
crates/agent_ui/Cargo.toml
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
[package]
|
||||||
|
name = "agent_ui"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition.workspace = true
|
||||||
|
publish.workspace = true
|
||||||
|
license = "GPL-3.0-or-later"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/agent_ui.rs"
|
||||||
|
doctest = false
|
||||||
|
|
||||||
|
[features]
|
||||||
|
test-support = [
|
||||||
|
"gpui/test-support",
|
||||||
|
"language/test-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
agent.workspace = true
|
||||||
|
agent_settings.workspace = true
|
||||||
|
anyhow.workspace = true
|
||||||
|
assistant_context_editor.workspace = true
|
||||||
|
assistant_slash_command.workspace = true
|
||||||
|
assistant_slash_commands.workspace = true
|
||||||
|
assistant_tool.workspace = true
|
||||||
|
audio.workspace = true
|
||||||
|
buffer_diff.workspace = true
|
||||||
|
chrono.workspace = true
|
||||||
|
client.workspace = true
|
||||||
|
collections.workspace = true
|
||||||
|
component.workspace = true
|
||||||
|
context_server.workspace = true
|
||||||
|
db.workspace = true
|
||||||
|
editor.workspace = true
|
||||||
|
extension.workspace = true
|
||||||
|
extension_host.workspace = true
|
||||||
|
feature_flags.workspace = true
|
||||||
|
file_icons.workspace = true
|
||||||
|
fs.workspace = true
|
||||||
|
futures.workspace = true
|
||||||
|
fuzzy.workspace = true
|
||||||
|
gpui.workspace = true
|
||||||
|
html_to_markdown.workspace = true
|
||||||
|
indoc.workspace = true
|
||||||
|
http_client.workspace = true
|
||||||
|
indexed_docs.workspace = true
|
||||||
|
inventory.workspace = true
|
||||||
|
itertools.workspace = true
|
||||||
|
jsonschema.workspace = true
|
||||||
|
language.workspace = true
|
||||||
|
language_model.workspace = true
|
||||||
|
log.workspace = true
|
||||||
|
lsp.workspace = true
|
||||||
|
markdown.workspace = true
|
||||||
|
menu.workspace = true
|
||||||
|
multi_buffer.workspace = true
|
||||||
|
notifications.workspace = true
|
||||||
|
ordered-float.workspace = true
|
||||||
|
parking_lot.workspace = true
|
||||||
|
paths.workspace = true
|
||||||
|
picker.workspace = true
|
||||||
|
project.workspace = true
|
||||||
|
prompt_store.workspace = true
|
||||||
|
proto.workspace = true
|
||||||
|
release_channel.workspace = true
|
||||||
|
rope.workspace = true
|
||||||
|
rules_library.workspace = true
|
||||||
|
schemars.workspace = true
|
||||||
|
search.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
|
serde_json_lenient.workspace = true
|
||||||
|
settings.workspace = true
|
||||||
|
smol.workspace = true
|
||||||
|
streaming_diff.workspace = true
|
||||||
|
telemetry.workspace = true
|
||||||
|
telemetry_events.workspace = true
|
||||||
|
terminal.workspace = true
|
||||||
|
terminal_view.workspace = true
|
||||||
|
text.workspace = true
|
||||||
|
theme.workspace = true
|
||||||
|
time.workspace = true
|
||||||
|
time_format.workspace = true
|
||||||
|
ui.workspace = true
|
||||||
|
urlencoding.workspace = true
|
||||||
|
util.workspace = true
|
||||||
|
uuid.workspace = true
|
||||||
|
watch.workspace = true
|
||||||
|
workspace-hack.workspace = true
|
||||||
|
workspace.workspace = true
|
||||||
|
zed_actions.workspace = true
|
||||||
|
zed_llm_client.workspace = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
assistant_tools.workspace = true
|
||||||
|
buffer_diff = { workspace = true, features = ["test-support"] }
|
||||||
|
editor = { workspace = true, features = ["test-support"] }
|
||||||
|
gpui = { workspace = true, "features" = ["test-support"] }
|
||||||
|
indoc.workspace = true
|
||||||
|
language = { workspace = true, "features" = ["test-support"] }
|
||||||
|
language_model = { workspace = true, "features" = ["test-support"] }
|
||||||
|
pretty_assertions.workspace = true
|
||||||
|
project = { workspace = true, features = ["test-support"] }
|
||||||
|
rand.workspace = true
|
1
crates/agent_ui/LICENSE-GPL
Symbolic link
1
crates/agent_ui/LICENSE-GPL
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../LICENSE-GPL
|
|
@ -1,18 +1,17 @@
|
||||||
use crate::context::{AgentContextHandle, RULES_ICON};
|
|
||||||
use crate::context_picker::{ContextPicker, MentionLink};
|
use crate::context_picker::{ContextPicker, MentionLink};
|
||||||
use crate::context_store::ContextStore;
|
|
||||||
use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind};
|
use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind};
|
||||||
use crate::message_editor::{extract_message_creases, insert_message_creases};
|
use crate::message_editor::{extract_message_creases, insert_message_creases};
|
||||||
use crate::thread::{
|
|
||||||
LastRestoreCheckpoint, MessageCrease, MessageId, MessageSegment, Thread, ThreadError,
|
|
||||||
ThreadEvent, ThreadFeedback, ThreadSummary,
|
|
||||||
};
|
|
||||||
use crate::thread_store::{RulesLoadingError, TextThreadStore, ThreadStore};
|
|
||||||
use crate::tool_use::{PendingToolUseStatus, ToolUse};
|
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
AddedContext, AgentNotification, AgentNotificationEvent, AnimatedLabel, ContextPill,
|
AddedContext, AgentNotification, AgentNotificationEvent, AnimatedLabel, ContextPill,
|
||||||
};
|
};
|
||||||
use crate::{AgentPanel, ModelUsageContext};
|
use crate::{AgentPanel, ModelUsageContext};
|
||||||
|
use agent::{
|
||||||
|
ContextStore, LastRestoreCheckpoint, MessageCrease, MessageId, MessageSegment, TextThreadStore,
|
||||||
|
Thread, ThreadError, ThreadEvent, ThreadFeedback, ThreadStore, ThreadSummary,
|
||||||
|
context::{self, AgentContextHandle, RULES_ICON},
|
||||||
|
thread_store::RulesLoadingError,
|
||||||
|
tool_use::{PendingToolUseStatus, ToolUse},
|
||||||
|
};
|
||||||
use agent_settings::{AgentSettings, NotifyWhenAgentWaiting};
|
use agent_settings::{AgentSettings, NotifyWhenAgentWaiting};
|
||||||
use anyhow::Context as _;
|
use anyhow::Context as _;
|
||||||
use assistant_tool::ToolUseStatus;
|
use assistant_tool::ToolUseStatus;
|
||||||
|
@ -1583,8 +1582,7 @@ impl ActiveThread {
|
||||||
let git_store = project.read(cx).git_store().clone();
|
let git_store = project.read(cx).git_store().clone();
|
||||||
let checkpoint = git_store.update(cx, |git_store, cx| git_store.checkpoint(cx));
|
let checkpoint = git_store.update(cx, |git_store, cx| git_store.checkpoint(cx));
|
||||||
|
|
||||||
let load_context_task =
|
let load_context_task = context::load_context(new_context, &project, &prompt_store, cx);
|
||||||
crate::context::load_context(new_context, &project, &prompt_store, cx);
|
|
||||||
self._load_edited_message_context_task =
|
self._load_edited_message_context_task =
|
||||||
Some(cx.spawn_in(window, async move |this, cx| {
|
Some(cx.spawn_in(window, async move |this, cx| {
|
||||||
let (context, checkpoint) =
|
let (context, checkpoint) =
|
||||||
|
@ -1737,7 +1735,7 @@ impl ActiveThread {
|
||||||
telemetry::event!(
|
telemetry::event!(
|
||||||
"Assistant Thread Feedback Comments",
|
"Assistant Thread Feedback Comments",
|
||||||
thread_id,
|
thread_id,
|
||||||
message_id = message_id.0,
|
message_id = message_id.as_usize(),
|
||||||
message_content,
|
message_content,
|
||||||
comments = comments_value
|
comments = comments_value
|
||||||
);
|
);
|
||||||
|
@ -3723,8 +3721,10 @@ fn open_editor_at_position(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use agent::{MessageSegment, context::ContextLoadResult, thread_store};
|
||||||
use assistant_tool::{ToolRegistry, ToolWorkingSet};
|
use assistant_tool::{ToolRegistry, ToolWorkingSet};
|
||||||
use editor::{EditorSettings, display_map::CreaseMetadata};
|
use editor::EditorSettings;
|
||||||
use fs::FakeFs;
|
use fs::FakeFs;
|
||||||
use gpui::{AppContext, TestAppContext, VisualTestContext};
|
use gpui::{AppContext, TestAppContext, VisualTestContext};
|
||||||
use language_model::{
|
use language_model::{
|
||||||
|
@ -3738,10 +3738,6 @@ mod tests {
|
||||||
use util::path;
|
use util::path;
|
||||||
use workspace::CollaboratorId;
|
use workspace::CollaboratorId;
|
||||||
|
|
||||||
use crate::{ContextLoadResult, thread::MessageSegment, thread_store};
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_agent_is_unfollowed_after_cancelling_completion(cx: &mut TestAppContext) {
|
async fn test_agent_is_unfollowed_after_cancelling_completion(cx: &mut TestAppContext) {
|
||||||
init_test_settings(cx);
|
init_test_settings(cx);
|
||||||
|
@ -3813,10 +3809,8 @@ mod tests {
|
||||||
|
|
||||||
let creases = vec![MessageCrease {
|
let creases = vec![MessageCrease {
|
||||||
range: 14..22,
|
range: 14..22,
|
||||||
metadata: CreaseMetadata {
|
icon_path: "icon".into(),
|
||||||
icon_path: "icon".into(),
|
label: "foo.txt".into(),
|
||||||
label: "foo.txt".into(),
|
|
||||||
},
|
|
||||||
context: None,
|
context: None,
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -15,8 +15,8 @@ use workspace::{ModalView, Workspace};
|
||||||
|
|
||||||
use crate::agent_configuration::manage_profiles_modal::profile_modal_header::ProfileModalHeader;
|
use crate::agent_configuration::manage_profiles_modal::profile_modal_header::ProfileModalHeader;
|
||||||
use crate::agent_configuration::tool_picker::{ToolPicker, ToolPickerDelegate};
|
use crate::agent_configuration::tool_picker::{ToolPicker, ToolPickerDelegate};
|
||||||
use crate::agent_profile::AgentProfile;
|
|
||||||
use crate::{AgentPanel, ManageProfiles};
|
use crate::{AgentPanel, ManageProfiles};
|
||||||
|
use agent::agent_profile::AgentProfile;
|
||||||
|
|
||||||
use super::tool_picker::ToolPickerMode;
|
use super::tool_picker::ToolPickerMode;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::{Keep, KeepAll, OpenAgentDiff, Reject, RejectAll, Thread, ThreadEvent};
|
use crate::{Keep, KeepAll, OpenAgentDiff, Reject, RejectAll};
|
||||||
|
use agent::{Thread, ThreadEvent};
|
||||||
use agent_settings::AgentSettings;
|
use agent_settings::AgentSettings;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use buffer_diff::DiffHunkStatus;
|
use buffer_diff::DiffHunkStatus;
|
||||||
|
@ -1748,7 +1749,8 @@ impl editor::Addon for EditorAgentDiffAddon {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{Keep, ThreadStore, thread_store};
|
use crate::Keep;
|
||||||
|
use agent::thread_store::{self, ThreadStore};
|
||||||
use agent_settings::AgentSettings;
|
use agent_settings::AgentSettings;
|
||||||
use assistant_tool::ToolWorkingSet;
|
use assistant_tool::ToolWorkingSet;
|
||||||
use editor::EditorSettings;
|
use editor::EditorSettings;
|
|
@ -45,30 +45,34 @@ use ui::{
|
||||||
PopoverMenuHandle, ProgressBar, Tab, Tooltip, Vector, VectorName, prelude::*,
|
PopoverMenuHandle, ProgressBar, Tab, Tooltip, Vector, VectorName, prelude::*,
|
||||||
};
|
};
|
||||||
use util::ResultExt as _;
|
use util::ResultExt as _;
|
||||||
use workspace::dock::{DockPosition, Panel, PanelEvent};
|
|
||||||
use workspace::{
|
use workspace::{
|
||||||
CollaboratorId, DraggedSelection, DraggedTab, ToggleZoom, ToolbarItemView, Workspace,
|
CollaboratorId, DraggedSelection, DraggedTab, ToggleZoom, ToolbarItemView, Workspace,
|
||||||
|
dock::{DockPosition, Panel, PanelEvent},
|
||||||
|
};
|
||||||
|
use zed_actions::{
|
||||||
|
DecreaseBufferFontSize, IncreaseBufferFontSize, ResetBufferFontSize,
|
||||||
|
agent::{OpenConfiguration, OpenOnboardingModal, ResetOnboarding},
|
||||||
|
assistant::{OpenRulesLibrary, ToggleFocus},
|
||||||
};
|
};
|
||||||
use zed_actions::agent::{OpenConfiguration, OpenOnboardingModal, ResetOnboarding};
|
|
||||||
use zed_actions::assistant::{OpenRulesLibrary, ToggleFocus};
|
|
||||||
use zed_actions::{DecreaseBufferFontSize, IncreaseBufferFontSize, ResetBufferFontSize};
|
|
||||||
use zed_llm_client::{CompletionIntent, UsageLimit};
|
use zed_llm_client::{CompletionIntent, UsageLimit};
|
||||||
|
|
||||||
use crate::active_thread::{self, ActiveThread, ActiveThreadEvent};
|
|
||||||
use crate::agent_configuration::{AgentConfiguration, AssistantConfigurationEvent};
|
|
||||||
use crate::agent_diff::AgentDiff;
|
|
||||||
use crate::history_store::{HistoryEntryId, HistoryStore};
|
|
||||||
use crate::message_editor::{MessageEditor, MessageEditorEvent};
|
|
||||||
use crate::thread::{Thread, ThreadError, ThreadId, ThreadSummary, TokenUsageRatio};
|
|
||||||
use crate::thread_history::{HistoryEntryElement, ThreadHistory};
|
|
||||||
use crate::thread_store::ThreadStore;
|
|
||||||
use crate::ui::AgentOnboardingModal;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AddContextServer, AgentDiffPane, ContextStore, ContinueThread, ContinueWithBurnMode,
|
AddContextServer, AgentDiffPane, ContinueThread, ContinueWithBurnMode,
|
||||||
DeleteRecentlyOpenThread, ExpandMessageEditor, Follow, InlineAssistant, NewTextThread,
|
DeleteRecentlyOpenThread, ExpandMessageEditor, Follow, InlineAssistant, NewTextThread,
|
||||||
NewThread, OpenActiveThreadAsMarkdown, OpenAgentDiff, OpenHistory, ResetTrialEndUpsell,
|
NewThread, OpenActiveThreadAsMarkdown, OpenAgentDiff, OpenHistory, ResetTrialEndUpsell,
|
||||||
ResetTrialUpsell, TextThreadStore, ThreadEvent, ToggleBurnMode, ToggleContextPicker,
|
ResetTrialUpsell, ToggleBurnMode, ToggleContextPicker, ToggleNavigationMenu, ToggleOptionsMenu,
|
||||||
ToggleNavigationMenu, ToggleOptionsMenu,
|
active_thread::{self, ActiveThread, ActiveThreadEvent},
|
||||||
|
agent_configuration::{AgentConfiguration, AssistantConfigurationEvent},
|
||||||
|
agent_diff::AgentDiff,
|
||||||
|
message_editor::{MessageEditor, MessageEditorEvent},
|
||||||
|
thread_history::{HistoryEntryElement, ThreadHistory},
|
||||||
|
ui::AgentOnboardingModal,
|
||||||
|
};
|
||||||
|
use agent::{
|
||||||
|
Thread, ThreadError, ThreadEvent, ThreadId, ThreadSummary, TokenUsageRatio,
|
||||||
|
context_store::ContextStore,
|
||||||
|
history_store::{HistoryEntryId, HistoryStore},
|
||||||
|
thread_store::{TextThreadStore, ThreadStore},
|
||||||
};
|
};
|
||||||
|
|
||||||
const AGENT_PANEL_KEY: &str = "agent_panel";
|
const AGENT_PANEL_KEY: &str = "agent_panel";
|
||||||
|
@ -369,7 +373,7 @@ pub struct AgentPanel {
|
||||||
_default_model_subscription: Subscription,
|
_default_model_subscription: Subscription,
|
||||||
context_store: Entity<TextThreadStore>,
|
context_store: Entity<TextThreadStore>,
|
||||||
prompt_store: Option<Entity<PromptStore>>,
|
prompt_store: Option<Entity<PromptStore>>,
|
||||||
inline_assist_context_store: Entity<crate::context_store::ContextStore>,
|
inline_assist_context_store: Entity<ContextStore>,
|
||||||
configuration: Option<Entity<AgentConfiguration>>,
|
configuration: Option<Entity<AgentConfiguration>>,
|
||||||
configuration_subscription: Option<Subscription>,
|
configuration_subscription: Option<Subscription>,
|
||||||
local_timezone: UtcOffset,
|
local_timezone: UtcOffset,
|
||||||
|
@ -490,18 +494,10 @@ impl AgentPanel {
|
||||||
let workspace = workspace.weak_handle();
|
let workspace = workspace.weak_handle();
|
||||||
let weak_self = cx.entity().downgrade();
|
let weak_self = cx.entity().downgrade();
|
||||||
|
|
||||||
let message_editor_context_store = cx.new(|_cx| {
|
let message_editor_context_store =
|
||||||
crate::context_store::ContextStore::new(
|
cx.new(|_cx| ContextStore::new(project.downgrade(), Some(thread_store.downgrade())));
|
||||||
project.downgrade(),
|
let inline_assist_context_store =
|
||||||
Some(thread_store.downgrade()),
|
cx.new(|_cx| ContextStore::new(project.downgrade(), Some(thread_store.downgrade())));
|
||||||
)
|
|
||||||
});
|
|
||||||
let inline_assist_context_store = cx.new(|_cx| {
|
|
||||||
crate::context_store::ContextStore::new(
|
|
||||||
project.downgrade(),
|
|
||||||
Some(thread_store.downgrade()),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
let message_editor = cx.new(|cx| {
|
let message_editor = cx.new(|cx| {
|
||||||
MessageEditor::new(
|
MessageEditor::new(
|
||||||
|
@ -708,9 +704,7 @@ impl AgentPanel {
|
||||||
&self.prompt_store
|
&self.prompt_store
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn inline_assist_context_store(
|
pub(crate) fn inline_assist_context_store(&self) -> &Entity<ContextStore> {
|
||||||
&self,
|
|
||||||
) -> &Entity<crate::context_store::ContextStore> {
|
|
||||||
&self.inline_assist_context_store
|
&self.inline_assist_context_store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,7 +736,7 @@ impl AgentPanel {
|
||||||
self.set_active_view(thread_view, window, cx);
|
self.set_active_view(thread_view, window, cx);
|
||||||
|
|
||||||
let context_store = cx.new(|_cx| {
|
let context_store = cx.new(|_cx| {
|
||||||
crate::context_store::ContextStore::new(
|
ContextStore::new(
|
||||||
self.project.downgrade(),
|
self.project.downgrade(),
|
||||||
Some(self.thread_store.downgrade()),
|
Some(self.thread_store.downgrade()),
|
||||||
)
|
)
|
||||||
|
@ -990,7 +984,7 @@ impl AgentPanel {
|
||||||
let thread_view = ActiveView::thread(thread.clone(), window, cx);
|
let thread_view = ActiveView::thread(thread.clone(), window, cx);
|
||||||
self.set_active_view(thread_view, window, cx);
|
self.set_active_view(thread_view, window, cx);
|
||||||
let context_store = cx.new(|_cx| {
|
let context_store = cx.new(|_cx| {
|
||||||
crate::context_store::ContextStore::new(
|
ContextStore::new(
|
||||||
self.project.downgrade(),
|
self.project.downgrade(),
|
||||||
Some(self.thread_store.downgrade()),
|
Some(self.thread_store.downgrade()),
|
||||||
)
|
)
|
285
crates/agent_ui/src/agent_ui.rs
Normal file
285
crates/agent_ui/src/agent_ui.rs
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
mod active_thread;
|
||||||
|
mod agent_configuration;
|
||||||
|
mod agent_diff;
|
||||||
|
mod agent_model_selector;
|
||||||
|
mod agent_panel;
|
||||||
|
mod buffer_codegen;
|
||||||
|
mod context_picker;
|
||||||
|
mod context_server_configuration;
|
||||||
|
mod context_strip;
|
||||||
|
mod debug;
|
||||||
|
mod inline_assistant;
|
||||||
|
mod inline_prompt_editor;
|
||||||
|
mod message_editor;
|
||||||
|
mod profile_selector;
|
||||||
|
mod slash_command_settings;
|
||||||
|
mod terminal_codegen;
|
||||||
|
mod terminal_inline_assistant;
|
||||||
|
mod thread_history;
|
||||||
|
mod tool_compatibility;
|
||||||
|
mod ui;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use agent::{Thread, ThreadId};
|
||||||
|
use agent_settings::{AgentProfileId, AgentSettings, LanguageModelSelection};
|
||||||
|
use assistant_slash_command::SlashCommandRegistry;
|
||||||
|
use client::Client;
|
||||||
|
use feature_flags::FeatureFlagAppExt as _;
|
||||||
|
use fs::Fs;
|
||||||
|
use gpui::{App, Entity, actions, impl_actions};
|
||||||
|
use language::LanguageRegistry;
|
||||||
|
use language_model::{
|
||||||
|
ConfiguredModel, LanguageModel, LanguageModelId, LanguageModelProviderId, LanguageModelRegistry,
|
||||||
|
};
|
||||||
|
use prompt_store::PromptBuilder;
|
||||||
|
use schemars::JsonSchema;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use settings::{Settings as _, SettingsStore};
|
||||||
|
|
||||||
|
pub use crate::active_thread::ActiveThread;
|
||||||
|
use crate::agent_configuration::{ConfigureContextServerModal, ManageProfilesModal};
|
||||||
|
pub use crate::agent_panel::{AgentPanel, ConcreteAssistantPanelDelegate};
|
||||||
|
pub use crate::inline_assistant::InlineAssistant;
|
||||||
|
use crate::slash_command_settings::SlashCommandSettings;
|
||||||
|
pub use agent_diff::{AgentDiffPane, AgentDiffToolbar};
|
||||||
|
pub use ui::preview::{all_agent_previews, get_agent_preview};
|
||||||
|
|
||||||
|
actions!(
|
||||||
|
agent,
|
||||||
|
[
|
||||||
|
NewTextThread,
|
||||||
|
ToggleContextPicker,
|
||||||
|
ToggleNavigationMenu,
|
||||||
|
ToggleOptionsMenu,
|
||||||
|
DeleteRecentlyOpenThread,
|
||||||
|
ToggleProfileSelector,
|
||||||
|
RemoveAllContext,
|
||||||
|
ExpandMessageEditor,
|
||||||
|
OpenHistory,
|
||||||
|
AddContextServer,
|
||||||
|
RemoveSelectedThread,
|
||||||
|
Chat,
|
||||||
|
ChatWithFollow,
|
||||||
|
CycleNextInlineAssist,
|
||||||
|
CyclePreviousInlineAssist,
|
||||||
|
FocusUp,
|
||||||
|
FocusDown,
|
||||||
|
FocusLeft,
|
||||||
|
FocusRight,
|
||||||
|
RemoveFocusedContext,
|
||||||
|
AcceptSuggestedContext,
|
||||||
|
OpenActiveThreadAsMarkdown,
|
||||||
|
OpenAgentDiff,
|
||||||
|
Keep,
|
||||||
|
Reject,
|
||||||
|
RejectAll,
|
||||||
|
KeepAll,
|
||||||
|
Follow,
|
||||||
|
ResetTrialUpsell,
|
||||||
|
ResetTrialEndUpsell,
|
||||||
|
ContinueThread,
|
||||||
|
ContinueWithBurnMode,
|
||||||
|
ToggleBurnMode,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
#[derive(Default, Clone, PartialEq, Deserialize, JsonSchema)]
|
||||||
|
pub struct NewThread {
|
||||||
|
#[serde(default)]
|
||||||
|
from_thread_id: Option<ThreadId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
|
||||||
|
pub struct ManageProfiles {
|
||||||
|
#[serde(default)]
|
||||||
|
pub customize_tools: Option<AgentProfileId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ManageProfiles {
|
||||||
|
pub fn customize_tools(profile_id: AgentProfileId) -> Self {
|
||||||
|
Self {
|
||||||
|
customize_tools: Some(profile_id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_actions!(agent, [NewThread, ManageProfiles]);
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(crate) enum ModelUsageContext {
|
||||||
|
Thread(Entity<Thread>),
|
||||||
|
InlineAssistant,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModelUsageContext {
|
||||||
|
pub fn configured_model(&self, cx: &App) -> Option<ConfiguredModel> {
|
||||||
|
match self {
|
||||||
|
Self::Thread(thread) => thread.read(cx).configured_model(),
|
||||||
|
Self::InlineAssistant => {
|
||||||
|
LanguageModelRegistry::read_global(cx).inline_assistant_model()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn language_model(&self, cx: &App) -> Option<Arc<dyn LanguageModel>> {
|
||||||
|
self.configured_model(cx)
|
||||||
|
.map(|configured_model| configured_model.model)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initializes the `agent` crate.
|
||||||
|
pub fn init(
|
||||||
|
fs: Arc<dyn Fs>,
|
||||||
|
client: Arc<Client>,
|
||||||
|
prompt_builder: Arc<PromptBuilder>,
|
||||||
|
language_registry: Arc<LanguageRegistry>,
|
||||||
|
is_eval: bool,
|
||||||
|
cx: &mut App,
|
||||||
|
) {
|
||||||
|
AgentSettings::register(cx);
|
||||||
|
SlashCommandSettings::register(cx);
|
||||||
|
|
||||||
|
assistant_context_editor::init(client.clone(), cx);
|
||||||
|
rules_library::init(cx);
|
||||||
|
if !is_eval {
|
||||||
|
// Initializing the language model from the user settings messes with the eval, so we only initialize them when
|
||||||
|
// we're not running inside of the eval.
|
||||||
|
init_language_model_settings(cx);
|
||||||
|
}
|
||||||
|
assistant_slash_command::init(cx);
|
||||||
|
agent::init(cx);
|
||||||
|
agent_panel::init(cx);
|
||||||
|
context_server_configuration::init(language_registry.clone(), fs.clone(), cx);
|
||||||
|
|
||||||
|
register_slash_commands(cx);
|
||||||
|
inline_assistant::init(
|
||||||
|
fs.clone(),
|
||||||
|
prompt_builder.clone(),
|
||||||
|
client.telemetry().clone(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
terminal_inline_assistant::init(
|
||||||
|
fs.clone(),
|
||||||
|
prompt_builder.clone(),
|
||||||
|
client.telemetry().clone(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
indexed_docs::init(cx);
|
||||||
|
cx.observe_new(move |workspace, window, cx| {
|
||||||
|
ConfigureContextServerModal::register(workspace, language_registry.clone(), window, cx)
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
cx.observe_new(ManageProfilesModal::register).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_language_model_settings(cx: &mut App) {
|
||||||
|
update_active_language_model_from_settings(cx);
|
||||||
|
|
||||||
|
cx.observe_global::<SettingsStore>(update_active_language_model_from_settings)
|
||||||
|
.detach();
|
||||||
|
cx.subscribe(
|
||||||
|
&LanguageModelRegistry::global(cx),
|
||||||
|
|_, event: &language_model::Event, cx| match event {
|
||||||
|
language_model::Event::ProviderStateChanged
|
||||||
|
| language_model::Event::AddedProvider(_)
|
||||||
|
| language_model::Event::RemovedProvider(_) => {
|
||||||
|
update_active_language_model_from_settings(cx);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_active_language_model_from_settings(cx: &mut App) {
|
||||||
|
let settings = AgentSettings::get_global(cx);
|
||||||
|
|
||||||
|
fn to_selected_model(selection: &LanguageModelSelection) -> language_model::SelectedModel {
|
||||||
|
language_model::SelectedModel {
|
||||||
|
provider: LanguageModelProviderId::from(selection.provider.0.clone()),
|
||||||
|
model: LanguageModelId::from(selection.model.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let default = to_selected_model(&settings.default_model);
|
||||||
|
let inline_assistant = settings
|
||||||
|
.inline_assistant_model
|
||||||
|
.as_ref()
|
||||||
|
.map(to_selected_model);
|
||||||
|
let commit_message = settings
|
||||||
|
.commit_message_model
|
||||||
|
.as_ref()
|
||||||
|
.map(to_selected_model);
|
||||||
|
let thread_summary = settings
|
||||||
|
.thread_summary_model
|
||||||
|
.as_ref()
|
||||||
|
.map(to_selected_model);
|
||||||
|
let inline_alternatives = settings
|
||||||
|
.inline_alternatives
|
||||||
|
.iter()
|
||||||
|
.map(to_selected_model)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
LanguageModelRegistry::global(cx).update(cx, |registry, cx| {
|
||||||
|
registry.select_default_model(Some(&default), cx);
|
||||||
|
registry.select_inline_assistant_model(inline_assistant.as_ref(), cx);
|
||||||
|
registry.select_commit_message_model(commit_message.as_ref(), cx);
|
||||||
|
registry.select_thread_summary_model(thread_summary.as_ref(), cx);
|
||||||
|
registry.select_inline_alternative_models(inline_alternatives, cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_slash_commands(cx: &mut App) {
|
||||||
|
let slash_command_registry = SlashCommandRegistry::global(cx);
|
||||||
|
|
||||||
|
slash_command_registry.register_command(assistant_slash_commands::FileSlashCommand, true);
|
||||||
|
slash_command_registry.register_command(assistant_slash_commands::DeltaSlashCommand, true);
|
||||||
|
slash_command_registry.register_command(assistant_slash_commands::OutlineSlashCommand, true);
|
||||||
|
slash_command_registry.register_command(assistant_slash_commands::TabSlashCommand, true);
|
||||||
|
slash_command_registry
|
||||||
|
.register_command(assistant_slash_commands::CargoWorkspaceSlashCommand, true);
|
||||||
|
slash_command_registry.register_command(assistant_slash_commands::PromptSlashCommand, true);
|
||||||
|
slash_command_registry.register_command(assistant_slash_commands::SelectionCommand, true);
|
||||||
|
slash_command_registry.register_command(assistant_slash_commands::DefaultSlashCommand, false);
|
||||||
|
slash_command_registry.register_command(assistant_slash_commands::NowSlashCommand, false);
|
||||||
|
slash_command_registry
|
||||||
|
.register_command(assistant_slash_commands::DiagnosticsSlashCommand, true);
|
||||||
|
slash_command_registry.register_command(assistant_slash_commands::FetchSlashCommand, true);
|
||||||
|
|
||||||
|
cx.observe_flag::<assistant_slash_commands::StreamingExampleSlashCommandFeatureFlag, _>({
|
||||||
|
let slash_command_registry = slash_command_registry.clone();
|
||||||
|
move |is_enabled, _cx| {
|
||||||
|
if is_enabled {
|
||||||
|
slash_command_registry.register_command(
|
||||||
|
assistant_slash_commands::StreamingExampleSlashCommand,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
|
||||||
|
update_slash_commands_from_settings(cx);
|
||||||
|
cx.observe_global::<SettingsStore>(update_slash_commands_from_settings)
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_slash_commands_from_settings(cx: &mut App) {
|
||||||
|
let slash_command_registry = SlashCommandRegistry::global(cx);
|
||||||
|
let settings = SlashCommandSettings::get_global(cx);
|
||||||
|
|
||||||
|
if settings.docs.enabled {
|
||||||
|
slash_command_registry.register_command(assistant_slash_commands::DocsSlashCommand, true);
|
||||||
|
} else {
|
||||||
|
slash_command_registry.unregister_command(assistant_slash_commands::DocsSlashCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
if settings.cargo_workspace.enabled {
|
||||||
|
slash_command_registry
|
||||||
|
.register_command(assistant_slash_commands::CargoWorkspaceSlashCommand, true);
|
||||||
|
} else {
|
||||||
|
slash_command_registry
|
||||||
|
.unregister_command(assistant_slash_commands::CargoWorkspaceSlashCommand);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
use crate::context::ContextLoadResult;
|
|
||||||
use crate::inline_prompt_editor::CodegenStatus;
|
use crate::inline_prompt_editor::CodegenStatus;
|
||||||
use crate::{context::load_context, context_store::ContextStore};
|
use agent::{
|
||||||
|
ContextStore,
|
||||||
|
context::{ContextLoadResult, load_context},
|
||||||
|
};
|
||||||
use agent_settings::AgentSettings;
|
use agent_settings::AgentSettings;
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
use client::telemetry::Telemetry;
|
use client::telemetry::Telemetry;
|
||||||
|
@ -18,8 +20,7 @@ use language_model::{
|
||||||
use multi_buffer::MultiBufferRow;
|
use multi_buffer::MultiBufferRow;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use prompt_store::PromptBuilder;
|
use prompt_store::{PromptBuilder, PromptStore};
|
||||||
use prompt_store::PromptStore;
|
|
||||||
use rope::Rope;
|
use rope::Rope;
|
||||||
use smol::future::FutureExt;
|
use smol::future::FutureExt;
|
||||||
use std::{
|
use std::{
|
|
@ -37,10 +37,12 @@ use uuid::Uuid;
|
||||||
use workspace::{Workspace, notifications::NotifyResultExt};
|
use workspace::{Workspace, notifications::NotifyResultExt};
|
||||||
|
|
||||||
use crate::AgentPanel;
|
use crate::AgentPanel;
|
||||||
use crate::context::RULES_ICON;
|
use agent::{
|
||||||
use crate::context_store::ContextStore;
|
ThreadId,
|
||||||
use crate::thread::ThreadId;
|
context::RULES_ICON,
|
||||||
use crate::thread_store::{TextThreadStore, ThreadStore};
|
context_store::ContextStore,
|
||||||
|
thread_store::{TextThreadStore, ThreadStore},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
enum ContextPickerEntry {
|
enum ContextPickerEntry {
|
|
@ -3,6 +3,7 @@ use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
|
|
||||||
|
use agent::context_store::ContextStore;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use editor::{CompletionProvider, Editor, ExcerptId, ToOffset as _};
|
use editor::{CompletionProvider, Editor, ExcerptId, ToOffset as _};
|
||||||
use file_icons::FileIcons;
|
use file_icons::FileIcons;
|
||||||
|
@ -20,10 +21,11 @@ use ui::prelude::*;
|
||||||
use util::ResultExt as _;
|
use util::ResultExt as _;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
use crate::Thread;
|
use agent::{
|
||||||
use crate::context::{AgentContextHandle, AgentContextKey, ContextCreasesAddon, RULES_ICON};
|
Thread,
|
||||||
use crate::context_store::ContextStore;
|
context::{AgentContextHandle, AgentContextKey, RULES_ICON},
|
||||||
use crate::thread_store::{TextThreadStore, ThreadStore};
|
thread_store::{TextThreadStore, ThreadStore},
|
||||||
|
};
|
||||||
|
|
||||||
use super::fetch_context_picker::fetch_url_content;
|
use super::fetch_context_picker::fetch_url_content;
|
||||||
use super::file_context_picker::{FileMatch, search_files};
|
use super::file_context_picker::{FileMatch, search_files};
|
||||||
|
@ -35,6 +37,7 @@ use super::{
|
||||||
ContextPickerAction, ContextPickerEntry, ContextPickerMode, MentionLink, RecentEntry,
|
ContextPickerAction, ContextPickerEntry, ContextPickerMode, MentionLink, RecentEntry,
|
||||||
available_context_picker_entries, recent_context_picker_entries, selection_ranges,
|
available_context_picker_entries, recent_context_picker_entries, selection_ranges,
|
||||||
};
|
};
|
||||||
|
use crate::message_editor::ContextCreasesAddon;
|
||||||
|
|
||||||
pub(crate) enum Match {
|
pub(crate) enum Match {
|
||||||
File(FileMatch),
|
File(FileMatch),
|
|
@ -2,6 +2,7 @@ use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use agent::context_store::ContextStore;
|
||||||
use anyhow::{Context as _, Result, bail};
|
use anyhow::{Context as _, Result, bail};
|
||||||
use futures::AsyncReadExt as _;
|
use futures::AsyncReadExt as _;
|
||||||
use gpui::{App, DismissEvent, Entity, FocusHandle, Focusable, Task, WeakEntity};
|
use gpui::{App, DismissEvent, Entity, FocusHandle, Focusable, Task, WeakEntity};
|
||||||
|
@ -12,7 +13,6 @@ use ui::{Context, ListItem, Window, prelude::*};
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
use crate::context_picker::ContextPicker;
|
use crate::context_picker::ContextPicker;
|
||||||
use crate::context_store::ContextStore;
|
|
||||||
|
|
||||||
pub struct FetchContextPicker {
|
pub struct FetchContextPicker {
|
||||||
picker: Entity<Picker<FetchContextPickerDelegate>>,
|
picker: Entity<Picker<FetchContextPickerDelegate>>,
|
|
@ -14,7 +14,7 @@ use util::ResultExt as _;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
use crate::context_picker::ContextPicker;
|
use crate::context_picker::ContextPicker;
|
||||||
use crate::context_store::{ContextStore, FileInclusion};
|
use agent::context_store::{ContextStore, FileInclusion};
|
||||||
|
|
||||||
pub struct FileContextPicker {
|
pub struct FileContextPicker {
|
||||||
picker: Entity<Picker<FileContextPickerDelegate>>,
|
picker: Entity<Picker<FileContextPickerDelegate>>,
|
|
@ -7,9 +7,9 @@ use prompt_store::{PromptId, PromptStore, UserPromptId};
|
||||||
use ui::{ListItem, prelude::*};
|
use ui::{ListItem, prelude::*};
|
||||||
use util::ResultExt as _;
|
use util::ResultExt as _;
|
||||||
|
|
||||||
use crate::context::RULES_ICON;
|
|
||||||
use crate::context_picker::ContextPicker;
|
use crate::context_picker::ContextPicker;
|
||||||
use crate::context_store::{self, ContextStore};
|
use agent::context::RULES_ICON;
|
||||||
|
use agent::context_store::{self, ContextStore};
|
||||||
|
|
||||||
pub struct RulesContextPicker {
|
pub struct RulesContextPicker {
|
||||||
picker: Entity<Picker<RulesContextPickerDelegate>>,
|
picker: Entity<Picker<RulesContextPickerDelegate>>,
|
|
@ -14,9 +14,9 @@ use ui::{ListItem, prelude::*};
|
||||||
use util::ResultExt as _;
|
use util::ResultExt as _;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
use crate::context::AgentContextHandle;
|
|
||||||
use crate::context_picker::ContextPicker;
|
use crate::context_picker::ContextPicker;
|
||||||
use crate::context_store::ContextStore;
|
use agent::context::AgentContextHandle;
|
||||||
|
use agent::context_store::ContextStore;
|
||||||
|
|
||||||
pub struct SymbolContextPicker {
|
pub struct SymbolContextPicker {
|
||||||
picker: Entity<Picker<SymbolContextPickerDelegate>>,
|
picker: Entity<Picker<SymbolContextPickerDelegate>>,
|
|
@ -9,9 +9,11 @@ use picker::{Picker, PickerDelegate};
|
||||||
use ui::{ListItem, prelude::*};
|
use ui::{ListItem, prelude::*};
|
||||||
|
|
||||||
use crate::context_picker::ContextPicker;
|
use crate::context_picker::ContextPicker;
|
||||||
use crate::context_store::{self, ContextStore};
|
use agent::{
|
||||||
use crate::thread::ThreadId;
|
ThreadId,
|
||||||
use crate::thread_store::{TextThreadStore, ThreadStore};
|
context_store::{self, ContextStore},
|
||||||
|
thread_store::{TextThreadStore, ThreadStore},
|
||||||
|
};
|
||||||
|
|
||||||
pub struct ThreadContextPicker {
|
pub struct ThreadContextPicker {
|
||||||
picker: Entity<Picker<ThreadContextPickerDelegate>>,
|
picker: Entity<Picker<ThreadContextPickerDelegate>>,
|
|
@ -1,7 +1,15 @@
|
||||||
use std::path::Path;
|
use crate::{
|
||||||
use std::rc::Rc;
|
AcceptSuggestedContext, AgentPanel, FocusDown, FocusLeft, FocusRight, FocusUp,
|
||||||
|
ModelUsageContext, RemoveAllContext, RemoveFocusedContext, ToggleContextPicker,
|
||||||
use assistant_context_editor::AssistantContext;
|
context_picker::ContextPicker,
|
||||||
|
ui::{AddedContext, ContextPill},
|
||||||
|
};
|
||||||
|
use agent::context_store::SuggestedContext;
|
||||||
|
use agent::{
|
||||||
|
context::AgentContextHandle,
|
||||||
|
context_store::ContextStore,
|
||||||
|
thread_store::{TextThreadStore, ThreadStore},
|
||||||
|
};
|
||||||
use collections::HashSet;
|
use collections::HashSet;
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
use file_icons::FileIcons;
|
use file_icons::FileIcons;
|
||||||
|
@ -10,22 +18,11 @@ use gpui::{
|
||||||
Subscription, WeakEntity,
|
Subscription, WeakEntity,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::Buffer;
|
|
||||||
use project::ProjectItem;
|
use project::ProjectItem;
|
||||||
|
use std::{path::Path, rc::Rc};
|
||||||
use ui::{PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*};
|
use ui::{PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*};
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
use crate::context::{AgentContextHandle, ContextKind};
|
|
||||||
use crate::context_picker::ContextPicker;
|
|
||||||
use crate::context_store::ContextStore;
|
|
||||||
use crate::thread::Thread;
|
|
||||||
use crate::thread_store::{TextThreadStore, ThreadStore};
|
|
||||||
use crate::ui::{AddedContext, ContextPill};
|
|
||||||
use crate::{
|
|
||||||
AcceptSuggestedContext, AgentPanel, FocusDown, FocusLeft, FocusRight, FocusUp,
|
|
||||||
ModelUsageContext, RemoveAllContext, RemoveFocusedContext, ToggleContextPicker,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct ContextStrip {
|
pub struct ContextStrip {
|
||||||
context_store: Entity<ContextStore>,
|
context_store: Entity<ContextStore>,
|
||||||
context_picker: Entity<ContextPicker>,
|
context_picker: Entity<ContextPicker>,
|
||||||
|
@ -575,46 +572,3 @@ pub enum SuggestContextKind {
|
||||||
File,
|
File,
|
||||||
Thread,
|
Thread,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum SuggestedContext {
|
|
||||||
File {
|
|
||||||
name: SharedString,
|
|
||||||
icon_path: Option<SharedString>,
|
|
||||||
buffer: WeakEntity<Buffer>,
|
|
||||||
},
|
|
||||||
Thread {
|
|
||||||
name: SharedString,
|
|
||||||
thread: WeakEntity<Thread>,
|
|
||||||
},
|
|
||||||
TextThread {
|
|
||||||
name: SharedString,
|
|
||||||
context: WeakEntity<AssistantContext>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SuggestedContext {
|
|
||||||
pub fn name(&self) -> &SharedString {
|
|
||||||
match self {
|
|
||||||
Self::File { name, .. } => name,
|
|
||||||
Self::Thread { name, .. } => name,
|
|
||||||
Self::TextThread { name, .. } => name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn icon_path(&self) -> Option<SharedString> {
|
|
||||||
match self {
|
|
||||||
Self::File { icon_path, .. } => icon_path.clone(),
|
|
||||||
Self::Thread { .. } => None,
|
|
||||||
Self::TextThread { .. } => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kind(&self) -> ContextKind {
|
|
||||||
match self {
|
|
||||||
Self::File { .. } => ContextKind::File,
|
|
||||||
Self::Thread { .. } => ContextKind::Thread,
|
|
||||||
Self::TextThread { .. } => ContextKind::TextThread,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,18 +4,27 @@ use std::ops::Range;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
AgentPanel,
|
||||||
|
buffer_codegen::{BufferCodegen, CodegenAlternative, CodegenEvent},
|
||||||
|
inline_prompt_editor::{CodegenStatus, InlineAssistId, PromptEditor, PromptEditorEvent},
|
||||||
|
terminal_inline_assistant::TerminalInlineAssistant,
|
||||||
|
};
|
||||||
|
use agent::{
|
||||||
|
context_store::ContextStore,
|
||||||
|
thread_store::{TextThreadStore, ThreadStore},
|
||||||
|
};
|
||||||
use agent_settings::AgentSettings;
|
use agent_settings::AgentSettings;
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
use client::telemetry::Telemetry;
|
use client::telemetry::Telemetry;
|
||||||
use collections::{HashMap, HashSet, VecDeque, hash_map};
|
use collections::{HashMap, HashSet, VecDeque, hash_map};
|
||||||
use editor::display_map::EditorMargins;
|
|
||||||
use editor::{
|
use editor::{
|
||||||
Anchor, AnchorRangeExt, CodeActionProvider, Editor, EditorEvent, ExcerptId, ExcerptRange,
|
Anchor, AnchorRangeExt, CodeActionProvider, Editor, EditorEvent, ExcerptId, ExcerptRange,
|
||||||
MultiBuffer, MultiBufferSnapshot, ToOffset as _, ToPoint,
|
MultiBuffer, MultiBufferSnapshot, ToOffset as _, ToPoint,
|
||||||
actions::SelectAll,
|
actions::SelectAll,
|
||||||
display_map::{
|
display_map::{
|
||||||
BlockContext, BlockPlacement, BlockProperties, BlockStyle, CustomBlockId, RenderBlock,
|
BlockContext, BlockPlacement, BlockProperties, BlockStyle, CustomBlockId, EditorMargins,
|
||||||
ToDisplayPoint,
|
RenderBlock, ToDisplayPoint,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
|
@ -24,16 +33,13 @@ use gpui::{
|
||||||
WeakEntity, Window, point,
|
WeakEntity, Window, point,
|
||||||
};
|
};
|
||||||
use language::{Buffer, Point, Selection, TransactionId};
|
use language::{Buffer, Point, Selection, TransactionId};
|
||||||
use language_model::ConfigurationError;
|
use language_model::{
|
||||||
use language_model::ConfiguredModel;
|
ConfigurationError, ConfiguredModel, LanguageModelRegistry, report_assistant_event,
|
||||||
use language_model::{LanguageModelRegistry, report_assistant_event};
|
};
|
||||||
use multi_buffer::MultiBufferRow;
|
use multi_buffer::MultiBufferRow;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use project::LspAction;
|
use project::{CodeAction, LspAction, Project, ProjectTransaction};
|
||||||
use project::Project;
|
use prompt_store::{PromptBuilder, PromptStore};
|
||||||
use project::{CodeAction, ProjectTransaction};
|
|
||||||
use prompt_store::PromptBuilder;
|
|
||||||
use prompt_store::PromptStore;
|
|
||||||
use settings::{Settings, SettingsStore};
|
use settings::{Settings, SettingsStore};
|
||||||
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
|
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
|
||||||
use terminal_view::{TerminalView, terminal_panel::TerminalPanel};
|
use terminal_view::{TerminalView, terminal_panel::TerminalPanel};
|
||||||
|
@ -43,14 +49,6 @@ use util::{RangeExt, ResultExt, maybe};
|
||||||
use workspace::{ItemHandle, Toast, Workspace, dock::Panel, notifications::NotificationId};
|
use workspace::{ItemHandle, Toast, Workspace, dock::Panel, notifications::NotificationId};
|
||||||
use zed_actions::agent::OpenConfiguration;
|
use zed_actions::agent::OpenConfiguration;
|
||||||
|
|
||||||
use crate::AgentPanel;
|
|
||||||
use crate::buffer_codegen::{BufferCodegen, CodegenAlternative, CodegenEvent};
|
|
||||||
use crate::context_store::ContextStore;
|
|
||||||
use crate::inline_prompt_editor::{CodegenStatus, InlineAssistId, PromptEditor, PromptEditorEvent};
|
|
||||||
use crate::terminal_inline_assistant::TerminalInlineAssistant;
|
|
||||||
use crate::thread_store::TextThreadStore;
|
|
||||||
use crate::thread_store::ThreadStore;
|
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
prompt_builder: Arc<PromptBuilder>,
|
prompt_builder: Arc<PromptBuilder>,
|
|
@ -1,14 +1,15 @@
|
||||||
use crate::agent_model_selector::AgentModelSelector;
|
use crate::agent_model_selector::AgentModelSelector;
|
||||||
use crate::buffer_codegen::BufferCodegen;
|
use crate::buffer_codegen::BufferCodegen;
|
||||||
use crate::context::ContextCreasesAddon;
|
|
||||||
use crate::context_picker::{ContextPicker, ContextPickerCompletionProvider};
|
use crate::context_picker::{ContextPicker, ContextPickerCompletionProvider};
|
||||||
use crate::context_store::ContextStore;
|
|
||||||
use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind};
|
use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind};
|
||||||
use crate::message_editor::{extract_message_creases, insert_message_creases};
|
use crate::message_editor::{ContextCreasesAddon, extract_message_creases, insert_message_creases};
|
||||||
use crate::terminal_codegen::TerminalCodegen;
|
use crate::terminal_codegen::TerminalCodegen;
|
||||||
use crate::thread_store::{TextThreadStore, ThreadStore};
|
|
||||||
use crate::{CycleNextInlineAssist, CyclePreviousInlineAssist, ModelUsageContext};
|
use crate::{CycleNextInlineAssist, CyclePreviousInlineAssist, ModelUsageContext};
|
||||||
use crate::{RemoveAllContext, ToggleContextPicker};
|
use crate::{RemoveAllContext, ToggleContextPicker};
|
||||||
|
use agent::{
|
||||||
|
context_store::ContextStore,
|
||||||
|
thread_store::{TextThreadStore, ThreadStore},
|
||||||
|
};
|
||||||
use assistant_context_editor::language_model_selector::ToggleModelSelector;
|
use assistant_context_editor::language_model_selector::ToggleModelSelector;
|
||||||
use client::ErrorExt;
|
use client::ErrorExt;
|
||||||
use collections::VecDeque;
|
use collections::VecDeque;
|
|
@ -3,21 +3,25 @@ use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::agent_model_selector::AgentModelSelector;
|
use crate::agent_model_selector::AgentModelSelector;
|
||||||
use crate::context::{AgentContextKey, ContextCreasesAddon, ContextLoadResult, load_context};
|
|
||||||
use crate::tool_compatibility::{IncompatibleToolsState, IncompatibleToolsTooltip};
|
use crate::tool_compatibility::{IncompatibleToolsState, IncompatibleToolsTooltip};
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
MaxModeTooltip,
|
MaxModeTooltip,
|
||||||
preview::{AgentPreview, UsageCallout},
|
preview::{AgentPreview, UsageCallout},
|
||||||
};
|
};
|
||||||
|
use agent::{
|
||||||
|
context::{AgentContextKey, ContextLoadResult, load_context},
|
||||||
|
context_store::ContextStoreEvent,
|
||||||
|
};
|
||||||
use agent_settings::{AgentSettings, CompletionMode};
|
use agent_settings::{AgentSettings, CompletionMode};
|
||||||
use assistant_context_editor::language_model_selector::ToggleModelSelector;
|
use assistant_context_editor::language_model_selector::ToggleModelSelector;
|
||||||
use buffer_diff::BufferDiff;
|
use buffer_diff::BufferDiff;
|
||||||
use client::UserStore;
|
use client::UserStore;
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
use editor::actions::{MoveUp, Paste};
|
use editor::actions::{MoveUp, Paste};
|
||||||
|
use editor::display_map::CreaseId;
|
||||||
use editor::{
|
use editor::{
|
||||||
AnchorRangeExt, ContextMenuOptions, ContextMenuPlacement, Editor, EditorElement, EditorEvent,
|
Addon, AnchorRangeExt, ContextMenuOptions, ContextMenuPlacement, Editor, EditorElement,
|
||||||
EditorMode, EditorStyle, MultiBuffer,
|
EditorEvent, EditorMode, EditorStyle, MultiBuffer,
|
||||||
};
|
};
|
||||||
use file_icons::FileIcons;
|
use file_icons::FileIcons;
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
|
@ -46,16 +50,18 @@ use workspace::{CollaboratorId, Workspace};
|
||||||
use zed_llm_client::CompletionIntent;
|
use zed_llm_client::CompletionIntent;
|
||||||
|
|
||||||
use crate::context_picker::{ContextPicker, ContextPickerCompletionProvider, crease_for_mention};
|
use crate::context_picker::{ContextPicker, ContextPickerCompletionProvider, crease_for_mention};
|
||||||
use crate::context_store::ContextStore;
|
|
||||||
use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind};
|
use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind};
|
||||||
use crate::profile_selector::ProfileSelector;
|
use crate::profile_selector::ProfileSelector;
|
||||||
use crate::thread::{MessageCrease, Thread, TokenUsageRatio};
|
|
||||||
use crate::thread_store::{TextThreadStore, ThreadStore};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ActiveThread, AgentDiffPane, Chat, ChatWithFollow, ExpandMessageEditor, Follow, KeepAll,
|
ActiveThread, AgentDiffPane, Chat, ChatWithFollow, ExpandMessageEditor, Follow, KeepAll,
|
||||||
ModelUsageContext, NewThread, OpenAgentDiff, RejectAll, RemoveAllContext, ToggleBurnMode,
|
ModelUsageContext, NewThread, OpenAgentDiff, RejectAll, RemoveAllContext, ToggleBurnMode,
|
||||||
ToggleContextPicker, ToggleProfileSelector, register_agent_preview,
|
ToggleContextPicker, ToggleProfileSelector, register_agent_preview,
|
||||||
};
|
};
|
||||||
|
use agent::{
|
||||||
|
MessageCrease, Thread, TokenUsageRatio,
|
||||||
|
context_store::ContextStore,
|
||||||
|
thread_store::{TextThreadStore, ThreadStore},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(RegisterComponent)]
|
#[derive(RegisterComponent)]
|
||||||
pub struct MessageEditor {
|
pub struct MessageEditor {
|
||||||
|
@ -1466,6 +1472,69 @@ impl MessageEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ContextCreasesAddon {
|
||||||
|
creases: HashMap<AgentContextKey, Vec<(CreaseId, SharedString)>>,
|
||||||
|
_subscription: Option<Subscription>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Addon for ContextCreasesAddon {
|
||||||
|
fn to_any(&self) -> &dyn std::any::Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_any_mut(&mut self) -> Option<&mut dyn std::any::Any> {
|
||||||
|
Some(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ContextCreasesAddon {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
creases: HashMap::default(),
|
||||||
|
_subscription: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_creases(
|
||||||
|
&mut self,
|
||||||
|
context_store: &Entity<ContextStore>,
|
||||||
|
key: AgentContextKey,
|
||||||
|
creases: impl IntoIterator<Item = (CreaseId, SharedString)>,
|
||||||
|
cx: &mut Context<Editor>,
|
||||||
|
) {
|
||||||
|
self.creases.entry(key).or_default().extend(creases);
|
||||||
|
self._subscription = Some(cx.subscribe(
|
||||||
|
&context_store,
|
||||||
|
|editor, _, event, cx| match event {
|
||||||
|
ContextStoreEvent::ContextRemoved(key) => {
|
||||||
|
let Some(this) = editor.addon_mut::<Self>() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let (crease_ids, replacement_texts): (Vec<_>, Vec<_>) = this
|
||||||
|
.creases
|
||||||
|
.remove(key)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.into_iter()
|
||||||
|
.unzip();
|
||||||
|
let ranges = editor
|
||||||
|
.remove_creases(crease_ids, cx)
|
||||||
|
.into_iter()
|
||||||
|
.map(|(_, range)| range)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
editor.unfold_ranges(&ranges, false, false, cx);
|
||||||
|
editor.edit(ranges.into_iter().zip(replacement_texts), cx);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_inner(self) -> HashMap<AgentContextKey, Vec<(CreaseId, SharedString)>> {
|
||||||
|
self.creases
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn extract_message_creases(
|
pub fn extract_message_creases(
|
||||||
editor: &mut Editor,
|
editor: &mut Editor,
|
||||||
cx: &mut Context<'_, Editor>,
|
cx: &mut Context<'_, Editor>,
|
||||||
|
@ -1504,8 +1573,9 @@ pub fn extract_message_creases(
|
||||||
let context = contexts_by_crease_id.remove(&id);
|
let context = contexts_by_crease_id.remove(&id);
|
||||||
MessageCrease {
|
MessageCrease {
|
||||||
range,
|
range,
|
||||||
metadata,
|
|
||||||
context,
|
context,
|
||||||
|
label: metadata.label,
|
||||||
|
icon_path: metadata.icon_path,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -1577,8 +1647,8 @@ pub fn insert_message_creases(
|
||||||
let start = buffer_snapshot.anchor_after(crease.range.start);
|
let start = buffer_snapshot.anchor_after(crease.range.start);
|
||||||
let end = buffer_snapshot.anchor_before(crease.range.end);
|
let end = buffer_snapshot.anchor_before(crease.range.end);
|
||||||
crease_for_mention(
|
crease_for_mention(
|
||||||
crease.metadata.label.clone(),
|
crease.label.clone(),
|
||||||
crease.metadata.icon_path.clone(),
|
crease.icon_path.clone(),
|
||||||
start..end,
|
start..end,
|
||||||
cx.weak_entity(),
|
cx.weak_entity(),
|
||||||
)
|
)
|
||||||
|
@ -1590,12 +1660,7 @@ pub fn insert_message_creases(
|
||||||
for (crease, id) in message_creases.iter().zip(ids) {
|
for (crease, id) in message_creases.iter().zip(ids) {
|
||||||
if let Some(context) = crease.context.as_ref() {
|
if let Some(context) = crease.context.as_ref() {
|
||||||
let key = AgentContextKey(context.clone());
|
let key = AgentContextKey(context.clone());
|
||||||
addon.add_creases(
|
addon.add_creases(context_store, key, vec![(id, crease.label.clone())], cx);
|
||||||
context_store,
|
|
||||||
key,
|
|
||||||
vec![(id, crease.metadata.label.clone())],
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,20 +1,19 @@
|
||||||
use std::sync::Arc;
|
use crate::{ManageProfiles, ToggleProfileSelector};
|
||||||
|
use agent::{
|
||||||
|
Thread,
|
||||||
|
agent_profile::{AgentProfile, AvailableProfiles},
|
||||||
|
};
|
||||||
use agent_settings::{AgentDockPosition, AgentProfileId, AgentSettings, builtin_profiles};
|
use agent_settings::{AgentDockPosition, AgentProfileId, AgentSettings, builtin_profiles};
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use gpui::{Action, Empty, Entity, FocusHandle, Subscription, prelude::*};
|
use gpui::{Action, Empty, Entity, FocusHandle, Subscription, prelude::*};
|
||||||
use language_model::LanguageModelRegistry;
|
use language_model::LanguageModelRegistry;
|
||||||
use settings::{Settings as _, SettingsStore, update_settings_file};
|
use settings::{Settings as _, SettingsStore, update_settings_file};
|
||||||
|
use std::sync::Arc;
|
||||||
use ui::{
|
use ui::{
|
||||||
ContextMenu, ContextMenuEntry, DocumentationSide, PopoverMenu, PopoverMenuHandle, Tooltip,
|
ContextMenu, ContextMenuEntry, DocumentationSide, PopoverMenu, PopoverMenuHandle, Tooltip,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
|
||||||
ManageProfiles, Thread, ToggleProfileSelector,
|
|
||||||
agent_profile::{AgentProfile, AvailableProfiles},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct ProfileSelector {
|
pub struct ProfileSelector {
|
||||||
profiles: AvailableProfiles,
|
profiles: AvailableProfiles,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
|
@ -1,10 +1,12 @@
|
||||||
use crate::context::load_context;
|
|
||||||
use crate::context_store::ContextStore;
|
|
||||||
use crate::inline_prompt_editor::{
|
use crate::inline_prompt_editor::{
|
||||||
CodegenStatus, PromptEditor, PromptEditorEvent, TerminalInlineAssistId,
|
CodegenStatus, PromptEditor, PromptEditorEvent, TerminalInlineAssistId,
|
||||||
};
|
};
|
||||||
use crate::terminal_codegen::{CLEAR_INPUT, CodegenEvent, TerminalCodegen};
|
use crate::terminal_codegen::{CLEAR_INPUT, CodegenEvent, TerminalCodegen};
|
||||||
use crate::thread_store::{TextThreadStore, ThreadStore};
|
use agent::{
|
||||||
|
context::load_context,
|
||||||
|
context_store::ContextStore,
|
||||||
|
thread_store::{TextThreadStore, ThreadStore},
|
||||||
|
};
|
||||||
use agent_settings::AgentSettings;
|
use agent_settings::AgentSettings;
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
use client::telemetry::Telemetry;
|
use client::telemetry::Telemetry;
|
|
@ -1,7 +1,5 @@
|
||||||
use std::fmt::Display;
|
use crate::{AgentPanel, RemoveSelectedThread};
|
||||||
use std::ops::Range;
|
use agent::history_store::{HistoryEntry, HistoryStore};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use chrono::{Datelike as _, Local, NaiveDate, TimeDelta};
|
use chrono::{Datelike as _, Local, NaiveDate, TimeDelta};
|
||||||
use editor::{Editor, EditorEvent};
|
use editor::{Editor, EditorEvent};
|
||||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||||
|
@ -9,6 +7,7 @@ use gpui::{
|
||||||
App, ClickEvent, Empty, Entity, FocusHandle, Focusable, ScrollStrategy, Stateful, Task,
|
App, ClickEvent, Empty, Entity, FocusHandle, Focusable, ScrollStrategy, Stateful, Task,
|
||||||
UniformListScrollHandle, WeakEntity, Window, uniform_list,
|
UniformListScrollHandle, WeakEntity, Window, uniform_list,
|
||||||
};
|
};
|
||||||
|
use std::{fmt::Display, ops::Range, sync::Arc};
|
||||||
use time::{OffsetDateTime, UtcOffset};
|
use time::{OffsetDateTime, UtcOffset};
|
||||||
use ui::{
|
use ui::{
|
||||||
HighlightedLabel, IconButtonShape, ListItem, ListItemSpacing, Scrollbar, ScrollbarState,
|
HighlightedLabel, IconButtonShape, ListItem, ListItemSpacing, Scrollbar, ScrollbarState,
|
||||||
|
@ -16,9 +15,6 @@ use ui::{
|
||||||
};
|
};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
use crate::history_store::{HistoryEntry, HistoryStore};
|
|
||||||
use crate::{AgentPanel, RemoveSelectedThread};
|
|
||||||
|
|
||||||
pub struct ThreadHistory {
|
pub struct ThreadHistory {
|
||||||
agent_panel: WeakEntity<AgentPanel>,
|
agent_panel: WeakEntity<AgentPanel>,
|
||||||
history_store: Entity<HistoryStore>,
|
history_store: Entity<HistoryStore>,
|
|
@ -1,13 +1,11 @@
|
||||||
use std::sync::Arc;
|
use agent::{Thread, ThreadEvent};
|
||||||
|
|
||||||
use assistant_tool::{Tool, ToolSource};
|
use assistant_tool::{Tool, ToolSource};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use gpui::{App, Context, Entity, IntoElement, Render, Subscription, Window};
|
use gpui::{App, Context, Entity, IntoElement, Render, Subscription, Window};
|
||||||
use language_model::{LanguageModel, LanguageModelToolSchemaFormat};
|
use language_model::{LanguageModel, LanguageModelToolSchemaFormat};
|
||||||
|
use std::sync::Arc;
|
||||||
use ui::prelude::*;
|
use ui::prelude::*;
|
||||||
|
|
||||||
use crate::{Thread, ThreadEvent};
|
|
||||||
|
|
||||||
pub struct IncompatibleToolsState {
|
pub struct IncompatibleToolsState {
|
||||||
cache: HashMap<LanguageModelToolSchemaFormat, Vec<Arc<dyn Tool>>>,
|
cache: HashMap<LanguageModelToolSchemaFormat, Vec<Arc<dyn Tool>>>,
|
||||||
thread: Entity<Thread>,
|
thread: Entity<Thread>,
|
|
@ -12,7 +12,7 @@ use prompt_store::PromptStore;
|
||||||
use rope::Point;
|
use rope::Point;
|
||||||
use ui::{IconButtonShape, Tooltip, prelude::*, tooltip_container};
|
use ui::{IconButtonShape, Tooltip, prelude::*, tooltip_container};
|
||||||
|
|
||||||
use crate::context::{
|
use agent::context::{
|
||||||
AgentContext, AgentContextHandle, ContextId, ContextKind, DirectoryContext,
|
AgentContext, AgentContextHandle, ContextId, ContextKind, DirectoryContext,
|
||||||
DirectoryContextHandle, FetchedUrlContext, FileContext, FileContextHandle, ImageContext,
|
DirectoryContextHandle, FetchedUrlContext, FileContext, FileContextHandle, ImageContext,
|
||||||
ImageStatus, RulesContext, RulesContextHandle, SelectionContext, SelectionContextHandle,
|
ImageStatus, RulesContext, RulesContextHandle, SelectionContext, SelectionContextHandle,
|
|
@ -19,6 +19,7 @@ path = "src/explorer.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
agent.workspace = true
|
agent.workspace = true
|
||||||
|
agent_ui.workspace = true
|
||||||
agent_settings.workspace = true
|
agent_settings.workspace = true
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
assistant_tool.workspace = true
|
assistant_tool.workspace = true
|
||||||
|
|
|
@ -423,7 +423,7 @@ pub fn init(cx: &mut App) -> Arc<AgentAppState> {
|
||||||
terminal_view::init(cx);
|
terminal_view::init(cx);
|
||||||
let stdout_is_a_pty = false;
|
let stdout_is_a_pty = false;
|
||||||
let prompt_builder = PromptBuilder::load(fs.clone(), stdout_is_a_pty, cx);
|
let prompt_builder = PromptBuilder::load(fs.clone(), stdout_is_a_pty, cx);
|
||||||
agent::init(
|
agent_ui::init(
|
||||||
fs.clone(),
|
fs.clone(),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
prompt_builder.clone(),
|
prompt_builder.clone(),
|
||||||
|
|
|
@ -100,7 +100,7 @@ impl ExampleContext {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
meta: ExampleMetadata,
|
meta: ExampleMetadata,
|
||||||
log_prefix: String,
|
log_prefix: String,
|
||||||
agent_thread: Entity<agent::Thread>,
|
agent_thread: Entity<Thread>,
|
||||||
model: Arc<dyn LanguageModel>,
|
model: Arc<dyn LanguageModel>,
|
||||||
app: AsyncApp,
|
app: AsyncApp,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
|
@ -21,6 +21,7 @@ path = "src/main.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
activity_indicator.workspace = true
|
activity_indicator.workspace = true
|
||||||
agent.workspace = true
|
agent.workspace = true
|
||||||
|
agent_ui.workspace = true
|
||||||
agent_settings.workspace = true
|
agent_settings.workspace = true
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
askpass.workspace = true
|
askpass.workspace = true
|
||||||
|
|
|
@ -531,7 +531,7 @@ pub fn main() {
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
let prompt_builder = PromptBuilder::load(app_state.fs.clone(), stdout_is_a_pty(), cx);
|
let prompt_builder = PromptBuilder::load(app_state.fs.clone(), stdout_is_a_pty(), cx);
|
||||||
agent::init(
|
agent_ui::init(
|
||||||
app_state.fs.clone(),
|
app_state.fs.clone(),
|
||||||
app_state.client.clone(),
|
app_state.client.clone(),
|
||||||
prompt_builder.clone(),
|
prompt_builder.clone(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ mod quick_action_bar;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub(crate) mod windows_only_instance;
|
pub(crate) mod windows_only_instance;
|
||||||
|
|
||||||
use agent::AgentDiffToolbar;
|
use agent_ui::AgentDiffToolbar;
|
||||||
use anyhow::Context as _;
|
use anyhow::Context as _;
|
||||||
pub use app_menus::*;
|
pub use app_menus::*;
|
||||||
use assets::Assets;
|
use assets::Assets;
|
||||||
|
@ -515,7 +515,7 @@ fn initialize_panels(
|
||||||
let is_assistant2_enabled = !cfg!(test);
|
let is_assistant2_enabled = !cfg!(test);
|
||||||
let agent_panel = if is_assistant2_enabled {
|
let agent_panel = if is_assistant2_enabled {
|
||||||
let agent_panel =
|
let agent_panel =
|
||||||
agent::AgentPanel::load(workspace_handle.clone(), prompt_builder, cx.clone())
|
agent_ui::AgentPanel::load(workspace_handle.clone(), prompt_builder, cx.clone())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Some(agent_panel)
|
Some(agent_panel)
|
||||||
|
@ -536,13 +536,13 @@ fn initialize_panels(
|
||||||
// Once we ship `assistant2` we can push this back down into `agent::agent_panel::init`.
|
// Once we ship `assistant2` we can push this back down into `agent::agent_panel::init`.
|
||||||
if is_assistant2_enabled {
|
if is_assistant2_enabled {
|
||||||
<dyn AgentPanelDelegate>::set_global(
|
<dyn AgentPanelDelegate>::set_global(
|
||||||
Arc::new(agent::ConcreteAssistantPanelDelegate),
|
Arc::new(agent_ui::ConcreteAssistantPanelDelegate),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
||||||
workspace
|
workspace
|
||||||
.register_action(agent::AgentPanel::toggle_focus)
|
.register_action(agent_ui::AgentPanel::toggle_focus)
|
||||||
.register_action(agent::InlineAssistant::inline_assist);
|
.register_action(agent_ui::InlineAssistant::inline_assist);
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -4320,7 +4320,7 @@ mod tests {
|
||||||
web_search::init(cx);
|
web_search::init(cx);
|
||||||
web_search_providers::init(app_state.client.clone(), cx);
|
web_search_providers::init(app_state.client.clone(), cx);
|
||||||
let prompt_builder = PromptBuilder::load(app_state.fs.clone(), false, cx);
|
let prompt_builder = PromptBuilder::load(app_state.fs.clone(), false, cx);
|
||||||
agent::init(
|
agent_ui::init(
|
||||||
app_state.fs.clone(),
|
app_state.fs.clone(),
|
||||||
app_state.client.clone(),
|
app_state.client.clone(),
|
||||||
prompt_builder.clone(),
|
prompt_builder.clone(),
|
||||||
|
|
|
@ -5,20 +5,14 @@
|
||||||
mod persistence;
|
mod persistence;
|
||||||
mod preview_support;
|
mod preview_support;
|
||||||
|
|
||||||
use std::ops::Range;
|
use agent::{TextThreadStore, ThreadStore};
|
||||||
use std::sync::Arc;
|
use agent_ui::ActiveThread;
|
||||||
|
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
use agent::{ActiveThread, TextThreadStore, ThreadStore};
|
|
||||||
use client::UserStore;
|
use client::UserStore;
|
||||||
|
use collections::HashMap;
|
||||||
use component::{ComponentId, ComponentMetadata, ComponentStatus, components};
|
use component::{ComponentId, ComponentMetadata, ComponentStatus, components};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, Entity, EventEmitter, FocusHandle, Focusable, Task, WeakEntity, Window, list, prelude::*,
|
App, Entity, EventEmitter, FocusHandle, Focusable, Task, WeakEntity, Window, list, prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use collections::HashMap;
|
|
||||||
|
|
||||||
use gpui::{ListState, ScrollHandle, ScrollStrategy, UniformListScrollHandle};
|
use gpui::{ListState, ScrollHandle, ScrollStrategy, UniformListScrollHandle};
|
||||||
use languages::LanguageRegistry;
|
use languages::LanguageRegistry;
|
||||||
use notifications::status_toast::{StatusToast, ToastIcon};
|
use notifications::status_toast::{StatusToast, ToastIcon};
|
||||||
|
@ -27,11 +21,14 @@ use preview_support::active_thread::{
|
||||||
load_preview_text_thread_store, load_preview_thread_store, static_active_thread,
|
load_preview_text_thread_store, load_preview_thread_store, static_active_thread,
|
||||||
};
|
};
|
||||||
use project::Project;
|
use project::Project;
|
||||||
|
use std::{iter::Iterator, ops::Range, sync::Arc};
|
||||||
use ui::{ButtonLike, Divider, HighlightedLabel, ListItem, ListSubHeader, Tooltip, prelude::*};
|
use ui::{ButtonLike, Divider, HighlightedLabel, ListItem, ListSubHeader, Tooltip, prelude::*};
|
||||||
use ui_input::SingleLineInput;
|
use ui_input::SingleLineInput;
|
||||||
use util::ResultExt as _;
|
use util::ResultExt as _;
|
||||||
use workspace::{AppState, ItemId, SerializableItem, delete_unloaded_items};
|
use workspace::{
|
||||||
use workspace::{Item, Workspace, WorkspaceId, item::ItemEvent};
|
AppState, Item, ItemId, SerializableItem, Workspace, WorkspaceId, delete_unloaded_items,
|
||||||
|
item::ItemEvent,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn init(app_state: Arc<AppState>, cx: &mut App) {
|
pub fn init(app_state: Arc<AppState>, cx: &mut App) {
|
||||||
workspace::register_serializable_item::<ComponentPreview>(cx);
|
workspace::register_serializable_item::<ComponentPreview>(cx);
|
||||||
|
@ -642,7 +639,7 @@ impl ComponentPreview {
|
||||||
// Check if the component's scope is Agent
|
// Check if the component's scope is Agent
|
||||||
if scope == ComponentScope::Agent {
|
if scope == ComponentScope::Agent {
|
||||||
if let Some(active_thread) = self.active_thread.clone() {
|
if let Some(active_thread) = self.active_thread.clone() {
|
||||||
if let Some(element) = agent::get_agent_preview(
|
if let Some(element) = agent_ui::get_agent_preview(
|
||||||
&component.id(),
|
&component.id(),
|
||||||
self.workspace.clone(),
|
self.workspace.clone(),
|
||||||
active_thread,
|
active_thread,
|
||||||
|
@ -1140,7 +1137,7 @@ impl ComponentPreviewPage {
|
||||||
fn render_preview(&self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
fn render_preview(&self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||||
// Try to get agent preview first if we have an active thread
|
// Try to get agent preview first if we have an active thread
|
||||||
let maybe_agent_preview = if let Some(active_thread) = self.active_thread.as_ref() {
|
let maybe_agent_preview = if let Some(active_thread) = self.active_thread.as_ref() {
|
||||||
agent::get_agent_preview(
|
agent_ui::get_agent_preview(
|
||||||
&self.component.id(),
|
&self.component.id(),
|
||||||
self.workspace.clone(),
|
self.workspace.clone(),
|
||||||
active_thread.clone(),
|
active_thread.clone(),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use agent::{ActiveThread, ContextStore, MessageSegment, TextThreadStore, ThreadStore};
|
use agent::{ContextStore, MessageSegment, TextThreadStore, ThreadStore};
|
||||||
|
use agent_ui::ActiveThread;
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use assistant_tool::ToolWorkingSet;
|
use assistant_tool::ToolWorkingSet;
|
||||||
use gpui::{AppContext, AsyncApp, Entity, Task, WeakEntity};
|
use gpui::{AppContext, AsyncApp, Entity, Task, WeakEntity};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue