assistant: Unship tool use (#23969)
This PR unships tool use from Assistant1. This was only ever partially implemented, and was never released to end users. Assistant2 will support tool use. Release Notes: - N/A
This commit is contained in:
parent
d2828e8722
commit
4ab372d6b5
10 changed files with 13 additions and 409 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -506,14 +506,12 @@ dependencies = [
|
|||
"assistant_settings",
|
||||
"assistant_slash_command",
|
||||
"assistant_slash_commands",
|
||||
"assistant_tool",
|
||||
"chrono",
|
||||
"client",
|
||||
"clock",
|
||||
"collections",
|
||||
"context_server",
|
||||
"editor",
|
||||
"feature_flags",
|
||||
"fs",
|
||||
"futures 0.3.31",
|
||||
"fuzzy",
|
||||
|
|
|
@ -11,7 +11,6 @@ use assistant_context_editor::{
|
|||
};
|
||||
use assistant_settings::{AssistantDockPosition, AssistantSettings};
|
||||
use assistant_slash_command::SlashCommandWorkingSet;
|
||||
use assistant_tool::ToolWorkingSet;
|
||||
use client::{proto, Client, Status};
|
||||
use editor::{Editor, EditorEvent};
|
||||
use fs::Fs;
|
||||
|
@ -100,11 +99,10 @@ impl AssistantPanel {
|
|||
) -> Task<Result<Entity<Self>>> {
|
||||
cx.spawn(|mut cx| async move {
|
||||
let slash_commands = Arc::new(SlashCommandWorkingSet::default());
|
||||
let tools = Arc::new(ToolWorkingSet::default());
|
||||
let context_store = workspace
|
||||
.update(&mut cx, |workspace, cx| {
|
||||
let project = workspace.project().clone();
|
||||
ContextStore::new(project, prompt_builder.clone(), slash_commands, tools, cx)
|
||||
ContextStore::new(project, prompt_builder.clone(), slash_commands, cx)
|
||||
})?
|
||||
.await?;
|
||||
|
||||
|
|
|
@ -134,7 +134,6 @@ impl AssistantPanel {
|
|||
project,
|
||||
prompt_builder.clone(),
|
||||
slash_commands,
|
||||
tools.clone(),
|
||||
cx,
|
||||
)
|
||||
})?
|
||||
|
|
|
@ -16,14 +16,12 @@ anyhow.workspace = true
|
|||
assistant_settings.workspace = true
|
||||
assistant_slash_command.workspace = true
|
||||
assistant_slash_commands.workspace = true
|
||||
assistant_tool.workspace = true
|
||||
chrono.workspace = true
|
||||
client.workspace = true
|
||||
clock.workspace = true
|
||||
collections.workspace = true
|
||||
context_server.workspace = true
|
||||
editor.workspace = true
|
||||
feature_flags.workspace = true
|
||||
fs.workspace = true
|
||||
futures.workspace = true
|
||||
fuzzy.workspace = true
|
||||
|
|
|
@ -8,11 +8,9 @@ use assistant_slash_command::{
|
|||
SlashCommandResult, SlashCommandWorkingSet,
|
||||
};
|
||||
use assistant_slash_commands::FileCommandMetadata;
|
||||
use assistant_tool::ToolWorkingSet;
|
||||
use client::{self, proto, telemetry::Telemetry};
|
||||
use clock::ReplicaId;
|
||||
use collections::{HashMap, HashSet};
|
||||
use feature_flags::{FeatureFlagAppExt, ToolUseFeatureFlag};
|
||||
use fs::{Fs, RemoveOptions};
|
||||
use futures::{future::Shared, FutureExt, StreamExt};
|
||||
use gpui::{
|
||||
|
@ -23,7 +21,6 @@ use language::{AnchorRangeExt, Bias, Buffer, LanguageRegistry, OffsetRangeExt, P
|
|||
use language_model::{
|
||||
LanguageModel, LanguageModelCacheConfiguration, LanguageModelCompletionEvent,
|
||||
LanguageModelImage, LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage,
|
||||
LanguageModelRequestTool, LanguageModelToolResult, LanguageModelToolUse,
|
||||
LanguageModelToolUseId, MessageContent, Role, StopReason,
|
||||
};
|
||||
use language_models::{
|
||||
|
@ -438,11 +435,6 @@ pub enum ContextEvent {
|
|||
SlashCommandOutputSectionAdded {
|
||||
section: SlashCommandOutputSection<language::Anchor>,
|
||||
},
|
||||
UsePendingTools,
|
||||
ToolFinished {
|
||||
tool_use_id: LanguageModelToolUseId,
|
||||
output_range: Range<language::Anchor>,
|
||||
},
|
||||
Operation(ContextOperation),
|
||||
}
|
||||
|
||||
|
@ -528,21 +520,12 @@ pub enum Content {
|
|||
render_image: Arc<RenderImage>,
|
||||
image: Shared<Task<Option<LanguageModelImage>>>,
|
||||
},
|
||||
ToolUse {
|
||||
range: Range<language::Anchor>,
|
||||
tool_use: LanguageModelToolUse,
|
||||
},
|
||||
ToolResult {
|
||||
range: Range<language::Anchor>,
|
||||
tool_use_id: LanguageModelToolUseId,
|
||||
},
|
||||
}
|
||||
|
||||
impl Content {
|
||||
fn range(&self) -> Range<language::Anchor> {
|
||||
match self {
|
||||
Self::Image { anchor, .. } => *anchor..*anchor,
|
||||
Self::ToolUse { range, .. } | Self::ToolResult { range, .. } => range.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -599,9 +582,7 @@ pub struct AssistantContext {
|
|||
invoked_slash_commands: HashMap<InvokedSlashCommandId, InvokedSlashCommand>,
|
||||
edits_since_last_parse: language::Subscription,
|
||||
slash_commands: Arc<SlashCommandWorkingSet>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
slash_command_output_sections: Vec<SlashCommandOutputSection<language::Anchor>>,
|
||||
pending_tool_uses_by_id: HashMap<LanguageModelToolUseId, PendingToolUse>,
|
||||
message_anchors: Vec<MessageAnchor>,
|
||||
contents: Vec<Content>,
|
||||
messages_metadata: HashMap<MessageId, MessageMetadata>,
|
||||
|
@ -654,7 +635,6 @@ impl AssistantContext {
|
|||
telemetry: Option<Arc<Telemetry>>,
|
||||
prompt_builder: Arc<PromptBuilder>,
|
||||
slash_commands: Arc<SlashCommandWorkingSet>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
Self::new(
|
||||
|
@ -664,7 +644,6 @@ impl AssistantContext {
|
|||
language_registry,
|
||||
prompt_builder,
|
||||
slash_commands,
|
||||
tools,
|
||||
project,
|
||||
telemetry,
|
||||
cx,
|
||||
|
@ -679,7 +658,6 @@ impl AssistantContext {
|
|||
language_registry: Arc<LanguageRegistry>,
|
||||
prompt_builder: Arc<PromptBuilder>,
|
||||
slash_commands: Arc<SlashCommandWorkingSet>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
project: Option<Entity<Project>>,
|
||||
telemetry: Option<Arc<Telemetry>>,
|
||||
cx: &mut Context<Self>,
|
||||
|
@ -707,7 +685,6 @@ impl AssistantContext {
|
|||
messages_metadata: Default::default(),
|
||||
parsed_slash_commands: Vec::new(),
|
||||
invoked_slash_commands: HashMap::default(),
|
||||
pending_tool_uses_by_id: HashMap::default(),
|
||||
slash_command_output_sections: Vec::new(),
|
||||
edits_since_last_parse: edits_since_last_slash_command_parse,
|
||||
summary: None,
|
||||
|
@ -725,7 +702,6 @@ impl AssistantContext {
|
|||
project,
|
||||
language_registry,
|
||||
slash_commands,
|
||||
tools,
|
||||
patches: Vec::new(),
|
||||
xml_tags: Vec::new(),
|
||||
prompt_builder,
|
||||
|
@ -802,7 +778,6 @@ impl AssistantContext {
|
|||
language_registry: Arc<LanguageRegistry>,
|
||||
prompt_builder: Arc<PromptBuilder>,
|
||||
slash_commands: Arc<SlashCommandWorkingSet>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
project: Option<Entity<Project>>,
|
||||
telemetry: Option<Arc<Telemetry>>,
|
||||
cx: &mut Context<Self>,
|
||||
|
@ -815,7 +790,6 @@ impl AssistantContext {
|
|||
language_registry,
|
||||
prompt_builder,
|
||||
slash_commands,
|
||||
tools,
|
||||
project,
|
||||
telemetry,
|
||||
cx,
|
||||
|
@ -848,10 +822,6 @@ impl AssistantContext {
|
|||
&self.slash_commands
|
||||
}
|
||||
|
||||
pub fn tools(&self) -> &Arc<ToolWorkingSet> {
|
||||
&self.tools
|
||||
}
|
||||
|
||||
pub fn set_capability(&mut self, capability: language::Capability, cx: &mut Context<Self>) {
|
||||
self.buffer
|
||||
.update(cx, |buffer, cx| buffer.set_capability(capability, cx));
|
||||
|
@ -1177,14 +1147,6 @@ impl AssistantContext {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn pending_tool_uses(&self) -> Vec<&PendingToolUse> {
|
||||
self.pending_tool_uses_by_id.values().collect()
|
||||
}
|
||||
|
||||
pub fn get_tool_use_by_id(&self, id: &LanguageModelToolUseId) -> Option<&PendingToolUse> {
|
||||
self.pending_tool_uses_by_id.get(id)
|
||||
}
|
||||
|
||||
fn set_language(&mut self, cx: &mut Context<Self>) {
|
||||
let markdown = self.language_registry.language_for_name("Markdown");
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
|
@ -2206,68 +2168,6 @@ impl AssistantContext {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn insert_tool_output(
|
||||
&mut self,
|
||||
tool_use_id: LanguageModelToolUseId,
|
||||
output: Task<Result<String>>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let insert_output_task = cx.spawn(|this, mut cx| {
|
||||
let tool_use_id = tool_use_id.clone();
|
||||
async move {
|
||||
let output = output.await;
|
||||
this.update(&mut cx, |this, cx| match output {
|
||||
Ok(mut output) => {
|
||||
const NEWLINE: char = '\n';
|
||||
|
||||
if !output.ends_with(NEWLINE) {
|
||||
output.push(NEWLINE);
|
||||
}
|
||||
|
||||
let anchor_range = this.buffer.update(cx, |buffer, cx| {
|
||||
let insert_start = buffer.len().to_offset(buffer);
|
||||
let insert_end = insert_start;
|
||||
|
||||
let start = insert_start;
|
||||
let end = start + output.len() - NEWLINE.len_utf8();
|
||||
|
||||
buffer.edit([(insert_start..insert_end, output)], None, cx);
|
||||
|
||||
let output_range = buffer.anchor_after(start)..buffer.anchor_after(end);
|
||||
|
||||
output_range
|
||||
});
|
||||
|
||||
this.insert_content(
|
||||
Content::ToolResult {
|
||||
range: anchor_range.clone(),
|
||||
tool_use_id: tool_use_id.clone(),
|
||||
},
|
||||
cx,
|
||||
);
|
||||
|
||||
cx.emit(ContextEvent::ToolFinished {
|
||||
tool_use_id,
|
||||
output_range: anchor_range,
|
||||
});
|
||||
}
|
||||
Err(err) => {
|
||||
if let Some(tool_use) = this.pending_tool_uses_by_id.get_mut(&tool_use_id) {
|
||||
tool_use.status = PendingToolUseStatus::Error(err.to_string());
|
||||
}
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(tool_use) = self.pending_tool_uses_by_id.get_mut(&tool_use_id) {
|
||||
tool_use.status = PendingToolUseStatus::Running {
|
||||
_task: insert_output_task.shared(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn completion_provider_changed(&mut self, cx: &mut Context<Self>) {
|
||||
self.count_remaining_tokens(cx);
|
||||
}
|
||||
|
@ -2298,23 +2198,7 @@ impl AssistantContext {
|
|||
// Compute which messages to cache, including the last one.
|
||||
self.mark_cache_anchors(&model.cache_configuration(), false, cx);
|
||||
|
||||
let mut request = self.to_completion_request(request_type, cx);
|
||||
|
||||
// Don't attach tools for now; we'll be removing tool use from
|
||||
// Assistant1 shortly.
|
||||
#[allow(clippy::overly_complex_bool_expr)]
|
||||
if false && cx.has_flag::<ToolUseFeatureFlag>() {
|
||||
request.tools = self
|
||||
.tools
|
||||
.tools(cx)
|
||||
.into_iter()
|
||||
.map(|tool| LanguageModelRequestTool {
|
||||
name: tool.name(),
|
||||
description: tool.description(),
|
||||
input_schema: tool.input_schema(),
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
let request = self.to_completion_request(request_type, cx);
|
||||
|
||||
let assistant_message = self
|
||||
.insert_message_after(last_message_id, Role::Assistant, MessageStatus::Pending, cx)
|
||||
|
@ -2371,44 +2255,7 @@ impl AssistantContext {
|
|||
cx,
|
||||
);
|
||||
}
|
||||
LanguageModelCompletionEvent::ToolUse(tool_use) => {
|
||||
const NEWLINE: char = '\n';
|
||||
|
||||
let mut text = String::new();
|
||||
text.push(NEWLINE);
|
||||
text.push_str(
|
||||
&serde_json::to_string_pretty(&tool_use)
|
||||
.expect("failed to serialize tool use to JSON"),
|
||||
);
|
||||
text.push(NEWLINE);
|
||||
let text_len = text.len();
|
||||
|
||||
buffer.edit(
|
||||
[(
|
||||
message_old_end_offset..message_old_end_offset,
|
||||
text,
|
||||
)],
|
||||
None,
|
||||
cx,
|
||||
);
|
||||
|
||||
let start_ix = message_old_end_offset + NEWLINE.len_utf8();
|
||||
let end_ix =
|
||||
message_old_end_offset + text_len - NEWLINE.len_utf8();
|
||||
let source_range = buffer.anchor_after(start_ix)
|
||||
..buffer.anchor_after(end_ix);
|
||||
|
||||
this.pending_tool_uses_by_id.insert(
|
||||
tool_use.id.clone(),
|
||||
PendingToolUse {
|
||||
id: tool_use.id,
|
||||
name: tool_use.name,
|
||||
input: tool_use.input,
|
||||
status: PendingToolUseStatus::Idle,
|
||||
source_range,
|
||||
},
|
||||
);
|
||||
}
|
||||
LanguageModelCompletionEvent::ToolUse(_) => {}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2491,9 +2338,7 @@ impl AssistantContext {
|
|||
|
||||
if let Ok(stop_reason) = result {
|
||||
match stop_reason {
|
||||
StopReason::ToolUse => {
|
||||
cx.emit(ContextEvent::UsePendingTools);
|
||||
}
|
||||
StopReason::ToolUse => {}
|
||||
StopReason::EndTurn => {}
|
||||
StopReason::MaxTokens => {}
|
||||
}
|
||||
|
@ -2572,23 +2417,6 @@ impl AssistantContext {
|
|||
.push(language_model::MessageContent::Image(image));
|
||||
}
|
||||
}
|
||||
Content::ToolUse { tool_use, .. } => {
|
||||
request_message
|
||||
.content
|
||||
.push(language_model::MessageContent::ToolUse(tool_use.clone()));
|
||||
}
|
||||
Content::ToolResult { tool_use_id, .. } => {
|
||||
request_message.content.push(
|
||||
language_model::MessageContent::ToolResult(
|
||||
LanguageModelToolResult {
|
||||
tool_use_id: tool_use_id.to_string(),
|
||||
is_error: false,
|
||||
content: collect_text_content(buffer, range.clone())
|
||||
.unwrap_or_default(),
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
offset = range.end;
|
||||
|
|
|
@ -8,7 +8,6 @@ use assistant_slash_command::{
|
|||
SlashCommandOutputSection, SlashCommandRegistry, SlashCommandResult, SlashCommandWorkingSet,
|
||||
};
|
||||
use assistant_slash_commands::FileSlashCommand;
|
||||
use assistant_tool::ToolWorkingSet;
|
||||
use collections::{HashMap, HashSet};
|
||||
use fs::FakeFs;
|
||||
use futures::{
|
||||
|
@ -56,7 +55,6 @@ fn test_inserting_and_removing_messages(cx: &mut App) {
|
|||
None,
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
@ -197,7 +195,6 @@ fn test_message_splitting(cx: &mut App) {
|
|||
None,
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
@ -300,7 +297,6 @@ fn test_messages_for_offsets(cx: &mut App) {
|
|||
None,
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
@ -414,7 +410,6 @@ async fn test_slash_commands(cx: &mut TestAppContext) {
|
|||
None,
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
@ -704,7 +699,6 @@ async fn test_workflow_step_parsing(cx: &mut TestAppContext) {
|
|||
None,
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
@ -969,7 +963,6 @@ async fn test_workflow_step_parsing(cx: &mut TestAppContext) {
|
|||
registry.clone(),
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
None,
|
||||
None,
|
||||
cx,
|
||||
|
@ -1088,7 +1081,6 @@ async fn test_serialization(cx: &mut TestAppContext) {
|
|||
None,
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
@ -1132,7 +1124,6 @@ async fn test_serialization(cx: &mut TestAppContext) {
|
|||
registry.clone(),
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
None,
|
||||
None,
|
||||
cx,
|
||||
|
@ -1191,7 +1182,6 @@ async fn test_random_context_collaboration(cx: &mut TestAppContext, mut rng: Std
|
|||
registry.clone(),
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
None,
|
||||
None,
|
||||
cx,
|
||||
|
@ -1451,7 +1441,6 @@ fn test_mark_cache_anchors(cx: &mut App) {
|
|||
None,
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
|
|
@ -5,7 +5,6 @@ use assistant_slash_commands::{
|
|||
selections_creases, DefaultSlashCommand, DocsSlashCommand, DocsSlashCommandArgs,
|
||||
FileSlashCommand,
|
||||
};
|
||||
use assistant_tool::ToolWorkingSet;
|
||||
use client::{proto, zed_urls};
|
||||
use collections::{hash_map, BTreeSet, HashMap, HashSet};
|
||||
use editor::{
|
||||
|
@ -33,7 +32,7 @@ use indexed_docs::IndexedDocsStore;
|
|||
use language::{language_settings::SoftWrap, BufferSnapshot, LspAdapterDelegate, ToOffset};
|
||||
use language_model::{
|
||||
LanguageModelImage, LanguageModelProvider, LanguageModelProviderTosView, LanguageModelRegistry,
|
||||
LanguageModelToolUse, Role,
|
||||
Role,
|
||||
};
|
||||
use language_model_selector::{LanguageModelSelector, LanguageModelSelectorPopoverMenu};
|
||||
use multi_buffer::MultiBufferRow;
|
||||
|
@ -171,7 +170,6 @@ pub struct ContextEditor {
|
|||
context: Entity<AssistantContext>,
|
||||
fs: Arc<dyn Fs>,
|
||||
slash_commands: Arc<SlashCommandWorkingSet>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
project: Entity<Project>,
|
||||
lsp_adapter_delegate: Option<Arc<dyn LspAdapterDelegate>>,
|
||||
|
@ -182,7 +180,6 @@ pub struct ContextEditor {
|
|||
remote_id: Option<workspace::ViewId>,
|
||||
pending_slash_command_creases: HashMap<Range<language::Anchor>, CreaseId>,
|
||||
invoked_slash_command_creases: HashMap<InvokedSlashCommandId, CreaseId>,
|
||||
pending_tool_use_creases: HashMap<Range<language::Anchor>, CreaseId>,
|
||||
_subscriptions: Vec<Subscription>,
|
||||
patches: HashMap<Range<language::Anchor>, PatchViewState>,
|
||||
active_patch: Option<Range<language::Anchor>>,
|
||||
|
@ -244,11 +241,9 @@ impl ContextEditor {
|
|||
let sections = context.read(cx).slash_command_output_sections().to_vec();
|
||||
let patch_ranges = context.read(cx).patch_ranges().collect::<Vec<_>>();
|
||||
let slash_commands = context.read(cx).slash_commands().clone();
|
||||
let tools = context.read(cx).tools().clone();
|
||||
let mut this = Self {
|
||||
context,
|
||||
slash_commands,
|
||||
tools,
|
||||
editor,
|
||||
lsp_adapter_delegate,
|
||||
blocks: Default::default(),
|
||||
|
@ -260,7 +255,6 @@ impl ContextEditor {
|
|||
project,
|
||||
pending_slash_command_creases: HashMap::default(),
|
||||
invoked_slash_command_creases: HashMap::default(),
|
||||
pending_tool_use_creases: HashMap::default(),
|
||||
_subscriptions,
|
||||
patches: HashMap::default(),
|
||||
active_patch: None,
|
||||
|
@ -580,87 +574,6 @@ impl ContextEditor {
|
|||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
let new_tool_uses = self
|
||||
.context
|
||||
.read(cx)
|
||||
.pending_tool_uses()
|
||||
.into_iter()
|
||||
.filter(|tool_use| {
|
||||
!self
|
||||
.pending_tool_use_creases
|
||||
.contains_key(&tool_use.source_range)
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
||||
let (excerpt_id, _buffer_id, _) = buffer.as_singleton().unwrap();
|
||||
let excerpt_id = *excerpt_id;
|
||||
|
||||
let mut buffer_rows_to_fold = BTreeSet::new();
|
||||
|
||||
let creases = new_tool_uses
|
||||
.iter()
|
||||
.map(|tool_use| {
|
||||
let placeholder = FoldPlaceholder {
|
||||
render: render_fold_icon_button(
|
||||
cx.entity().downgrade(),
|
||||
IconName::PocketKnife,
|
||||
tool_use.name.clone().into(),
|
||||
),
|
||||
..Default::default()
|
||||
};
|
||||
let render_trailer =
|
||||
move |_row, _unfold, _window: &mut Window, _cx: &mut App| {
|
||||
Empty.into_any()
|
||||
};
|
||||
|
||||
let start = buffer
|
||||
.anchor_in_excerpt(excerpt_id, tool_use.source_range.start)
|
||||
.unwrap();
|
||||
let end = buffer
|
||||
.anchor_in_excerpt(excerpt_id, tool_use.source_range.end)
|
||||
.unwrap();
|
||||
|
||||
let buffer_row = MultiBufferRow(start.to_point(&buffer).row);
|
||||
buffer_rows_to_fold.insert(buffer_row);
|
||||
|
||||
self.context.update(cx, |context, cx| {
|
||||
context.insert_content(
|
||||
Content::ToolUse {
|
||||
range: tool_use.source_range.clone(),
|
||||
tool_use: LanguageModelToolUse {
|
||||
id: tool_use.id.clone(),
|
||||
name: tool_use.name.clone(),
|
||||
input: tool_use.input.clone(),
|
||||
},
|
||||
},
|
||||
cx,
|
||||
);
|
||||
});
|
||||
|
||||
Crease::inline(
|
||||
start..end,
|
||||
placeholder,
|
||||
fold_toggle("tool-use"),
|
||||
render_trailer,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let crease_ids = editor.insert_creases(creases, cx);
|
||||
|
||||
for buffer_row in buffer_rows_to_fold.into_iter().rev() {
|
||||
editor.fold_at(&FoldAt { buffer_row }, window, cx);
|
||||
}
|
||||
|
||||
self.pending_tool_use_creases.extend(
|
||||
new_tool_uses
|
||||
.iter()
|
||||
.map(|tool_use| tool_use.source_range.clone())
|
||||
.zip(crease_ids),
|
||||
);
|
||||
});
|
||||
}
|
||||
ContextEvent::PatchesUpdated { removed, updated } => {
|
||||
|
@ -758,66 +671,6 @@ impl ContextEditor {
|
|||
ContextEvent::SlashCommandOutputSectionAdded { section } => {
|
||||
self.insert_slash_command_output_sections([section.clone()], false, window, cx);
|
||||
}
|
||||
ContextEvent::UsePendingTools => {
|
||||
let pending_tool_uses = self
|
||||
.context
|
||||
.read(cx)
|
||||
.pending_tool_uses()
|
||||
.into_iter()
|
||||
.filter(|tool_use| tool_use.status.is_idle())
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for tool_use in pending_tool_uses {
|
||||
if let Some(tool) = self.tools.tool(&tool_use.name, cx) {
|
||||
let task = tool.run(tool_use.input, self.workspace.clone(), window, cx);
|
||||
|
||||
self.context.update(cx, |context, cx| {
|
||||
context.insert_tool_output(tool_use.id.clone(), task, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
ContextEvent::ToolFinished {
|
||||
tool_use_id,
|
||||
output_range,
|
||||
} => {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
||||
let (excerpt_id, _buffer_id, _) = buffer.as_singleton().unwrap();
|
||||
let excerpt_id = *excerpt_id;
|
||||
|
||||
let placeholder = FoldPlaceholder {
|
||||
render: render_fold_icon_button(
|
||||
cx.entity().downgrade(),
|
||||
IconName::PocketKnife,
|
||||
format!("Tool Result: {tool_use_id}").into(),
|
||||
),
|
||||
..Default::default()
|
||||
};
|
||||
let render_trailer =
|
||||
move |_row, _unfold, _window: &mut Window, _cx: &mut App| Empty.into_any();
|
||||
|
||||
let start = buffer
|
||||
.anchor_in_excerpt(excerpt_id, output_range.start)
|
||||
.unwrap();
|
||||
let end = buffer
|
||||
.anchor_in_excerpt(excerpt_id, output_range.end)
|
||||
.unwrap();
|
||||
|
||||
let buffer_row = MultiBufferRow(start.to_point(&buffer).row);
|
||||
|
||||
let crease = Crease::inline(
|
||||
start..end,
|
||||
placeholder,
|
||||
fold_toggle("tool-use"),
|
||||
render_trailer,
|
||||
);
|
||||
|
||||
editor.insert_creases([crease], cx);
|
||||
editor.fold_at(&FoldAt { buffer_row }, window, cx);
|
||||
});
|
||||
}
|
||||
ContextEvent::Operation(_) => {}
|
||||
ContextEvent::ShowAssistError(error_message) => {
|
||||
self.last_error = Some(AssistError::Message(error_message.clone()));
|
||||
|
@ -2112,18 +1965,13 @@ impl ContextEditor {
|
|||
.context
|
||||
.read(cx)
|
||||
.contents(cx)
|
||||
.filter_map(|content| {
|
||||
if let Content::Image {
|
||||
anchor,
|
||||
render_image,
|
||||
..
|
||||
} = content
|
||||
{
|
||||
Some((anchor, render_image))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(
|
||||
|Content::Image {
|
||||
anchor,
|
||||
render_image,
|
||||
..
|
||||
}| (anchor, render_image),
|
||||
)
|
||||
.filter_map(|(anchor, render_image)| {
|
||||
const MAX_HEIGHT_IN_LINES: u32 = 8;
|
||||
let anchor = buffer.anchor_in_excerpt(excerpt_id, anchor).unwrap();
|
||||
|
|
|
@ -4,12 +4,11 @@ use crate::{
|
|||
};
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use assistant_slash_command::{SlashCommandId, SlashCommandWorkingSet};
|
||||
use assistant_tool::{ToolId, ToolWorkingSet};
|
||||
use client::{proto, telemetry::Telemetry, Client, TypedEnvelope};
|
||||
use clock::ReplicaId;
|
||||
use collections::HashMap;
|
||||
use context_server::manager::ContextServerManager;
|
||||
use context_server::{ContextServerFactoryRegistry, ContextServerTool};
|
||||
use context_server::ContextServerFactoryRegistry;
|
||||
use fs::Fs;
|
||||
use futures::StreamExt;
|
||||
use fuzzy::StringMatchCandidate;
|
||||
|
@ -50,12 +49,10 @@ pub struct ContextStore {
|
|||
contexts_metadata: Vec<SavedContextMetadata>,
|
||||
context_server_manager: Entity<ContextServerManager>,
|
||||
context_server_slash_command_ids: HashMap<Arc<str>, Vec<SlashCommandId>>,
|
||||
context_server_tool_ids: HashMap<Arc<str>, Vec<ToolId>>,
|
||||
host_contexts: Vec<RemoteContextMetadata>,
|
||||
fs: Arc<dyn Fs>,
|
||||
languages: Arc<LanguageRegistry>,
|
||||
slash_commands: Arc<SlashCommandWorkingSet>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
telemetry: Arc<Telemetry>,
|
||||
_watch_updates: Task<Option<()>>,
|
||||
client: Arc<Client>,
|
||||
|
@ -98,7 +95,6 @@ impl ContextStore {
|
|||
project: Entity<Project>,
|
||||
prompt_builder: Arc<PromptBuilder>,
|
||||
slash_commands: Arc<SlashCommandWorkingSet>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<Entity<Self>>> {
|
||||
let fs = project.read(cx).fs().clone();
|
||||
|
@ -119,12 +115,10 @@ impl ContextStore {
|
|||
contexts_metadata: Vec::new(),
|
||||
context_server_manager,
|
||||
context_server_slash_command_ids: HashMap::default(),
|
||||
context_server_tool_ids: HashMap::default(),
|
||||
host_contexts: Vec::new(),
|
||||
fs,
|
||||
languages,
|
||||
slash_commands,
|
||||
tools,
|
||||
telemetry,
|
||||
_watch_updates: cx.spawn(|this, mut cx| {
|
||||
async move {
|
||||
|
@ -367,7 +361,6 @@ impl ContextStore {
|
|||
Some(self.telemetry.clone()),
|
||||
self.prompt_builder.clone(),
|
||||
self.slash_commands.clone(),
|
||||
self.tools.clone(),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
@ -391,7 +384,6 @@ impl ContextStore {
|
|||
let telemetry = self.telemetry.clone();
|
||||
let prompt_builder = self.prompt_builder.clone();
|
||||
let slash_commands = self.slash_commands.clone();
|
||||
let tools = self.tools.clone();
|
||||
let request = self.client.request(proto::CreateContext { project_id });
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let response = request.await?;
|
||||
|
@ -405,7 +397,6 @@ impl ContextStore {
|
|||
language_registry,
|
||||
prompt_builder,
|
||||
slash_commands,
|
||||
tools,
|
||||
Some(project),
|
||||
Some(telemetry),
|
||||
cx,
|
||||
|
@ -456,7 +447,6 @@ impl ContextStore {
|
|||
});
|
||||
let prompt_builder = self.prompt_builder.clone();
|
||||
let slash_commands = self.slash_commands.clone();
|
||||
let tools = self.tools.clone();
|
||||
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let saved_context = load.await?;
|
||||
|
@ -467,7 +457,6 @@ impl ContextStore {
|
|||
languages,
|
||||
prompt_builder,
|
||||
slash_commands,
|
||||
tools,
|
||||
Some(project),
|
||||
Some(telemetry),
|
||||
cx,
|
||||
|
@ -535,7 +524,6 @@ impl ContextStore {
|
|||
});
|
||||
let prompt_builder = self.prompt_builder.clone();
|
||||
let slash_commands = self.slash_commands.clone();
|
||||
let tools = self.tools.clone();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let response = request.await?;
|
||||
let context_proto = response.context.context("invalid context")?;
|
||||
|
@ -547,7 +535,6 @@ impl ContextStore {
|
|||
language_registry,
|
||||
prompt_builder,
|
||||
slash_commands,
|
||||
tools,
|
||||
Some(project),
|
||||
Some(telemetry),
|
||||
cx,
|
||||
|
@ -816,7 +803,6 @@ impl ContextStore {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let slash_command_working_set = self.slash_commands.clone();
|
||||
let tool_working_set = self.tools.clone();
|
||||
match event {
|
||||
context_server::manager::Event::ServerStarted { server_id } => {
|
||||
if let Some(server) = context_server_manager.read(cx).get_server(server_id) {
|
||||
|
@ -856,29 +842,6 @@ impl ContextStore {
|
|||
.log_err();
|
||||
}
|
||||
}
|
||||
|
||||
if protocol.capable(context_server::protocol::ServerCapability::Tools) {
|
||||
if let Some(tools) = protocol.list_tools().await.log_err() {
|
||||
let tool_ids = tools.tools.into_iter().map(|tool| {
|
||||
log::info!("registering context server tool: {:?}", tool.name);
|
||||
tool_working_set.insert(
|
||||
Arc::new(ContextServerTool::new(
|
||||
context_server_manager.clone(),
|
||||
server.id(),
|
||||
tool,
|
||||
)),
|
||||
)
|
||||
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
|
||||
this.update(&mut cx, |this, _cx| {
|
||||
this.context_server_tool_ids
|
||||
.insert(server_id, tool_ids);
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
@ -890,10 +853,6 @@ impl ContextStore {
|
|||
{
|
||||
slash_command_working_set.remove(&slash_command_ids);
|
||||
}
|
||||
|
||||
if let Some(tool_ids) = self.context_server_tool_ids.remove(server_id) {
|
||||
tool_working_set.remove(&tool_ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use crate::{
|
|||
use anyhow::{anyhow, Result};
|
||||
use assistant_context_editor::ContextStore;
|
||||
use assistant_slash_command::SlashCommandWorkingSet;
|
||||
use assistant_tool::ToolWorkingSet;
|
||||
use call::{room, ActiveCall, ParticipantLocation, Room};
|
||||
use client::{User, RECEIVE_TIMEOUT};
|
||||
use collections::{HashMap, HashSet};
|
||||
|
@ -6547,7 +6546,6 @@ async fn test_context_collaboration_with_reconnect(
|
|||
project_a.clone(),
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
cx,
|
||||
)
|
||||
})
|
||||
|
@ -6559,7 +6557,6 @@ async fn test_context_collaboration_with_reconnect(
|
|||
project_b.clone(),
|
||||
prompt_builder.clone(),
|
||||
Arc::new(SlashCommandWorkingSet::default()),
|
||||
Arc::new(ToolWorkingSet::default()),
|
||||
cx,
|
||||
)
|
||||
})
|
||||
|
|
|
@ -41,16 +41,6 @@ impl FeatureFlag for Assistant2FeatureFlag {
|
|||
const NAME: &'static str = "assistant2";
|
||||
}
|
||||
|
||||
pub struct ToolUseFeatureFlag;
|
||||
|
||||
impl FeatureFlag for ToolUseFeatureFlag {
|
||||
const NAME: &'static str = "assistant-tool-use";
|
||||
|
||||
fn enabled_for_staff() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PredictEditsFeatureFlag;
|
||||
impl FeatureFlag for PredictEditsFeatureFlag {
|
||||
const NAME: &'static str = "predict-edits";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue