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 {
Bot,
BotMessageSquare,
Eye,
EyeOff,
Globe,
Copy,
Loader,
FileText,
Save,
FilePenLine,
RotateCcw,
Settings,
RefreshCcw,
Globe,
Copy
} 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';
interface Props {
@@ -68,10 +68,11 @@ if (maxTokens === undefined) maxTokens = 512;
if (temperature === undefined) temperature = 0.7;
// Internal State
let ae_promises: any = $state(null);
let ae_promises = $state<Promise<unknown> | null>(null);
let show_modal = $state(false);
let active_tab: 'result' | 'settings' = $state('result');
let tmp_summary = $state('');
let show_api_token = $state(false);
async function generate_ai_result() {
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 (!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) => {
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}`;
@@ -121,10 +124,13 @@ async function generate_ai_result() {
tmp_summary = result;
show_modal = true;
});
} catch (err: any) {
console.error('AE_AITools: AI Error:', err);
} catch (err: unknown) {
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
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;
ae_promises = Promise.resolve();
}
@@ -162,7 +168,7 @@ function handle_save() {
active_tab = 'settings';
show_modal = true;
}}
class="btn btn-sm variant-soft-surface shadow-md"
class="btn btn-sm preset-tonal-surface shadow-md"
title="AI Settings">
<Settings size="1.2em" />
</button>
@@ -173,21 +179,21 @@ function handle_save() {
title="Aether AI Assistant"
bind:open={show_modal}
size="lg"
class="bg-white dark:bg-gray-800">
class="bg-surface-50-900">
<div class="space-y-4 p-2">
<!-- Tab Navigation -->
<div class="border-surface-500/20 flex gap-1 border-b pb-2">
<button
class="btn btn-sm {active_tab === 'result'
? 'variant-filled-primary'
: 'variant-soft-surface'}"
? 'preset-filled-primary'
: 'preset-tonal-surface'}"
onclick={() => (active_tab = 'result')}>
<Bot size="1.1em" class="mr-1" /> Result
</button>
<button
class="btn btn-sm {active_tab === 'settings'
? 'variant-filled-secondary'
: 'variant-soft-surface'}"
? 'preset-filled-secondary'
: 'preset-tonal-surface'}"
onclick={() => (active_tab = 'settings')}>
<Settings size="1.1em" class="mr-1" /> Settings
</button>
@@ -197,12 +203,12 @@ function handle_save() {
<div class="animate-in fade-in space-y-4 duration-200">
<div class="flex justify-start gap-2">
<button
class="btn btn-sm variant-filled-success"
class="btn btn-sm preset-filled-success"
onclick={handle_save}>
<Save size="1.1em" class="mr-1" /> Save Result
</button>
<button
class="btn btn-sm variant-ghost-primary"
class="btn btn-sm preset-tonal-primary"
onclick={generate_ai_result}>
<RotateCcw size="1.1em" class="mr-1" /> Re-run
</button>
@@ -227,7 +233,7 @@ function handle_save() {
{#if onSyncConfig}
<button
class="btn btn-sm variant-soft-primary"
class="btn btn-sm preset-tonal-primary"
onclick={onSyncConfig}>
<Copy size="1.1em" class="mr-1" /> Sync Global
Defaults
@@ -239,6 +245,10 @@ function handle_save() {
<span>Base URL</span>
<input
type="text"
autocomplete="off"
autocapitalize="off"
autocorrect="off"
spellcheck="false"
bind:value={baseUrl}
class="input input-sm" />
</label>
@@ -246,16 +256,48 @@ function handle_save() {
<span>Model</span>
<input
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}
class="input input-sm" />
</label>
</div>
<label class="label">
<span>API Token</span>
<input
type="password"
bind:value={token}
class="input input-sm font-mono" />
<div class="flex gap-2">
<input
type={show_api_token ? 'text' : 'password'}
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>
</div>