From 51bdad9485df2dfbf3d4d4f1d746a8bcfc746772 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Thu, 8 Jan 2026 18:12:15 -0500 Subject: [PATCH] Centralize AI configuration into generic AE_AITools component - Enhanced AE_AITools with a Settings tab for model, prompt, and parameter configuration. - Connected AE_AITools to Journals state via two-way bindings for persistent configuration. - Removed redundant AI settings from Journals config modal. - Standardized Svelte 5 patterns for cross-module component configuration. --- src/lib/ae_elements/AE_AITools.svelte | 155 +++++++++++++----- .../ae_comp__journal_entry_obj_id_view.svelte | 16 +- .../journals/modal_journals_config.svelte | 125 -------------- 3 files changed, 123 insertions(+), 173 deletions(-) diff --git a/src/lib/ae_elements/AE_AITools.svelte b/src/lib/ae_elements/AE_AITools.svelte index 4c762b3e..953c71cd 100644 --- a/src/lib/ae_elements/AE_AITools.svelte +++ b/src/lib/ae_elements/AE_AITools.svelte @@ -2,13 +2,14 @@ /** * AE_AITools.svelte * GENERIC Aether AI Toolset (Runes/Svelte 5) - * Reusable across all modules (Journals, Events, People, etc.) + * Extracted logic from Journals module to be system-wide. */ import OpenAI from 'openai'; import { Modal } from 'flowbite-svelte'; import { Bot, BotMessageSquare, Loader, FileText, - Save, FilePenLine, RotateCcw + Save, FilePenLine, RotateCcw, Settings, + RefreshCcw, Globe, Copy } from '@lucide/svelte'; import { ae_loc, ae_api } from '$lib/stores/ae_stores'; import E_app_codemirror_v5 from '$lib/app_components/e_app_codemirror_v5.svelte'; @@ -18,61 +19,68 @@ content: string; // The text to summarize/analyze summary: string; // The result (bindable) - // Configuration + // Configuration (Bindable for global settings persistence) model?: string; baseUrl?: string; token?: string; systemPrompt?: string; + maxTokens?: number; + temperature?: number; // Callbacks onSave?: (newSummary: string) => void; + onSyncConfig?: () => void; // Optional: callback to sync from global site config // UI Customization buttonClass?: string; - showSavedButton?: boolean; log_lvl?: number; } let { content, summary = $bindable(), - model = '', - baseUrl = '', - token = '', - systemPrompt = 'You are a helpful assistant that summarizes technical content.', + model = $bindable('dgrzone-deepseek-8b-quick'), + baseUrl = $bindable('https://ai.dgrzone.com/api'), + token = $bindable(''), + systemPrompt = $bindable('You are a helpful assistant.'), + maxTokens = $bindable(512), + temperature = $bindable(0.7), onSave, + onSyncConfig, buttonClass = "btn btn-sm preset-tonal-primary shadow-lg hover:scale-105 transition-all", - showSavedButton = true, log_lvl = 0 }: Props = $props(); // Internal State let ae_promises: any = $state(null); let show_modal = $state(false); + let active_tab: 'result' | 'settings' = $state('result'); let tmp_summary = $state(''); async function generate_ai_result() { if (!content) { - alert('No content available to summarize.'); + alert('No content available to analyze.'); return; } const ai_client = new OpenAI({ apiKey: token || 'no-token-provided', - baseURL: baseUrl || 'https://ai.dgrzone.com/api', + baseURL: baseUrl, dangerouslyAllowBrowser: true }); try { + active_tab = 'result'; ae_promises = ai_client.chat.completions.create({ - model: model || 'dgrzone-deepseek-8b-quick', + model: model, + max_tokens: maxTokens, + temperature: temperature, messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: content } ] }).then((resp) => { const result = resp?.choices?.[0]?.message?.content || 'No result generated.'; - if (log_lvl) console.log('AE_AITools: Result generated', result); tmp_summary = result; show_modal = true; }); @@ -89,7 +97,7 @@ } -
+
- -
- - {model || 'Default Model'} - + +
+ +
- + {#if active_tab === 'result'} +
+
+ + +
+ + +
+ {:else} +
+ +
+

+ API Connection +

+ + {#if onSyncConfig} + + {/if} + +
+ + +
+ +
+ + +
+

+ Inference Parameters +

+
+ + +
+ +
+
+ {/if}
{/if} - - - + \ No newline at end of file diff --git a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte index 9f5d0dfa..e1bee490 100644 --- a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte +++ b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte @@ -1718,10 +1718,18 @@ content={tmp_entry_obj.content} bind:summary={tmp_entry_obj.summary} onSave={update_journal_entry} - token={$journals_loc?.llm__api_token} - baseUrl={$journals_loc?.llm__api_base_url} - model={$journals_loc?.llm__api_model} - systemPrompt={$journals_loc?.entry?.llm__system_prompt} + bind:token={$journals_loc.llm__api_token} + bind:baseUrl={$journals_loc.llm__api_base_url} + bind:model={$journals_loc.llm__api_model} + bind:systemPrompt={$journals_loc.entry.llm__system_prompt} + bind:maxTokens={$journals_loc.entry.llm__max_tokens} + bind:temperature={$journals_loc.entry.llm__temperature} + onSyncConfig={() => { + $journals_loc.llm__api_base_url = $ae_loc.site_cfg_json?.llm__api_base_url ?? 'https://ai.dgrzone.com/api'; + $journals_loc.llm__api_model = $ae_loc.site_cfg_json?.llm__api_model ?? 'dgrzone-deepseek-8b-quick'; + $journals_loc.llm__api_token = $ae_loc.site_cfg_json?.llm__api_token ?? ''; + $journals_loc.entry.llm__system_prompt = $ae_loc.site_cfg_json?.llm__system_prompt ?? ''; + }} {log_lvl} /> diff --git a/src/routes/journals/modal_journals_config.svelte b/src/routes/journals/modal_journals_config.svelte index bc6a8465..cdd88609 100644 --- a/src/routes/journals/modal_journals_config.svelte +++ b/src/routes/journals/modal_journals_config.svelte @@ -202,131 +202,6 @@ - -
-

- - AI Summary Configuration -

- -
- - -
- - - -
- - -
-
- -
-

$journals_loc?.entry:

- - - - - - - - - - - - - - - -