Modernize AI tools token input

This commit is contained in:
Scott Idem
2026-05-05 13:33:40 -04:00
parent 20d8a6975d
commit 146682a30b

View File

@@ -9,17 +9,17 @@ import { Modal } from 'flowbite-svelte';
import { import {
Bot, Bot,
BotMessageSquare, BotMessageSquare,
Eye,
EyeOff,
Globe,
Copy,
Loader, Loader,
FileText,
Save, Save,
FilePenLine, FilePenLine,
RotateCcw, RotateCcw,
Settings, Settings,
RefreshCcw,
Globe,
Copy
} from '@lucide/svelte'; } from '@lucide/svelte';
import { ae_loc, ae_api } from '$lib/stores/ae_stores'; import { ae_loc } from '$lib/stores/ae_stores';
import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte'; import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte';
interface Props { interface Props {
@@ -68,10 +68,11 @@ if (maxTokens === undefined) maxTokens = 512;
if (temperature === undefined) temperature = 0.7; if (temperature === undefined) temperature = 0.7;
// Internal State // Internal State
let ae_promises: any = $state(null); let ae_promises = $state<Promise<unknown> | null>(null);
let show_modal = $state(false); let show_modal = $state(false);
let active_tab: 'result' | 'settings' = $state('result'); let active_tab: 'result' | 'settings' = $state('result');
let tmp_summary = $state(''); let tmp_summary = $state('');
let show_api_token = $state(false);
async function generate_ai_result() { async function generate_ai_result() {
if (!content) { if (!content) {
@@ -83,7 +84,9 @@ async function generate_ai_result() {
// If no token is provided, trigger a "Demo Mode" placeholder after a fake delay // If no token is provided, trigger a "Demo Mode" placeholder after a fake delay
if (!token || token === '') { if (!token || token === '') {
console.log('AE_AITools: No token provided. Entering Demo Mode.'); if (log_lvl > 0) {
console.log('AE_AITools: No token provided. Entering Demo Mode.');
}
ae_promises = new Promise((resolve) => { ae_promises = new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
tmp_summary = `### AI Summary (DEMO MODE)\n\nThis is a placeholder summary because no API token was provided in the settings. \n\n**Original Content Length:** ${content.length} characters.\n\n**System Prompt:** ${systemPrompt}\n\n**Model:** ${model}`; tmp_summary = `### AI Summary (DEMO MODE)\n\nThis is a placeholder summary because no API token was provided in the settings. \n\n**Original Content Length:** ${content.length} characters.\n\n**System Prompt:** ${systemPrompt}\n\n**Model:** ${model}`;
@@ -121,10 +124,13 @@ async function generate_ai_result() {
tmp_summary = result; tmp_summary = result;
show_modal = true; show_modal = true;
}); });
} catch (err: any) { } catch (err: unknown) {
console.error('AE_AITools: AI Error:', err); if (log_lvl > 0) {
console.error('AE_AITools: AI Error:', err);
}
const err_msg = err instanceof Error ? err.message : String(err);
// Even on error, show the modal with the error message so the UI can be inspected // Even on error, show the modal with the error message so the UI can be inspected
tmp_summary = `### AI Error\n\nFailed to connect to the AI service.\n\n**Error:** ${err.message}\n\nCheck your Settings tab for Base URL and Token configuration.`; tmp_summary = `### AI Error\n\nFailed to connect to the AI service.\n\n**Error:** ${err_msg}\n\nCheck your Settings tab for Base URL and Token configuration.`;
show_modal = true; show_modal = true;
ae_promises = Promise.resolve(); ae_promises = Promise.resolve();
} }
@@ -162,7 +168,7 @@ function handle_save() {
active_tab = 'settings'; active_tab = 'settings';
show_modal = true; show_modal = true;
}} }}
class="btn btn-sm variant-soft-surface shadow-md" class="btn btn-sm preset-tonal-surface shadow-md"
title="AI Settings"> title="AI Settings">
<Settings size="1.2em" /> <Settings size="1.2em" />
</button> </button>
@@ -173,21 +179,21 @@ function handle_save() {
title="Aether AI Assistant" title="Aether AI Assistant"
bind:open={show_modal} bind:open={show_modal}
size="lg" size="lg"
class="bg-white dark:bg-gray-800"> class="bg-surface-50-900">
<div class="space-y-4 p-2"> <div class="space-y-4 p-2">
<!-- Tab Navigation --> <!-- Tab Navigation -->
<div class="border-surface-500/20 flex gap-1 border-b pb-2"> <div class="border-surface-500/20 flex gap-1 border-b pb-2">
<button <button
class="btn btn-sm {active_tab === 'result' class="btn btn-sm {active_tab === 'result'
? 'variant-filled-primary' ? 'preset-filled-primary'
: 'variant-soft-surface'}" : 'preset-tonal-surface'}"
onclick={() => (active_tab = 'result')}> onclick={() => (active_tab = 'result')}>
<Bot size="1.1em" class="mr-1" /> Result <Bot size="1.1em" class="mr-1" /> Result
</button> </button>
<button <button
class="btn btn-sm {active_tab === 'settings' class="btn btn-sm {active_tab === 'settings'
? 'variant-filled-secondary' ? 'preset-filled-secondary'
: 'variant-soft-surface'}" : 'preset-tonal-surface'}"
onclick={() => (active_tab = 'settings')}> onclick={() => (active_tab = 'settings')}>
<Settings size="1.1em" class="mr-1" /> Settings <Settings size="1.1em" class="mr-1" /> Settings
</button> </button>
@@ -197,12 +203,12 @@ function handle_save() {
<div class="animate-in fade-in space-y-4 duration-200"> <div class="animate-in fade-in space-y-4 duration-200">
<div class="flex justify-start gap-2"> <div class="flex justify-start gap-2">
<button <button
class="btn btn-sm variant-filled-success" class="btn btn-sm preset-filled-success"
onclick={handle_save}> onclick={handle_save}>
<Save size="1.1em" class="mr-1" /> Save Result <Save size="1.1em" class="mr-1" /> Save Result
</button> </button>
<button <button
class="btn btn-sm variant-ghost-primary" class="btn btn-sm preset-tonal-primary"
onclick={generate_ai_result}> onclick={generate_ai_result}>
<RotateCcw size="1.1em" class="mr-1" /> Re-run <RotateCcw size="1.1em" class="mr-1" /> Re-run
</button> </button>
@@ -227,7 +233,7 @@ function handle_save() {
{#if onSyncConfig} {#if onSyncConfig}
<button <button
class="btn btn-sm variant-soft-primary" class="btn btn-sm preset-tonal-primary"
onclick={onSyncConfig}> onclick={onSyncConfig}>
<Copy size="1.1em" class="mr-1" /> Sync Global <Copy size="1.1em" class="mr-1" /> Sync Global
Defaults Defaults
@@ -239,6 +245,10 @@ function handle_save() {
<span>Base URL</span> <span>Base URL</span>
<input <input
type="text" type="text"
autocomplete="off"
autocapitalize="off"
autocorrect="off"
spellcheck="false"
bind:value={baseUrl} bind:value={baseUrl}
class="input input-sm" /> class="input input-sm" />
</label> </label>
@@ -246,16 +256,48 @@ function handle_save() {
<span>Model</span> <span>Model</span>
<input <input
type="text" type="text"
autocomplete="off"
autocapitalize="off"
autocorrect="off"
spellcheck="false"
name="ai_model"
data-bwignore="true"
data-lpignore="true"
data-1p-ignore="true"
bind:value={model} bind:value={model}
class="input input-sm" /> class="input input-sm" />
</label> </label>
</div> </div>
<label class="label"> <label class="label">
<span>API Token</span> <span>API Token</span>
<input <div class="flex gap-2">
type="password" <input
bind:value={token} type={show_api_token ? 'text' : 'password'}
class="input input-sm font-mono" /> autocomplete="off"
autocapitalize="off"
autocorrect="off"
spellcheck="false"
name="ai_api_token"
data-bwignore="true"
data-lpignore="true"
data-1p-ignore="true"
bind:value={token}
class="input input-sm font-mono" />
<button
type="button"
class="btn btn-sm preset-tonal-surface"
onclick={() =>
(show_api_token = !show_api_token)}
title={show_api_token
? 'Hide API Token'
: 'Show API Token'}>
{#if show_api_token}
<EyeOff size="1.1em" />
{:else}
<Eye size="1.1em" />
{/if}
</button>
</div>
</label> </label>
</div> </div>