mirror of
https://github.com/aldo-g/obsidian-llm-test.git
synced 2026-07-22 05:42:19 +00:00
fix: all providers now working
This commit is contained in:
parent
72772a2041
commit
a3b33f7cf4
2 changed files with 57 additions and 43 deletions
|
|
@ -438,7 +438,9 @@ async function callGemini(
|
|||
const modelEndpoint = model === "gemini-pro" ? "gemini-pro" : model;
|
||||
const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/${modelEndpoint}:generateContent?key=${apiKey}`;
|
||||
|
||||
const requestBody = {
|
||||
const isModernGemini = model.includes("1.5") || model.includes("gemini-3") || model.includes("gemini-2");
|
||||
|
||||
const requestBody: any = {
|
||||
contents: [
|
||||
{
|
||||
parts: [
|
||||
|
|
@ -447,11 +449,15 @@ async function callGemini(
|
|||
}
|
||||
],
|
||||
generationConfig: {
|
||||
maxOutputTokens: maxTokens,
|
||||
maxOutputTokens: Math.max(maxTokens, 2048),
|
||||
temperature: 0.7
|
||||
}
|
||||
};
|
||||
|
||||
if (isModernGemini) {
|
||||
requestBody.generationConfig.responseMimeType = "application/json";
|
||||
}
|
||||
|
||||
const response = await requestUrl({
|
||||
url: apiUrl,
|
||||
method: "POST",
|
||||
|
|
@ -657,7 +663,30 @@ export async function fetchProviderModels(
|
|||
});
|
||||
const data = response.json;
|
||||
return data.models
|
||||
.filter((m: any) => m.supportedGenerationMethods.includes("generateContent"))
|
||||
.filter((m: any) => {
|
||||
const id = m.name.toLowerCase();
|
||||
const displayName = (m.displayName || "").toLowerCase();
|
||||
|
||||
// 1. Must support content generation
|
||||
if (!m.supportedGenerationMethods.includes("generateContent")) return false;
|
||||
|
||||
// 2. EXCLUDE specialized/incompatible models
|
||||
const isSpecialized =
|
||||
id.includes("nano") || displayName.includes("nano") ||
|
||||
id.includes("robotics") || displayName.includes("robotics") ||
|
||||
id.includes("computer use") || displayName.includes("computer use") ||
|
||||
id.includes("deep research") || displayName.includes("deep research") ||
|
||||
id.includes("aqa") || displayName.includes("aqa") ||
|
||||
id.includes("experimental") || id.includes("exp") && !id.includes("flash") && !id.includes("pro"); // Keep Pro/Flash exp
|
||||
|
||||
if (isSpecialized) return false;
|
||||
|
||||
// 3. ONLY keep Gemini and Gemma models
|
||||
const isTargetFamily = id.includes("gemini") || id.includes("gemma");
|
||||
if (!isTargetFamily) return false;
|
||||
|
||||
return true;
|
||||
})
|
||||
.map((m: any) => ({
|
||||
id: m.name.replace("models/", ""),
|
||||
name: m.displayName || m.name.replace("models/", "")
|
||||
|
|
@ -670,7 +699,23 @@ export async function fetchProviderModels(
|
|||
});
|
||||
const data = response.json;
|
||||
return data.data
|
||||
.filter((m: any) => !m.id.includes("embed") && !m.id.includes("moderation"))
|
||||
.filter((m: any) => {
|
||||
const id = m.id.toLowerCase();
|
||||
|
||||
// 1. MUST exclude known utility/non-chat models
|
||||
if (id.includes("embed") || id.includes("moderation") || id.includes("vibe-cli")) return false;
|
||||
|
||||
// 2. EXCLUDE experimental/developer/internal models
|
||||
if (id.includes("devstral") || id.includes("magistral") || id.includes("labs-")) return false;
|
||||
|
||||
// 3. CLEAN UP dated versions
|
||||
// Many Mistral models have both a 'latest' and a dated version (e.g. -2411, -2501).
|
||||
// We favor 'latest' tags and primary model names for a cleaner list.
|
||||
const isDated = /-\d{4}$/.test(id);
|
||||
if (isDated && !id.includes("pixtral") && !id.includes("codestral")) return false;
|
||||
|
||||
return true;
|
||||
})
|
||||
.map((m: any) => ({ id: m.id, name: m.id }));
|
||||
}
|
||||
case "ollama": {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import { fetchProviderModels, fetchCommunityModels } from "../services/llm";
|
|||
export default class SettingsTab extends PluginSettingTab {
|
||||
plugin: MyPlugin;
|
||||
fetchedModels: Record<string, Array<{ id: string; name: string }>> = {};
|
||||
modelFilter: string = "";
|
||||
|
||||
static readonly CORE_MODELS: Record<string, Array<{ id: string; name: string }>> = {
|
||||
openai: [
|
||||
|
|
@ -33,6 +32,8 @@ export default class SettingsTab extends PluginSettingTab {
|
|||
{ id: "deepseek-coder", name: "DeepSeek Coder" }
|
||||
],
|
||||
gemini: [
|
||||
{ id: "gemini-3-flash-preview", name: "Gemini 3 Flash (Preview)" },
|
||||
{ id: "gemini-2.0-flash-exp", name: "Gemini 2.0 Flash (Experimental)" },
|
||||
{ id: "gemini-1.5-pro", name: "Gemini 1.5 Pro" },
|
||||
{ id: "gemini-1.5-flash", name: "Gemini 1.5 Flash" },
|
||||
{ id: "gemini-1.5-flash-8b", name: "Gemini 1.5 Flash-8B" },
|
||||
|
|
@ -62,11 +63,12 @@ export default class SettingsTab extends PluginSettingTab {
|
|||
.addDropdown((dropdown: DropdownComponent) => {
|
||||
dropdown
|
||||
.addOption("openai", "OpenAI")
|
||||
.addOption("anthropic", "Anthropic (Claude)")
|
||||
.addOption("deepseek", "DeepSeek")
|
||||
.addOption("gemini", "Google (Gemini)")
|
||||
.addOption("mistral", "Mistral AI")
|
||||
.addOption("ollama", "Ollama (Local)")
|
||||
.setValue(this.plugin.settings.llmProvider === "anthropic" ? "openai" : this.plugin.settings.llmProvider)
|
||||
.setValue(this.plugin.settings.llmProvider)
|
||||
.onChange(async (value: LLMProvider) => {
|
||||
this.plugin.settings.llmProvider = value;
|
||||
await this.plugin.saveSettings();
|
||||
|
|
@ -79,33 +81,11 @@ export default class SettingsTab extends PluginSettingTab {
|
|||
const provider = this.plugin.settings.llmProvider;
|
||||
const apiKey = this.plugin.settings.apiKeys[provider];
|
||||
|
||||
// Model Filter
|
||||
new Setting(containerEl)
|
||||
.setName("Filter models")
|
||||
.setDesc("Type to filter the available models list")
|
||||
.addSearch((search) => {
|
||||
search
|
||||
.setPlaceholder("Filter models...")
|
||||
.setValue(this.modelFilter)
|
||||
.onChange((value) => {
|
||||
this.modelFilter = value.toLowerCase();
|
||||
this.display();
|
||||
});
|
||||
})
|
||||
.addExtraButton((button) => {
|
||||
button
|
||||
.setIcon("x-circle")
|
||||
.setTooltip("Clear filter")
|
||||
.onClick(() => {
|
||||
this.modelFilter = "";
|
||||
this.display();
|
||||
});
|
||||
});
|
||||
|
||||
// Model selection
|
||||
const modelSetting = new Setting(containerEl)
|
||||
.setName(`${provider.charAt(0).toUpperCase() + provider.slice(1)} model`)
|
||||
.setDesc(`Select which ${provider} model to use`);
|
||||
.setDesc(`Select which ${provider} model to use. Save your API key and refresh to get latest models. Warning: not all models are compatible with this plugin.`);
|
||||
|
||||
modelSetting.addDropdown(async (dropdown: DropdownComponent) => {
|
||||
const currentModel = this.plugin.settings.models[provider];
|
||||
|
|
@ -122,22 +102,11 @@ export default class SettingsTab extends PluginSettingTab {
|
|||
modelMap.set(currentModel, currentModel);
|
||||
}
|
||||
|
||||
// Apply filter
|
||||
let visibleModelsCount = 0;
|
||||
modelMap.forEach((name, id) => {
|
||||
if (!this.modelFilter || id.toLowerCase().includes(this.modelFilter) || name.toLowerCase().includes(this.modelFilter)) {
|
||||
dropdown.addOption(id, name);
|
||||
visibleModelsCount++;
|
||||
}
|
||||
dropdown.addOption(id, name);
|
||||
});
|
||||
|
||||
if (visibleModelsCount === 0 && this.modelFilter) {
|
||||
dropdown.addOption("", "No models match filter");
|
||||
dropdown.setDisabled(true);
|
||||
} else {
|
||||
dropdown.setDisabled(false);
|
||||
dropdown.setValue(currentModel);
|
||||
}
|
||||
dropdown.setValue(currentModel);
|
||||
|
||||
// Auto-fetch in background if we have an API key and haven't fetched yet
|
||||
if (fetched.length === 0 && apiKey) {
|
||||
|
|
@ -264,7 +233,7 @@ export default class SettingsTab extends PluginSettingTab {
|
|||
// Model selection
|
||||
new Setting(containerEl)
|
||||
.setName("Ollama model")
|
||||
.setDesc("Enter the name of the Ollama model to use")
|
||||
.setDesc("Enter the name of the Ollama model to use. Some models may not be compatible with this plugin.")
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("llama3")
|
||||
|
|
|
|||
Loading…
Reference in a new issue