Pass up intent with completion requests (#31710)

This PR adds a new `intent` field to completion requests to assist in
categorizing them correctly.

Release Notes:

- N/A

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
This commit is contained in:
Marshall Bowers 2025-05-29 16:43:12 -04:00 committed by GitHub
parent 38e45e828b
commit a23ee61a4b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 110 additions and 34 deletions

7
Cargo.lock generated
View file

@ -559,6 +559,7 @@ dependencies = [
"workspace", "workspace",
"workspace-hack", "workspace-hack",
"zed_actions", "zed_actions",
"zed_llm_client",
] ]
[[package]] [[package]]
@ -5047,6 +5048,7 @@ dependencies = [
"util", "util",
"uuid", "uuid",
"workspace-hack", "workspace-hack",
"zed_llm_client",
] ]
[[package]] [[package]]
@ -6149,6 +6151,7 @@ dependencies = [
"workspace", "workspace",
"workspace-hack", "workspace-hack",
"zed_actions", "zed_actions",
"zed_llm_client",
"zlog", "zlog",
] ]
@ -19876,9 +19879,9 @@ dependencies = [
[[package]] [[package]]
name = "zed_llm_client" name = "zed_llm_client"
version = "0.8.3" version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22a8b9575b215536ed8ad254ba07171e4e13bd029eda3b54cca4b184d2768050" checksum = "de7d9523255f4e00ee3d0918e5407bd252d798a4a8e71f6d37f23317a1588203"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"serde", "serde",

View file

@ -617,7 +617,7 @@ wasmtime = { version = "29", default-features = false, features = [
wasmtime-wasi = "29" wasmtime-wasi = "29"
which = "6.0.0" which = "6.0.0"
workspace-hack = "0.1.0" workspace-hack = "0.1.0"
zed_llm_client = "0.8.3" zed_llm_client = "0.8.4"
zstd = "0.11" zstd = "0.11"
[workspace.dependencies.async-stripe] [workspace.dependencies.async-stripe]

View file

@ -55,6 +55,7 @@ use util::ResultExt as _;
use util::markdown::MarkdownCodeBlock; use util::markdown::MarkdownCodeBlock;
use workspace::{CollaboratorId, Workspace}; use workspace::{CollaboratorId, Workspace};
use zed_actions::assistant::OpenRulesLibrary; use zed_actions::assistant::OpenRulesLibrary;
use zed_llm_client::CompletionIntent;
pub struct ActiveThread { pub struct ActiveThread {
context_store: Entity<ContextStore>, context_store: Entity<ContextStore>,
@ -1436,6 +1437,7 @@ impl ActiveThread {
let request = language_model::LanguageModelRequest { let request = language_model::LanguageModelRequest {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
intent: None,
mode: None, mode: None,
messages: vec![request_message], messages: vec![request_message],
tools: vec![], tools: vec![],
@ -1610,7 +1612,12 @@ impl ActiveThread {
this.thread.update(cx, |thread, cx| { this.thread.update(cx, |thread, cx| {
thread.advance_prompt_id(); thread.advance_prompt_id();
thread.send_to_model(model.model, Some(window.window_handle()), cx); thread.send_to_model(
model.model,
CompletionIntent::UserPrompt,
Some(window.window_handle()),
cx,
);
}); });
this._load_edited_message_context_task = None; this._load_edited_message_context_task = None;
cx.notify(); cx.notify();
@ -3702,7 +3709,8 @@ mod tests {
// Stream response to user message // Stream response to user message
thread.update(cx, |thread, cx| { thread.update(cx, |thread, cx| {
let request = thread.to_completion_request(model.clone(), cx); let request =
thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx);
thread.stream_completion(request, model, cx.active_window(), cx) thread.stream_completion(request, model, cx.active_window(), cx)
}); });
// Follow the agent // Follow the agent

View file

@ -52,7 +52,7 @@ use workspace::{
use zed_actions::agent::{OpenConfiguration, OpenOnboardingModal, ResetOnboarding}; use zed_actions::agent::{OpenConfiguration, OpenOnboardingModal, ResetOnboarding};
use zed_actions::assistant::{OpenRulesLibrary, ToggleFocus}; use zed_actions::assistant::{OpenRulesLibrary, ToggleFocus};
use zed_actions::{DecreaseBufferFontSize, IncreaseBufferFontSize, ResetBufferFontSize}; use zed_actions::{DecreaseBufferFontSize, IncreaseBufferFontSize, ResetBufferFontSize};
use zed_llm_client::UsageLimit; use zed_llm_client::{CompletionIntent, UsageLimit};
use crate::active_thread::{self, ActiveThread, ActiveThreadEvent}; use crate::active_thread::{self, ActiveThread, ActiveThreadEvent};
use crate::agent_configuration::{AgentConfiguration, AssistantConfigurationEvent}; use crate::agent_configuration::{AgentConfiguration, AssistantConfigurationEvent};
@ -1310,7 +1310,12 @@ impl AgentPanel {
active_thread.thread().update(cx, |thread, cx| { active_thread.thread().update(cx, |thread, cx| {
thread.insert_invisible_continue_message(cx); thread.insert_invisible_continue_message(cx);
thread.advance_prompt_id(); thread.advance_prompt_id();
thread.send_to_model(model, Some(window.window_handle()), cx); thread.send_to_model(
model,
CompletionIntent::UserPrompt,
Some(window.window_handle()),
cx,
);
}); });
}); });
} else { } else {

View file

@ -34,6 +34,7 @@ use std::{
}; };
use streaming_diff::{CharOperation, LineDiff, LineOperation, StreamingDiff}; use streaming_diff::{CharOperation, LineDiff, LineOperation, StreamingDiff};
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase}; use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
use zed_llm_client::CompletionIntent;
pub struct BufferCodegen { pub struct BufferCodegen {
alternatives: Vec<Entity<CodegenAlternative>>, alternatives: Vec<Entity<CodegenAlternative>>,
@ -464,6 +465,7 @@ impl CodegenAlternative {
LanguageModelRequest { LanguageModelRequest {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
intent: Some(CompletionIntent::InlineAssist),
mode: None, mode: None,
tools: Vec::new(), tools: Vec::new(),
tool_choice: None, tool_choice: None,

View file

@ -42,6 +42,7 @@ use theme::ThemeSettings;
use ui::{Disclosure, KeyBinding, PopoverMenuHandle, Tooltip, prelude::*}; use ui::{Disclosure, KeyBinding, PopoverMenuHandle, Tooltip, prelude::*};
use util::{ResultExt as _, maybe}; use util::{ResultExt as _, maybe};
use workspace::{CollaboratorId, Workspace}; use workspace::{CollaboratorId, Workspace};
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_store::ContextStore;
@ -375,7 +376,12 @@ impl MessageEditor {
thread thread
.update(cx, |thread, cx| { .update(cx, |thread, cx| {
thread.advance_prompt_id(); thread.advance_prompt_id();
thread.send_to_model(model, Some(window_handle), cx); thread.send_to_model(
model,
CompletionIntent::UserPrompt,
Some(window_handle),
cx,
);
}) })
.log_err(); .log_err();
}) })
@ -1280,6 +1286,7 @@ impl MessageEditor {
let request = language_model::LanguageModelRequest { let request = language_model::LanguageModelRequest {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
intent: None,
mode: None, mode: None,
messages: vec![request_message], messages: vec![request_message],
tools: vec![], tools: vec![],

View file

@ -25,6 +25,7 @@ use terminal_view::TerminalView;
use ui::prelude::*; use ui::prelude::*;
use util::ResultExt; use util::ResultExt;
use workspace::{Toast, Workspace, notifications::NotificationId}; use workspace::{Toast, Workspace, notifications::NotificationId};
use zed_llm_client::CompletionIntent;
pub fn init( pub fn init(
fs: Arc<dyn Fs>, fs: Arc<dyn Fs>,
@ -291,6 +292,7 @@ impl TerminalInlineAssistant {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
mode: None, mode: None,
intent: Some(CompletionIntent::TerminalInlineAssist),
messages: vec![request_message], messages: vec![request_message],
tools: Vec::new(), tools: Vec::new(),
tool_choice: None, tool_choice: None,

View file

@ -38,7 +38,7 @@ use thiserror::Error;
use ui::Window; 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::CompletionRequestStatus; use zed_llm_client::{CompletionIntent, CompletionRequestStatus};
use crate::ThreadStore; use crate::ThreadStore;
use crate::context::{AgentContext, AgentContextHandle, ContextLoadResult, LoadedContext}; use crate::context::{AgentContext, AgentContextHandle, ContextLoadResult, LoadedContext};
@ -1184,6 +1184,7 @@ impl Thread {
pub fn send_to_model( pub fn send_to_model(
&mut self, &mut self,
model: Arc<dyn LanguageModel>, model: Arc<dyn LanguageModel>,
intent: CompletionIntent,
window: Option<AnyWindowHandle>, window: Option<AnyWindowHandle>,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
@ -1193,7 +1194,7 @@ impl Thread {
self.remaining_turns -= 1; self.remaining_turns -= 1;
let request = self.to_completion_request(model.clone(), cx); let request = self.to_completion_request(model.clone(), intent, cx);
self.stream_completion(request, model, window, cx); self.stream_completion(request, model, window, cx);
} }
@ -1213,11 +1214,13 @@ impl Thread {
pub fn to_completion_request( pub fn to_completion_request(
&self, &self,
model: Arc<dyn LanguageModel>, model: Arc<dyn LanguageModel>,
intent: CompletionIntent,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> LanguageModelRequest { ) -> LanguageModelRequest {
let mut request = LanguageModelRequest { let mut request = LanguageModelRequest {
thread_id: Some(self.id.to_string()), thread_id: Some(self.id.to_string()),
prompt_id: Some(self.last_prompt_id.to_string()), prompt_id: Some(self.last_prompt_id.to_string()),
intent: Some(intent),
mode: None, mode: None,
messages: vec![], messages: vec![],
tools: Vec::new(), tools: Vec::new(),
@ -1371,12 +1374,14 @@ impl Thread {
fn to_summarize_request( fn to_summarize_request(
&self, &self,
model: &Arc<dyn LanguageModel>, model: &Arc<dyn LanguageModel>,
intent: CompletionIntent,
added_user_message: String, added_user_message: String,
cx: &App, cx: &App,
) -> LanguageModelRequest { ) -> LanguageModelRequest {
let mut request = LanguageModelRequest { let mut request = LanguageModelRequest {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
intent: Some(intent),
mode: None, mode: None,
messages: vec![], messages: vec![],
tools: Vec::new(), tools: Vec::new(),
@ -1854,7 +1859,12 @@ impl Thread {
If the conversation is about a specific subject, include it in the title. \ If the conversation is about a specific subject, include it in the title. \
Be descriptive. DO NOT speak in the first person."; Be descriptive. DO NOT speak in the first person.";
let request = self.to_summarize_request(&model.model, added_user_message.into(), cx); let request = self.to_summarize_request(
&model.model,
CompletionIntent::ThreadSummarization,
added_user_message.into(),
cx,
);
self.summary = ThreadSummary::Generating; self.summary = ThreadSummary::Generating;
@ -1955,7 +1965,12 @@ impl Thread {
4. Any action items or next steps if any\n\ 4. Any action items or next steps if any\n\
Format it in Markdown with headings and bullet points."; Format it in Markdown with headings and bullet points.";
let request = self.to_summarize_request(&model, added_user_message.into(), cx); let request = self.to_summarize_request(
&model,
CompletionIntent::ThreadContextSummarization,
added_user_message.into(),
cx,
);
*self.detailed_summary_tx.borrow_mut() = DetailedSummaryState::Generating { *self.detailed_summary_tx.borrow_mut() = DetailedSummaryState::Generating {
message_id: last_message_id, message_id: last_message_id,
@ -2047,7 +2062,8 @@ impl Thread {
model: Arc<dyn LanguageModel>, model: Arc<dyn LanguageModel>,
) -> Vec<PendingToolUse> { ) -> Vec<PendingToolUse> {
self.auto_capture_telemetry(cx); self.auto_capture_telemetry(cx);
let request = Arc::new(self.to_completion_request(model.clone(), cx)); let request =
Arc::new(self.to_completion_request(model.clone(), CompletionIntent::ToolResults, cx));
let pending_tool_uses = self let pending_tool_uses = self
.tool_use .tool_use
.pending_tool_uses() .pending_tool_uses()
@ -2243,7 +2259,7 @@ impl Thread {
if self.all_tools_finished() { if self.all_tools_finished() {
if let Some(ConfiguredModel { model, .. }) = self.configured_model.as_ref() { if let Some(ConfiguredModel { model, .. }) = self.configured_model.as_ref() {
if !canceled { if !canceled {
self.send_to_model(model.clone(), window, cx); self.send_to_model(model.clone(), CompletionIntent::ToolResults, window, cx);
} }
self.auto_capture_telemetry(cx); self.auto_capture_telemetry(cx);
} }
@ -2934,7 +2950,7 @@ fn main() {{
// Check message in request // Check message in request
let request = thread.update(cx, |thread, cx| { let request = thread.update(cx, |thread, cx| {
thread.to_completion_request(model.clone(), cx) thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx)
}); });
assert_eq!(request.messages.len(), 2); assert_eq!(request.messages.len(), 2);
@ -3029,7 +3045,7 @@ fn main() {{
// Check entire request to make sure all contexts are properly included // Check entire request to make sure all contexts are properly included
let request = thread.update(cx, |thread, cx| { let request = thread.update(cx, |thread, cx| {
thread.to_completion_request(model.clone(), cx) thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx)
}); });
// The request should contain all 3 messages // The request should contain all 3 messages
@ -3136,7 +3152,7 @@ fn main() {{
// Check message in request // Check message in request
let request = thread.update(cx, |thread, cx| { let request = thread.update(cx, |thread, cx| {
thread.to_completion_request(model.clone(), cx) thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx)
}); });
assert_eq!(request.messages.len(), 2); assert_eq!(request.messages.len(), 2);
@ -3162,7 +3178,7 @@ fn main() {{
// Check that both messages appear in the request // Check that both messages appear in the request
let request = thread.update(cx, |thread, cx| { let request = thread.update(cx, |thread, cx| {
thread.to_completion_request(model.clone(), cx) thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx)
}); });
assert_eq!(request.messages.len(), 3); assert_eq!(request.messages.len(), 3);
@ -3207,7 +3223,7 @@ fn main() {{
// Create a request and check that it doesn't have a stale buffer warning yet // Create a request and check that it doesn't have a stale buffer warning yet
let initial_request = thread.update(cx, |thread, cx| { let initial_request = thread.update(cx, |thread, cx| {
thread.to_completion_request(model.clone(), cx) thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx)
}); });
// Make sure we don't have a stale file warning yet // Make sure we don't have a stale file warning yet
@ -3243,7 +3259,7 @@ fn main() {{
// Create a new request and check for the stale buffer warning // Create a new request and check for the stale buffer warning
let new_request = thread.update(cx, |thread, cx| { let new_request = thread.update(cx, |thread, cx| {
thread.to_completion_request(model.clone(), cx) thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx)
}); });
// We should have a stale file warning as the last message // We should have a stale file warning as the last message
@ -3293,7 +3309,7 @@ fn main() {{
}); });
let request = thread.update(cx, |thread, cx| { let request = thread.update(cx, |thread, cx| {
thread.to_completion_request(model.clone(), cx) thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx)
}); });
assert_eq!(request.temperature, Some(0.66)); assert_eq!(request.temperature, Some(0.66));
@ -3313,7 +3329,7 @@ fn main() {{
}); });
let request = thread.update(cx, |thread, cx| { let request = thread.update(cx, |thread, cx| {
thread.to_completion_request(model.clone(), cx) thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx)
}); });
assert_eq!(request.temperature, Some(0.66)); assert_eq!(request.temperature, Some(0.66));
@ -3333,7 +3349,7 @@ fn main() {{
}); });
let request = thread.update(cx, |thread, cx| { let request = thread.update(cx, |thread, cx| {
thread.to_completion_request(model.clone(), cx) thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx)
}); });
assert_eq!(request.temperature, Some(0.66)); assert_eq!(request.temperature, Some(0.66));
@ -3353,7 +3369,7 @@ fn main() {{
}); });
let request = thread.update(cx, |thread, cx| { let request = thread.update(cx, |thread, cx| {
thread.to_completion_request(model.clone(), cx) thread.to_completion_request(model.clone(), CompletionIntent::UserPrompt, cx)
}); });
assert_eq!(request.temperature, None); assert_eq!(request.temperature, None);
} }
@ -3385,7 +3401,12 @@ fn main() {{
// Send a message // Send a message
thread.update(cx, |thread, cx| { thread.update(cx, |thread, cx| {
thread.insert_user_message("Hi!", ContextLoadResult::default(), None, vec![], cx); thread.insert_user_message("Hi!", ContextLoadResult::default(), None, vec![], cx);
thread.send_to_model(model.clone(), None, cx); thread.send_to_model(
model.clone(),
CompletionIntent::ThreadSummarization,
None,
cx,
);
}); });
let fake_model = model.as_fake(); let fake_model = model.as_fake();
@ -3480,7 +3501,7 @@ fn main() {{
vec![], vec![],
cx, cx,
); );
thread.send_to_model(model.clone(), None, cx); thread.send_to_model(model.clone(), CompletionIntent::UserPrompt, None, cx);
}); });
let fake_model = model.as_fake(); let fake_model = model.as_fake();
@ -3518,7 +3539,12 @@ fn main() {{
) { ) {
thread.update(cx, |thread, cx| { thread.update(cx, |thread, cx| {
thread.insert_user_message("Hi!", ContextLoadResult::default(), None, vec![], cx); thread.insert_user_message("Hi!", ContextLoadResult::default(), None, vec![], cx);
thread.send_to_model(model.clone(), None, cx); thread.send_to_model(
model.clone(),
CompletionIntent::ThreadSummarization,
None,
cx,
);
}); });
let fake_model = model.as_fake(); let fake_model = model.as_fake();

View file

@ -57,6 +57,7 @@ uuid.workspace = true
workspace-hack.workspace = true workspace-hack.workspace = true
workspace.workspace = true workspace.workspace = true
zed_actions.workspace = true zed_actions.workspace = true
zed_llm_client.workspace = true
[dev-dependencies] [dev-dependencies]
language_model = { workspace = true, features = ["test-support"] } language_model = { workspace = true, features = ["test-support"] }

View file

@ -45,6 +45,7 @@ use text::{BufferSnapshot, ToPoint};
use ui::IconName; use ui::IconName;
use util::{ResultExt, TryFutureExt, post_inc}; use util::{ResultExt, TryFutureExt, post_inc};
use uuid::Uuid; use uuid::Uuid;
use zed_llm_client::CompletionIntent;
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct ContextId(String); pub struct ContextId(String);
@ -2272,6 +2273,7 @@ impl AssistantContext {
let mut completion_request = LanguageModelRequest { let mut completion_request = LanguageModelRequest {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
intent: Some(CompletionIntent::UserPrompt),
mode: None, mode: None,
messages: Vec::new(), messages: Vec::new(),
tools: Vec::new(), tools: Vec::new(),

View file

@ -28,6 +28,7 @@ use std::{cmp, iter, mem, ops::Range, path::PathBuf, pin::Pin, sync::Arc, task::
use streaming_diff::{CharOperation, StreamingDiff}; use streaming_diff::{CharOperation, StreamingDiff};
use streaming_fuzzy_matcher::StreamingFuzzyMatcher; use streaming_fuzzy_matcher::StreamingFuzzyMatcher;
use util::debug_panic; use util::debug_panic;
use zed_llm_client::CompletionIntent;
#[derive(Serialize)] #[derive(Serialize)]
struct CreateFilePromptTemplate { struct CreateFilePromptTemplate {
@ -106,7 +107,9 @@ impl EditAgent {
edit_description, edit_description,
} }
.render(&this.templates)?; .render(&this.templates)?;
let new_chunks = this.request(conversation, prompt, cx).await?; let new_chunks = this
.request(conversation, CompletionIntent::CreateFile, prompt, cx)
.await?;
let (output, mut inner_events) = this.overwrite_with_chunks(buffer, new_chunks, cx); let (output, mut inner_events) = this.overwrite_with_chunks(buffer, new_chunks, cx);
while let Some(event) = inner_events.next().await { while let Some(event) = inner_events.next().await {
@ -213,7 +216,9 @@ impl EditAgent {
edit_description, edit_description,
} }
.render(&this.templates)?; .render(&this.templates)?;
let edit_chunks = this.request(conversation, prompt, cx).await?; let edit_chunks = this
.request(conversation, CompletionIntent::EditFile, prompt, cx)
.await?;
this.apply_edit_chunks(buffer, edit_chunks, events_tx, cx) this.apply_edit_chunks(buffer, edit_chunks, events_tx, cx)
.await .await
}); });
@ -589,6 +594,7 @@ impl EditAgent {
async fn request( async fn request(
&self, &self,
mut conversation: LanguageModelRequest, mut conversation: LanguageModelRequest,
intent: CompletionIntent,
prompt: String, prompt: String,
cx: &mut AsyncApp, cx: &mut AsyncApp,
) -> Result<BoxStream<'static, Result<String, LanguageModelCompletionError>>> { ) -> Result<BoxStream<'static, Result<String, LanguageModelCompletionError>>> {
@ -646,6 +652,7 @@ impl EditAgent {
let request = LanguageModelRequest { let request = LanguageModelRequest {
thread_id: conversation.thread_id, thread_id: conversation.thread_id,
prompt_id: conversation.prompt_id, prompt_id: conversation.prompt_id,
intent: Some(intent),
mode: conversation.mode, mode: conversation.mode,
messages: conversation.messages, messages: conversation.messages,
tool_choice, tool_choice,

View file

@ -67,3 +67,4 @@ unindent.workspace = true
util.workspace = true util.workspace = true
uuid.workspace = true uuid.workspace = true
workspace-hack.workspace = true workspace-hack.workspace = true
zed_llm_client.workspace = true

View file

@ -19,6 +19,7 @@ use collections::HashMap;
use futures::{FutureExt as _, StreamExt, channel::mpsc, select_biased}; use futures::{FutureExt as _, StreamExt, channel::mpsc, select_biased};
use gpui::{App, AppContext, AsyncApp, Entity}; use gpui::{App, AppContext, AsyncApp, Entity};
use language_model::{LanguageModel, Role, StopReason}; use language_model::{LanguageModel, Role, StopReason};
use zed_llm_client::CompletionIntent;
pub const THREAD_EVENT_TIMEOUT: Duration = Duration::from_secs(60 * 2); pub const THREAD_EVENT_TIMEOUT: Duration = Duration::from_secs(60 * 2);
@ -308,7 +309,7 @@ impl ExampleContext {
let message_count_before = self.app.update_entity(&self.agent_thread, |thread, cx| { let message_count_before = self.app.update_entity(&self.agent_thread, |thread, cx| {
thread.set_remaining_turns(iterations); thread.set_remaining_turns(iterations);
thread.send_to_model(model, None, cx); thread.send_to_model(model, CompletionIntent::UserPrompt, None, cx);
thread.messages().len() thread.messages().len()
})?; })?;

View file

@ -576,6 +576,7 @@ impl ExampleInstance {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
mode: None, mode: None,
intent: None,
messages: vec![LanguageModelRequestMessage { messages: vec![LanguageModelRequestMessage {
role: Role::User, role: Role::User,
content: vec![MessageContent::Text(to_prompt(assertion.description))], content: vec![MessageContent::Text(to_prompt(assertion.description))],

View file

@ -59,6 +59,7 @@ util.workspace = true
workspace-hack.workspace = true workspace-hack.workspace = true
workspace.workspace = true workspace.workspace = true
zed_actions.workspace = true zed_actions.workspace = true
zed_llm_client.workspace = true
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
windows.workspace = true windows.workspace = true

View file

@ -13,7 +13,6 @@ use agent_settings::AgentSettings;
use anyhow::Context as _; use anyhow::Context as _;
use askpass::AskPassDelegate; use askpass::AskPassDelegate;
use db::kvp::KEY_VALUE_STORE; use db::kvp::KEY_VALUE_STORE;
use editor::{ use editor::{
Editor, EditorElement, EditorMode, EditorSettings, MultiBuffer, ShowScrollbar, Editor, EditorElement, EditorMode, EditorSettings, MultiBuffer, ShowScrollbar,
scroll::ScrollbarAutoHide, scroll::ScrollbarAutoHide,
@ -42,6 +41,7 @@ use language_model::{
}; };
use menu::{Confirm, SecondaryConfirm, SelectFirst, SelectLast, SelectNext, SelectPrevious}; use menu::{Confirm, SecondaryConfirm, SelectFirst, SelectLast, SelectNext, SelectPrevious};
use multi_buffer::ExcerptInfo; use multi_buffer::ExcerptInfo;
use notifications::status_toast::{StatusToast, ToastIcon};
use panel::{ use panel::{
PanelHeader, panel_button, panel_editor_container, panel_editor_style, panel_filled_button, PanelHeader, panel_button, panel_editor_container, panel_editor_style, panel_filled_button,
panel_icon_button, panel_icon_button,
@ -64,13 +64,12 @@ use ui::{
}; };
use util::{ResultExt, TryFutureExt, maybe}; use util::{ResultExt, TryFutureExt, maybe};
use workspace::AppState; use workspace::AppState;
use notifications::status_toast::{StatusToast, ToastIcon};
use workspace::{ use workspace::{
Workspace, Workspace,
dock::{DockPosition, Panel, PanelEvent}, dock::{DockPosition, Panel, PanelEvent},
notifications::DetachAndPromptErr, notifications::DetachAndPromptErr,
}; };
use zed_llm_client::CompletionIntent;
actions!( actions!(
git_panel, git_panel,
@ -1767,6 +1766,7 @@ impl GitPanel {
let request = LanguageModelRequest { let request = LanguageModelRequest {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
intent: Some(CompletionIntent::GenerateGitCommitMessage),
mode: None, mode: None,
messages: vec![LanguageModelRequestMessage { messages: vec![LanguageModelRequestMessage {
role: Role::User, role: Role::User,

View file

@ -12,7 +12,7 @@ use gpui::{
use image::codecs::png::PngEncoder; use image::codecs::png::PngEncoder;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use util::ResultExt; use util::ResultExt;
use zed_llm_client::CompletionMode; use zed_llm_client::{CompletionIntent, CompletionMode};
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Hash)] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub struct LanguageModelImage { pub struct LanguageModelImage {
@ -384,6 +384,7 @@ pub enum LanguageModelToolChoice {
pub struct LanguageModelRequest { pub struct LanguageModelRequest {
pub thread_id: Option<String>, pub thread_id: Option<String>,
pub prompt_id: Option<String>, pub prompt_id: Option<String>,
pub intent: Option<CompletionIntent>,
pub mode: Option<CompletionMode>, pub mode: Option<CompletionMode>,
pub messages: Vec<LanguageModelRequestMessage>, pub messages: Vec<LanguageModelRequestMessage>,
pub tools: Vec<LanguageModelRequestTool>, pub tools: Vec<LanguageModelRequestTool>,

View file

@ -809,6 +809,7 @@ impl LanguageModel for CloudLanguageModel {
> { > {
let thread_id = request.thread_id.clone(); let thread_id = request.thread_id.clone();
let prompt_id = request.prompt_id.clone(); let prompt_id = request.prompt_id.clone();
let intent = request.intent;
let mode = request.mode; let mode = request.mode;
let app_version = cx.update(|cx| AppVersion::global(cx)).ok(); let app_version = cx.update(|cx| AppVersion::global(cx)).ok();
match self.model.provider { match self.model.provider {
@ -841,6 +842,7 @@ impl LanguageModel for CloudLanguageModel {
CompletionBody { CompletionBody {
thread_id, thread_id,
prompt_id, prompt_id,
intent,
mode, mode,
provider: zed_llm_client::LanguageModelProvider::Anthropic, provider: zed_llm_client::LanguageModelProvider::Anthropic,
model: request.model.clone(), model: request.model.clone(),
@ -897,6 +899,7 @@ impl LanguageModel for CloudLanguageModel {
CompletionBody { CompletionBody {
thread_id, thread_id,
prompt_id, prompt_id,
intent,
mode, mode,
provider: zed_llm_client::LanguageModelProvider::OpenAi, provider: zed_llm_client::LanguageModelProvider::OpenAi,
model: request.model.clone(), model: request.model.clone(),
@ -934,6 +937,7 @@ impl LanguageModel for CloudLanguageModel {
CompletionBody { CompletionBody {
thread_id, thread_id,
prompt_id, prompt_id,
intent,
mode, mode,
provider: zed_llm_client::LanguageModelProvider::Google, provider: zed_llm_client::LanguageModelProvider::Google,
model: request.model.model_id.clone(), model: request.model.model_id.clone(),

View file

@ -816,6 +816,7 @@ mod tests {
tool_choice: None, tool_choice: None,
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
intent: None,
mode: None, mode: None,
stop: Vec::new(), stop: Vec::new(),
}; };

View file

@ -860,6 +860,7 @@ mod tests {
let request = LanguageModelRequest { let request = LanguageModelRequest {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
intent: None,
mode: None, mode: None,
messages: vec![LanguageModelRequestMessage { messages: vec![LanguageModelRequestMessage {
role: Role::User, role: Role::User,

View file

@ -923,6 +923,7 @@ impl RulesLibrary {
LanguageModelRequest { LanguageModelRequest {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
intent: None,
mode: None, mode: None,
messages: vec![LanguageModelRequestMessage { messages: vec![LanguageModelRequestMessage {
role: Role::System, role: Role::System,

View file

@ -560,6 +560,7 @@ impl SummaryIndex {
thread_id: None, thread_id: None,
prompt_id: None, prompt_id: None,
mode: None, mode: None,
intent: None,
messages: vec![LanguageModelRequestMessage { messages: vec![LanguageModelRequestMessage {
role: Role::User, role: Role::User,
content: vec![prompt.into()], content: vec![prompt.into()],