feat(assistant): add multi-dialog UX, task-aware llm settings, and i18n cleanup
This commit is contained in:
@@ -28,6 +28,11 @@
|
||||
git_commit_prompt:
|
||||
"Generate a concise and professional git commit message based on the following diff and recent history.\\nUse Conventional Commits format (e.g., feat: ..., fix: ..., docs: ...).\\n\\nRecent History:\\n{history}\\n\\nDiff:\\n{diff}\\n\\nCommit Message:",
|
||||
};
|
||||
const DEFAULT_LLM_PROVIDER_BINDINGS = {
|
||||
dashboard_validation: "",
|
||||
documentation: "",
|
||||
git_commit: "",
|
||||
};
|
||||
|
||||
// State
|
||||
let activeTab = "environments";
|
||||
@@ -77,15 +82,50 @@
|
||||
providers: [],
|
||||
default_provider: "",
|
||||
prompts: { ...DEFAULT_LLM_PROMPTS },
|
||||
provider_bindings: { ...DEFAULT_LLM_PROVIDER_BINDINGS },
|
||||
assistant_planner_provider: "",
|
||||
assistant_planner_model: "",
|
||||
...(llm || {}),
|
||||
};
|
||||
normalized.prompts = {
|
||||
...DEFAULT_LLM_PROMPTS,
|
||||
...(llm?.prompts || {}),
|
||||
};
|
||||
normalized.provider_bindings = {
|
||||
...DEFAULT_LLM_PROVIDER_BINDINGS,
|
||||
...(llm?.provider_bindings || {}),
|
||||
};
|
||||
normalized.assistant_planner_provider = llm?.assistant_planner_provider || "";
|
||||
normalized.assistant_planner_model = llm?.assistant_planner_model || "";
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function isMultimodalModel(modelName) {
|
||||
const token = (modelName || "").toLowerCase();
|
||||
if (!token) return false;
|
||||
return (
|
||||
token.includes("gpt-4o") ||
|
||||
token.includes("gpt-4.1") ||
|
||||
token.includes("vision") ||
|
||||
token.includes("vl") ||
|
||||
token.includes("gemini") ||
|
||||
token.includes("claude-3") ||
|
||||
token.includes("claude-sonnet-4")
|
||||
);
|
||||
}
|
||||
|
||||
function getProviderById(providerId) {
|
||||
if (!providerId) return null;
|
||||
return (settings?.llm_providers || []).find((p) => p.id === providerId) || null;
|
||||
}
|
||||
|
||||
function isDashboardValidationBindingValid() {
|
||||
const providerId = settings?.llm?.provider_bindings?.dashboard_validation;
|
||||
if (!providerId) return true;
|
||||
const provider = getProviderById(providerId);
|
||||
return provider ? isMultimodalModel(provider.default_model) : true;
|
||||
}
|
||||
|
||||
// Handle tab change
|
||||
function handleTabChange(tab) {
|
||||
activeTab = tab;
|
||||
@@ -670,6 +710,121 @@
|
||||
onSave={loadSettings}
|
||||
/>
|
||||
|
||||
<div class="mt-6 rounded-lg border border-gray-200 bg-white p-4">
|
||||
<h3 class="text-base font-semibold text-gray-900">
|
||||
{$t.settings?.llm_chatbot_settings_title || "Chatbot Planner Settings"}
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-gray-600">
|
||||
{$t.settings?.llm_chatbot_settings_description ||
|
||||
"Select provider and optional model override for assistant intent planning."}
|
||||
</p>
|
||||
|
||||
<div class="mt-4 grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div>
|
||||
<label for="planner-provider" class="block text-sm font-medium text-gray-700">
|
||||
{$t.settings?.llm_chatbot_provider || "Chatbot Provider"}
|
||||
</label>
|
||||
<select
|
||||
id="planner-provider"
|
||||
bind:value={settings.llm.assistant_planner_provider}
|
||||
class="mt-1 block w-full rounded-md border border-gray-300 p-2 text-sm"
|
||||
>
|
||||
<option value="">{$t.dashboard?.use_default || "Use Default"}</option>
|
||||
{#each settings.llm_providers || [] as provider}
|
||||
<option value={provider.id}>
|
||||
{provider.name} ({provider.default_model})
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="planner-model" class="block text-sm font-medium text-gray-700">
|
||||
{$t.settings?.llm_chatbot_model || "Chatbot Model Override"}
|
||||
</label>
|
||||
<input
|
||||
id="planner-model"
|
||||
type="text"
|
||||
bind:value={settings.llm.assistant_planner_model}
|
||||
placeholder={$t.settings?.llm_chatbot_model_placeholder || "Optional, e.g. gpt-4.1-mini"}
|
||||
class="mt-1 block w-full rounded-md border border-gray-300 p-2 text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 rounded-lg border border-gray-200 bg-white p-4">
|
||||
<h3 class="text-base font-semibold text-gray-900">
|
||||
{$t.settings?.llm_provider_bindings_title || "Provider Bindings by Task"}
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-gray-600">
|
||||
{$t.settings?.llm_provider_bindings_description ||
|
||||
"Select which provider is used by default for each LLM task."}
|
||||
</p>
|
||||
|
||||
<div class="mt-4 grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div>
|
||||
<label for="binding-dashboard-validation" class="block text-sm font-medium text-gray-700">
|
||||
{$t.settings?.llm_binding_dashboard_validation || "Dashboard Validation Provider"}
|
||||
</label>
|
||||
<select
|
||||
id="binding-dashboard-validation"
|
||||
bind:value={settings.llm.provider_bindings.dashboard_validation}
|
||||
class="mt-1 block w-full rounded-md border border-gray-300 p-2 text-sm"
|
||||
>
|
||||
<option value="">{$t.dashboard?.use_default || "Use Default"}</option>
|
||||
{#each settings.llm_providers || [] as provider}
|
||||
<option value={provider.id}>
|
||||
{provider.name} ({provider.default_model})
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
{#if !isDashboardValidationBindingValid()}
|
||||
<p class="mt-1 text-xs text-amber-700">
|
||||
{$t.settings?.llm_multimodal_warning ||
|
||||
"Dashboard validation requires a multimodal model (image input)."}
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="binding-documentation" class="block text-sm font-medium text-gray-700">
|
||||
{$t.settings?.llm_binding_documentation || "Documentation Provider"}
|
||||
</label>
|
||||
<select
|
||||
id="binding-documentation"
|
||||
bind:value={settings.llm.provider_bindings.documentation}
|
||||
class="mt-1 block w-full rounded-md border border-gray-300 p-2 text-sm"
|
||||
>
|
||||
<option value="">{$t.dashboard?.use_default || "Use Default"}</option>
|
||||
{#each settings.llm_providers || [] as provider}
|
||||
<option value={provider.id}>
|
||||
{provider.name} ({provider.default_model})
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="md:col-span-2">
|
||||
<label for="binding-git-commit" class="block text-sm font-medium text-gray-700">
|
||||
{$t.settings?.llm_binding_git_commit || "Git Commit Provider"}
|
||||
</label>
|
||||
<select
|
||||
id="binding-git-commit"
|
||||
bind:value={settings.llm.provider_bindings.git_commit}
|
||||
class="mt-1 block w-full rounded-md border border-gray-300 p-2 text-sm"
|
||||
>
|
||||
<option value="">{$t.dashboard?.use_default || "Use Default"}</option>
|
||||
{#each settings.llm_providers || [] as provider}
|
||||
<option value={provider.id}>
|
||||
{provider.name} ({provider.default_model})
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 rounded-lg border border-gray-200 bg-gray-50 p-4">
|
||||
<h3 class="text-base font-semibold text-gray-900">
|
||||
{$t.settings?.llm_prompts_title || "LLM Prompt Templates"}
|
||||
|
||||
Reference in New Issue
Block a user