Modernize AI tools token input
This commit is contained in:
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user