mirror of
https://github.com/zed-industries/zed.git
synced 2026-05-31 19:05:00 +07:00
agent_ui: Put fast mode behind confirmation popover (#57482)
It look like this: <img width="1698" height="688" alt="grafik" src="https://github.com/user-attachments/assets/02a37271-63d3-42da-887f-e17b31e8d9ca" /> The idea is to avoid people turning on fast mode without understanding the financial implications. It also clarifiers (in the BYOK case) why they might not see a difference between fast mode enabled and disabled. Release Notes: - N/A --------- Co-authored-by: Danilo Leal <daniloleal09@gmail.com> Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
This commit is contained in:
parent
fe48ef424c
commit
b328711bbe
9 changed files with 274 additions and 35 deletions
|
|
@ -41,10 +41,10 @@ use crate::thread_metadata_store::{ThreadId, ThreadMetadataStore, ThreadMetadata
|
|||
use crate::{
|
||||
AddContextServer, AgentDiffPane, ConversationView, CopyThreadToClipboard, Follow,
|
||||
LoadThreadFromClipboard, NewTerminalThread, NewThread, OpenActiveThreadAsMarkdown,
|
||||
OpenAgentDiff, ResetTrialEndUpsell, ResetTrialUpsell, ShowAllSidebarThreadMetadata,
|
||||
ShowThreadMetadata, ToggleNewThreadMenu, ToggleOptionsMenu,
|
||||
OpenAgentDiff, ResetFastModeWarnings, ResetTrialEndUpsell, ResetTrialUpsell,
|
||||
ShowAllSidebarThreadMetadata, ShowThreadMetadata, ToggleNewThreadMenu, ToggleOptionsMenu,
|
||||
agent_configuration::{AgentConfiguration, AssistantConfigurationEvent},
|
||||
conversation_view::{AcpThreadViewEvent, ThreadView},
|
||||
conversation_view::{AcpThreadViewEvent, ThreadView, reset_fast_mode_warnings},
|
||||
ui::{AgentNotification, AgentNotificationEvent, EndTrialUpsell},
|
||||
};
|
||||
use crate::{
|
||||
|
|
@ -381,6 +381,9 @@ pub fn init(cx: &mut App) {
|
|||
.register_action(|_workspace, _: &ResetTrialEndUpsell, _window, cx| {
|
||||
TrialEndUpsell::set_dismissed(false, cx);
|
||||
})
|
||||
.register_action(|_workspace, _: &ResetFastModeWarnings, _window, cx| {
|
||||
reset_fast_mode_warnings(cx);
|
||||
})
|
||||
.register_action(|workspace, _: &ResetAgentZoom, window, cx| {
|
||||
if let Some(panel) = workspace.panel::<AgentPanel>(cx) {
|
||||
panel.update(cx, |panel, cx| {
|
||||
|
|
|
|||
|
|
@ -245,6 +245,8 @@ actions!(
|
|||
ResetTrialUpsell,
|
||||
/// Resets the trial end upsell notification.
|
||||
ResetTrialEndUpsell,
|
||||
/// Re-enables the fast mode warning for every provider and model.
|
||||
ResetFastModeWarnings,
|
||||
/// Opens the "Add Context" menu in the message editor.
|
||||
OpenAddContextMenu,
|
||||
/// Interrupts the current generation and sends the message immediately.
|
||||
|
|
|
|||
|
|
@ -70,9 +70,8 @@ use util::{
|
|||
size::format_file_size,
|
||||
time::duration_alt_display,
|
||||
};
|
||||
use workspace::PathList;
|
||||
use workspace::{
|
||||
CollaboratorId, MultiWorkspace, NewTerminal, Toast, Workspace, notifications::NotificationId,
|
||||
CollaboratorId, MultiWorkspace, NewTerminal, PathList, Toast, Workspace,
|
||||
path_link::sanitize_path_text,
|
||||
};
|
||||
use zed_actions::agent::{Chat, ToggleModelSelector};
|
||||
|
|
|
|||
|
|
@ -16,13 +16,18 @@ use feature_flags::AcpBetaFeatureFlag;
|
|||
use crate::completion_provider::AvailableSkill;
|
||||
use crate::message_editor::SharedSessionCapabilities;
|
||||
|
||||
use db::kvp::KeyValueStore;
|
||||
use gpui::List;
|
||||
use gpui::TaskExt;
|
||||
use heapless::Vec as ArrayVec;
|
||||
use language_model::{LanguageModelEffortLevel, Speed};
|
||||
use language_model::{
|
||||
FastModeConfirmation, LanguageModelEffortLevel, LanguageModelId, LanguageModelProviderId,
|
||||
LanguageModelRegistry, Speed,
|
||||
};
|
||||
use settings::update_settings_file;
|
||||
use ui::{ButtonLike, SpinnerLabel, SpinnerVariant, SplitButton, SplitButtonStyle, Tab};
|
||||
use workspace::SERIALIZATION_THROTTLE_TIME;
|
||||
use workspace::notifications::NotificationId;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
@ -597,6 +602,7 @@ pub struct ThreadView {
|
|||
pub message_editor: Entity<MessageEditor>,
|
||||
pub add_context_menu_handle: PopoverMenuHandle<ContextMenu>,
|
||||
pub thinking_effort_menu_handle: PopoverMenuHandle<ContextMenu>,
|
||||
pub fast_mode_menu_handle: PopoverMenuHandle<ContextMenu>,
|
||||
pub project: WeakEntity<Project>,
|
||||
/// Cache + worktree snapshot for resolving paths in markdown code spans.
|
||||
/// Cloned from the parent `ConversationView` so the cache is shared and the
|
||||
|
|
@ -910,6 +916,7 @@ impl ThreadView {
|
|||
message_editor,
|
||||
add_context_menu_handle: PopoverMenuHandle::default(),
|
||||
thinking_effort_menu_handle: PopoverMenuHandle::default(),
|
||||
fast_mode_menu_handle: PopoverMenuHandle::default(),
|
||||
project,
|
||||
code_span_resolver,
|
||||
show_external_source_prompt_warning,
|
||||
|
|
@ -4197,33 +4204,139 @@ impl ThreadView {
|
|||
}
|
||||
|
||||
let thread = self.as_native_thread(cx)?.read(cx);
|
||||
let is_fast = matches!(thread.speed(), Some(Speed::Fast));
|
||||
|
||||
let (tooltip_label, color, icon) = if matches!(thread.speed(), Some(Speed::Fast)) {
|
||||
("Disable Fast Mode", Color::Accent, IconName::FastForward)
|
||||
let model_identity = thread
|
||||
.model()
|
||||
.map(|model| (model.provider_id(), model.id()));
|
||||
|
||||
let (tooltip_label, color, icon, new_speed) = if is_fast {
|
||||
(
|
||||
"Disable Fast Mode",
|
||||
Color::Accent,
|
||||
IconName::FastForward,
|
||||
Speed::Standard,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
"Enable Fast Mode",
|
||||
Color::Custom(cx.theme().colors().icon_disabled.opacity(0.8)),
|
||||
IconName::FastForwardOff,
|
||||
Speed::Fast,
|
||||
)
|
||||
};
|
||||
|
||||
let focus_handle = self.message_editor.focus_handle(cx);
|
||||
|
||||
let pending_confirmation = (!is_fast)
|
||||
.then(|| self.pending_fast_mode_confirmation(cx))
|
||||
.flatten();
|
||||
|
||||
let icon_button = IconButton::new("fast-mode", icon)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_color(color);
|
||||
|
||||
if let Some((provider_id, model_id, confirmation)) = pending_confirmation {
|
||||
let weak_self = cx.entity().downgrade();
|
||||
let tooltip_focus = focus_handle;
|
||||
|
||||
return Some(
|
||||
PopoverMenu::new("fast-mode-warning")
|
||||
.with_handle(self.fast_mode_menu_handle.clone())
|
||||
.trigger_with_tooltip(icon_button, move |_, cx| {
|
||||
Tooltip::for_action_in(tooltip_label, &ToggleFastMode, &tooltip_focus, cx)
|
||||
})
|
||||
.menu(move |window, cx| {
|
||||
let weak_self = weak_self.clone();
|
||||
let confirmation = confirmation.clone();
|
||||
let provider_id = provider_id.clone();
|
||||
let model_id = model_id.clone();
|
||||
|
||||
Some(ContextMenu::build(window, cx, move |menu, _window, _cx| {
|
||||
let message = confirmation.message.clone();
|
||||
menu.custom_row(move |_window, _cx| {
|
||||
div()
|
||||
.max_w_72()
|
||||
.child(Label::new(confirmation.title.clone()))
|
||||
.child(Label::new(message.clone()).color(Color::Muted))
|
||||
.into_any_element()
|
||||
})
|
||||
.separator()
|
||||
.item(ContextMenuEntry::new("Enable Now").handler({
|
||||
let weak_self = weak_self.clone();
|
||||
move |_window, cx| {
|
||||
weak_self
|
||||
.update(cx, |this, cx| {
|
||||
this.apply_fast_mode_speed(Speed::Fast, cx);
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
}))
|
||||
.item(
|
||||
ContextMenuEntry::new("Enable and Don't Show Again").handler({
|
||||
let weak_self = weak_self.clone();
|
||||
let provider_id = provider_id.clone();
|
||||
let model_id = model_id;
|
||||
move |_window, cx| {
|
||||
weak_self
|
||||
.update(cx, |this, cx| {
|
||||
this.apply_fast_mode_speed(Speed::Fast, cx);
|
||||
})
|
||||
.log_err();
|
||||
set_fast_mode_warning_dismissed(
|
||||
&provider_id,
|
||||
&model_id,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
}),
|
||||
)
|
||||
}))
|
||||
})
|
||||
.offset(gpui::Point {
|
||||
x: px(0.0),
|
||||
y: px(-2.0),
|
||||
})
|
||||
.anchor(gpui::Anchor::BottomLeft)
|
||||
.into_any_element(),
|
||||
);
|
||||
}
|
||||
|
||||
let _ = model_identity;
|
||||
|
||||
Some(
|
||||
IconButton::new("fast-mode", icon)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_color(color)
|
||||
icon_button
|
||||
.tooltip(move |_, cx| {
|
||||
Tooltip::for_action_in(tooltip_label, &ToggleFastMode, &focus_handle, cx)
|
||||
})
|
||||
.on_click(cx.listener(move |this, _, _window, cx| {
|
||||
this.toggle_fast_mode(cx);
|
||||
this.apply_fast_mode_speed(new_speed, cx);
|
||||
}))
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
|
||||
fn pending_fast_mode_confirmation(
|
||||
&self,
|
||||
cx: &App,
|
||||
) -> Option<(
|
||||
LanguageModelProviderId,
|
||||
LanguageModelId,
|
||||
FastModeConfirmation,
|
||||
)> {
|
||||
let thread = self.as_native_thread(cx)?.read(cx);
|
||||
let model = thread.model()?;
|
||||
let provider_id = model.provider_id();
|
||||
let model_id = model.id();
|
||||
let confirmation = LanguageModelRegistry::read_global(cx)
|
||||
.provider(&provider_id)
|
||||
.and_then(|provider| provider.fast_mode_confirmation(cx))?;
|
||||
if fast_mode_warning_dismissed(&provider_id, &model_id, cx) {
|
||||
return None;
|
||||
}
|
||||
Some((provider_id, model_id, confirmation))
|
||||
}
|
||||
|
||||
fn render_thinking_control(&self, cx: &mut Context<Self>) -> Option<AnyElement> {
|
||||
let thread = self.as_native_thread(cx)?.read(cx);
|
||||
let model = thread.model()?;
|
||||
|
|
@ -9495,18 +9608,34 @@ impl ThreadView {
|
|||
});
|
||||
}
|
||||
|
||||
fn toggle_fast_mode(&mut self, cx: &mut Context<Self>) {
|
||||
fn toggle_fast_mode(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if !self.fast_mode_available(cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(thread) = self.as_native_thread(cx) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let current_speed = thread.read(cx).speed().unwrap_or_default();
|
||||
let new_speed = current_speed.toggle();
|
||||
|
||||
if new_speed == Speed::Fast && self.pending_fast_mode_confirmation(cx).is_some() {
|
||||
let menu_handle = self.fast_mode_menu_handle.clone();
|
||||
window.defer(cx, move |window, cx| {
|
||||
menu_handle.toggle(window, cx);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
self.apply_fast_mode_speed(new_speed, cx);
|
||||
}
|
||||
|
||||
fn apply_fast_mode_speed(&mut self, new_speed: Speed, cx: &mut Context<Self>) {
|
||||
let Some(thread) = self.as_native_thread(cx) else {
|
||||
return;
|
||||
};
|
||||
thread.update(cx, |thread, cx| {
|
||||
let new_speed = thread
|
||||
.speed()
|
||||
.map(|speed| speed.toggle())
|
||||
.unwrap_or(Speed::Fast);
|
||||
thread.set_speed(new_speed, cx);
|
||||
|
||||
let favorite_key = thread
|
||||
|
|
@ -9652,8 +9781,8 @@ impl Render for ThreadView {
|
|||
.on_action(cx.listener(Self::scroll_output_to_bottom))
|
||||
.on_action(cx.listener(Self::scroll_output_to_previous_message))
|
||||
.on_action(cx.listener(Self::scroll_output_to_next_message))
|
||||
.on_action(cx.listener(|this, _: &ToggleFastMode, _window, cx| {
|
||||
this.toggle_fast_mode(cx);
|
||||
.on_action(cx.listener(|this, _: &ToggleFastMode, window, cx| {
|
||||
this.toggle_fast_mode(window, cx);
|
||||
}))
|
||||
.on_action(cx.listener(|this, _: &ToggleThinkingMode, _window, cx| {
|
||||
if this.thread.read(cx).status() != ThreadStatus::Idle {
|
||||
|
|
@ -9924,3 +10053,52 @@ pub(crate) fn open_link(
|
|||
cx.open_url(&url);
|
||||
}
|
||||
}
|
||||
|
||||
const FAST_MODE_WARNING_NAMESPACE: &str = "fast-mode-warning-dismissed";
|
||||
|
||||
fn fast_mode_warning_id(
|
||||
provider_id: &LanguageModelProviderId,
|
||||
model_id: &LanguageModelId,
|
||||
) -> String {
|
||||
format!("{}:{}", provider_id.0, model_id.0)
|
||||
}
|
||||
|
||||
fn fast_mode_warning_dismissed(
|
||||
provider_id: &LanguageModelProviderId,
|
||||
model_id: &LanguageModelId,
|
||||
cx: &App,
|
||||
) -> bool {
|
||||
KeyValueStore::global(cx)
|
||||
.scoped(FAST_MODE_WARNING_NAMESPACE)
|
||||
.read(&fast_mode_warning_id(provider_id, model_id))
|
||||
.log_err()
|
||||
.flatten()
|
||||
.is_some()
|
||||
}
|
||||
|
||||
fn set_fast_mode_warning_dismissed(
|
||||
provider_id: &LanguageModelProviderId,
|
||||
model_id: &LanguageModelId,
|
||||
cx: &mut App,
|
||||
) {
|
||||
let key = fast_mode_warning_id(provider_id, model_id);
|
||||
let kvp = KeyValueStore::global(cx);
|
||||
cx.background_spawn(async move {
|
||||
kvp.scoped(FAST_MODE_WARNING_NAMESPACE)
|
||||
.write(key, "1".to_string())
|
||||
.await
|
||||
.log_err();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
pub(crate) fn reset_fast_mode_warnings(cx: &mut App) {
|
||||
let kvp = KeyValueStore::global(cx);
|
||||
cx.background_spawn(async move {
|
||||
kvp.scoped(FAST_MODE_WARNING_NAMESPACE)
|
||||
.delete_all()
|
||||
.await
|
||||
.log_err();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,6 +289,20 @@ pub trait LanguageModelProvider: 'static {
|
|||
cx: &mut App,
|
||||
) -> AnyView;
|
||||
fn reset_credentials(&self, cx: &mut App) -> Task<Result<()>>;
|
||||
|
||||
/// Copy shown the first time a user enables fast mode for a model from
|
||||
/// this provider. Returning `None` skips the confirmation prompt and lets
|
||||
/// the toggle apply silently.
|
||||
fn fast_mode_confirmation(&self, _cx: &App) -> Option<FastModeConfirmation> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider-specific copy shown the first time a user enables fast mode.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FastModeConfirmation {
|
||||
pub title: SharedString,
|
||||
pub message: SharedString,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, PartialEq, Eq)]
|
||||
|
|
|
|||
|
|
@ -9,10 +9,11 @@ use gpui::{AnyView, App, AsyncApp, Context, Entity, Task, TaskExt};
|
|||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
ANTHROPIC_PROVIDER_ID, ANTHROPIC_PROVIDER_NAME, ApiKeyState, AuthenticateError,
|
||||
ConfigurationViewTargetAgent, EnvVar, IconOrSvg, LanguageModel, LanguageModelCompletionError,
|
||||
LanguageModelCompletionEvent, LanguageModelId, LanguageModelName, LanguageModelProvider,
|
||||
LanguageModelProviderId, LanguageModelProviderName, LanguageModelProviderState,
|
||||
LanguageModelRequest, LanguageModelToolChoice, RateLimiter, env_var,
|
||||
ConfigurationViewTargetAgent, EnvVar, FastModeConfirmation, IconOrSvg, LanguageModel,
|
||||
LanguageModelCompletionError, LanguageModelCompletionEvent, LanguageModelId, LanguageModelName,
|
||||
LanguageModelProvider, LanguageModelProviderId, LanguageModelProviderName,
|
||||
LanguageModelProviderState, LanguageModelRequest, LanguageModelToolChoice, RateLimiter,
|
||||
env_var,
|
||||
};
|
||||
use settings::{Settings, SettingsStore};
|
||||
use std::sync::{Arc, LazyLock};
|
||||
|
|
@ -275,6 +276,17 @@ impl LanguageModelProvider for AnthropicLanguageModelProvider {
|
|||
self.state
|
||||
.update(cx, |state, cx| state.set_api_key(None, cx))
|
||||
}
|
||||
|
||||
fn fast_mode_confirmation(&self, _cx: &App) -> Option<FastModeConfirmation> {
|
||||
Some(FastModeConfirmation {
|
||||
title: "Enable Fast Mode for Anthropic?".into(),
|
||||
message: "Fast mode lets requests use your Anthropic Priority Tier capacity, which \
|
||||
Anthropic prioritizes over standard requests during peak load. Requires a \
|
||||
Priority Tier commitment with Anthropic; without one, requests behave the same \
|
||||
as the standard tier."
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Pick the model from `models` whose id starts with the earliest matching
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ use futures::StreamExt;
|
|||
use futures::future::BoxFuture;
|
||||
use gpui::{AnyElement, AnyView, App, AppContext, Context, Entity, Subscription, Task, TaskExt};
|
||||
use language_model::{
|
||||
AuthenticateError, IconOrSvg, LanguageModel, LanguageModelProvider, LanguageModelProviderId,
|
||||
LanguageModelProviderName, LanguageModelProviderState, ZED_CLOUD_PROVIDER_ID,
|
||||
ZED_CLOUD_PROVIDER_NAME,
|
||||
AuthenticateError, FastModeConfirmation, IconOrSvg, LanguageModel, LanguageModelProvider,
|
||||
LanguageModelProviderId, LanguageModelProviderName, LanguageModelProviderState,
|
||||
ZED_CLOUD_PROVIDER_ID, ZED_CLOUD_PROVIDER_NAME,
|
||||
};
|
||||
use language_models_cloud::{CloudLlmTokenProvider, CloudModelProvider};
|
||||
use release_channel::AppVersion;
|
||||
|
|
@ -306,6 +306,16 @@ impl LanguageModelProvider for CloudLanguageModelProvider {
|
|||
fn reset_credentials(&self, _cx: &mut App) -> Task<Result<()>> {
|
||||
Task::ready(Ok(()))
|
||||
}
|
||||
|
||||
fn fast_mode_confirmation(&self, _cx: &App) -> Option<FastModeConfirmation> {
|
||||
Some(FastModeConfirmation {
|
||||
title: "Enable Fast Mode for Zed?".into(),
|
||||
message: "Fast mode routes requests through the upstream provider's fast mode or priority tier. The \
|
||||
upstream provider's premium per-token pricing applies and is passed through to \
|
||||
your Zed billing."
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(IntoElement, RegisterComponent)]
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ use futures::{FutureExt, StreamExt, future::BoxFuture};
|
|||
use gpui::{AnyView, App, AsyncApp, Context, Entity, SharedString, Task, TaskExt, Window};
|
||||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
ApiKeyState, AuthenticateError, EnvVar, IconOrSvg, LanguageModel, LanguageModelCompletionError,
|
||||
LanguageModelCompletionEvent, LanguageModelEffortLevel, LanguageModelId, LanguageModelName,
|
||||
LanguageModelProvider, LanguageModelProviderId, LanguageModelProviderName,
|
||||
LanguageModelProviderState, LanguageModelRequest, LanguageModelToolChoice, OPEN_AI_PROVIDER_ID,
|
||||
OPEN_AI_PROVIDER_NAME, RateLimiter, env_var,
|
||||
ApiKeyState, AuthenticateError, EnvVar, FastModeConfirmation, IconOrSvg, LanguageModel,
|
||||
LanguageModelCompletionError, LanguageModelCompletionEvent, LanguageModelEffortLevel,
|
||||
LanguageModelId, LanguageModelName, LanguageModelProvider, LanguageModelProviderId,
|
||||
LanguageModelProviderName, LanguageModelProviderState, LanguageModelRequest,
|
||||
LanguageModelToolChoice, OPEN_AI_PROVIDER_ID, OPEN_AI_PROVIDER_NAME, RateLimiter, env_var,
|
||||
};
|
||||
use menu;
|
||||
use open_ai::{
|
||||
|
|
@ -215,6 +215,16 @@ impl LanguageModelProvider for OpenAiLanguageModelProvider {
|
|||
self.state
|
||||
.update(cx, |state, cx| state.set_api_key(None, cx))
|
||||
}
|
||||
|
||||
fn fast_mode_confirmation(&self, _cx: &App) -> Option<FastModeConfirmation> {
|
||||
Some(FastModeConfirmation {
|
||||
title: "Enable Fast Mode for OpenAI?".into(),
|
||||
message: "Fast mode sends requests using OpenAI's Priority processing tier, which \
|
||||
targets significantly lower latency than the standard tier and is billed at a \
|
||||
premium per-token rate."
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn default_thinking_reasoning_effort(model: &open_ai::Model) -> Option<open_ai::ReasoningEffort> {
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@ use futures::{FutureExt, StreamExt, future::BoxFuture, future::Shared};
|
|||
use gpui::{AnyView, App, AsyncApp, Context, Entity, SharedString, Task, Window};
|
||||
use http_client::{AsyncBody, HttpClient, Method, Request as HttpRequest};
|
||||
use language_model::{
|
||||
AuthenticateError, IconOrSvg, LanguageModel, LanguageModelCompletionError,
|
||||
LanguageModelCompletionEvent, LanguageModelEffortLevel, LanguageModelId, LanguageModelName,
|
||||
LanguageModelProvider, LanguageModelProviderId, LanguageModelProviderName,
|
||||
LanguageModelProviderState, LanguageModelRequest, LanguageModelToolChoice, RateLimiter,
|
||||
AuthenticateError, FastModeConfirmation, IconOrSvg, LanguageModel,
|
||||
LanguageModelCompletionError, LanguageModelCompletionEvent, LanguageModelEffortLevel,
|
||||
LanguageModelId, LanguageModelName, LanguageModelProvider, LanguageModelProviderId,
|
||||
LanguageModelProviderName, LanguageModelProviderState, LanguageModelRequest,
|
||||
LanguageModelToolChoice, RateLimiter,
|
||||
};
|
||||
use open_ai::{ReasoningEffort, responses::stream_response};
|
||||
use rand::RngCore as _;
|
||||
|
|
@ -251,6 +252,16 @@ impl LanguageModelProvider for OpenAiSubscribedProvider {
|
|||
fn reset_credentials(&self, cx: &mut App) -> Task<Result<()>> {
|
||||
self.sign_out(cx)
|
||||
}
|
||||
|
||||
fn fast_mode_confirmation(&self, _cx: &App) -> Option<FastModeConfirmation> {
|
||||
Some(FastModeConfirmation {
|
||||
title: "Enable Fast Mode for OpenAI?".into(),
|
||||
message: "Fast mode sends requests using OpenAI's Priority processing tier, which \
|
||||
targets significantly lower latency than the standard tier and is billed at a \
|
||||
premium per-token rate."
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
Loading…
Reference in a new issue