Improve Ollama tool use (#30120)

<img width="458" alt="Screenshot 2025-05-07 at 9 37 39 AM"
src="https://github.com/user-attachments/assets/80f8a9b8-6a13-4e84-b91d-140e11475638"
/>

<img width="603" alt="Screenshot 2025-05-07 at 9 37 33 AM"
src="https://github.com/user-attachments/assets/7fe67a68-3885-4a0e-a282-aad37e92068b"
/>


Release Notes:

- Ollama models no longer require the supports_tools field in settings
(defaults to false)

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
Richard Feldman 2025-05-07 11:37:06 -04:00 committed by Joseph T. Lyons
parent b5c6567924
commit 3f96f70475
4 changed files with 44 additions and 39 deletions

View File

@ -156,46 +156,47 @@ impl Render for ProfileSelector {
.default_model()
.map_or(false, |default| default.model.supports_tools());
let this = cx.entity().clone();
let focus_handle = self.focus_handle.clone();
let trigger_button = if supports_tools {
Button::new("profile-selector-model", selected_profile)
if supports_tools {
let this = cx.entity().clone();
let focus_handle = self.focus_handle.clone();
let trigger_button = Button::new("profile-selector-model", selected_profile)
.label_size(LabelSize::Small)
.color(Color::Muted)
.icon(IconName::ChevronDown)
.icon_size(IconSize::XSmall)
.icon_position(IconPosition::End)
.icon_color(Color::Muted)
.icon_color(Color::Muted);
PopoverMenu::new("profile-selector")
.trigger_with_tooltip(trigger_button, {
let focus_handle = focus_handle.clone();
move |window, cx| {
Tooltip::for_action_in(
"Toggle Profile Menu",
&ToggleProfileSelector,
&focus_handle,
window,
cx,
)
}
})
.anchor(if self.documentation_side == DocumentationSide::Left {
gpui::Corner::BottomRight
} else {
gpui::Corner::BottomLeft
})
.with_handle(self.menu_handle.clone())
.menu(move |window, cx| {
Some(this.update(cx, |this, cx| this.build_context_menu(window, cx)))
})
.into_any_element()
} else {
Button::new("tools-not-supported-button", "No Tools")
Button::new("tools-not-supported-button", "Tools Unsupported")
.disabled(true)
.label_size(LabelSize::Small)
.color(Color::Muted)
.tooltip(Tooltip::text("The current model does not support tools."))
};
PopoverMenu::new("profile-selector")
.trigger_with_tooltip(trigger_button, {
let focus_handle = focus_handle.clone();
move |window, cx| {
Tooltip::for_action_in(
"Toggle Profile Menu",
&ToggleProfileSelector,
&focus_handle,
window,
cx,
)
}
})
.anchor(if self.documentation_side == DocumentationSide::Left {
gpui::Corner::BottomRight
} else {
gpui::Corner::BottomLeft
})
.with_handle(self.menu_handle.clone())
.menu(move |window, cx| {
Some(this.update(cx, |this, cx| this.build_context_menu(window, cx)))
})
.tooltip(Tooltip::text("This model does not support tools."))
.into_any_element()
}
}
}

View File

@ -366,7 +366,7 @@ impl AssistantSettingsContent {
&model,
None,
None,
language_model.supports_tools(),
Some(language_model.supports_tools()),
)),
api_url,
});

View File

@ -52,7 +52,7 @@ pub struct AvailableModel {
/// The number of seconds to keep the connection open after the last request
pub keep_alive: Option<KeepAlive>,
/// Whether the model supports tools
pub supports_tools: bool,
pub supports_tools: Option<bool>,
}
pub struct OllamaLanguageModelProvider {
@ -93,8 +93,12 @@ impl State {
async move {
let name = model.name.as_str();
let capabilities = show_model(http_client.as_ref(), &api_url, name).await?;
let ollama_model =
ollama::Model::new(name, None, None, capabilities.supports_tools());
let ollama_model = ollama::Model::new(
name,
None,
None,
Some(capabilities.supports_tools()),
);
Ok(ollama_model)
}
});
@ -317,7 +321,7 @@ impl LanguageModel for OllamaLanguageModel {
}
fn supports_tools(&self) -> bool {
self.model.supports_tools
self.model.supports_tools.unwrap_or(false)
}
fn telemetry_id(&self) -> String {

View File

@ -37,7 +37,7 @@ pub struct Model {
pub display_name: Option<String>,
pub max_tokens: usize,
pub keep_alive: Option<KeepAlive>,
pub supports_tools: bool,
pub supports_tools: Option<bool>,
}
fn get_max_tokens(name: &str) -> usize {
@ -67,7 +67,7 @@ impl Model {
name: &str,
display_name: Option<&str>,
max_tokens: Option<usize>,
supports_tools: bool,
supports_tools: Option<bool>,
) -> Self {
Self {
name: name.to_owned(),