refac
This commit is contained in:
1 parent
8270aa59ab
commit
75894161e4
9 files changed
+188
-60
No files matched your search
@@ -1948,6 +1948,7 @@ async def get_app_config(request: Request):
|
|||||||
'calendar.enable',
|
'calendar.enable',
|
||||||
'automations.enable',
|
'automations.enable',
|
||||||
'notes.enable',
|
'notes.enable',
|
||||||
|
'chat.context_compaction.enable',
|
||||||
'web.search.enable',
|
'web.search.enable',
|
||||||
'web.search.confirmation.enable',
|
'web.search.confirmation.enable',
|
||||||
'web.search.confirmation.content',
|
'web.search.confirmation.content',
|
||||||
@@ -2017,6 +2018,7 @@ async def get_app_config(request: Request):
|
|||||||
'enable_calendar': config.get('calendar.enable'),
|
'enable_calendar': config.get('calendar.enable'),
|
||||||
'enable_automations': config.get('automations.enable'),
|
'enable_automations': config.get('automations.enable'),
|
||||||
'enable_notes': config.get('notes.enable'),
|
'enable_notes': config.get('notes.enable'),
|
||||||
|
'enable_context_compaction': config.get('chat.context_compaction.enable'),
|
||||||
'enable_web_search': config.get('web.search.enable'),
|
'enable_web_search': config.get('web.search.enable'),
|
||||||
'enable_web_search_confirmation': config.get('web.search.confirmation.enable'),
|
'enable_web_search_confirmation': config.get('web.search.confirmation.enable'),
|
||||||
'web_search_confirmation_content': config.get('web.search.confirmation.content'),
|
'web_search_confirmation_content': config.get('web.search.confirmation.content'),
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ async def compact_messages_for_request(
|
|||||||
|
|
||||||
async def compact_chat_branch(request, user, chat: Any, model_id: str, models: dict) -> dict:
|
async def compact_chat_branch(request, user, chat: Any, model_id: str, models: dict) -> dict:
|
||||||
config = await _load_config()
|
config = await _load_config()
|
||||||
|
if not config['enable']:
|
||||||
|
return {'ok': True, 'compacted': False, 'reason': 'disabled'}
|
||||||
|
|
||||||
history = (chat.chat or {}).get('history') or {}
|
history = (chat.chat or {}).get('history') or {}
|
||||||
current_id = history.get('currentId')
|
current_id = history.get('currentId')
|
||||||
@@ -225,6 +227,9 @@ async def get_chat_context_usage(chat: Any, model_id: str | None = None) -> dict
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
config = await _load_config()
|
config = await _load_config()
|
||||||
|
if not config['enable']:
|
||||||
|
return None
|
||||||
|
|
||||||
params = ((chat.chat or {}).get('params') or {}).copy()
|
params = ((chat.chat or {}).get('params') or {}).copy()
|
||||||
if model_id:
|
if model_id:
|
||||||
params['model'] = model_id
|
params['model'] = model_id
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
import AdminSettingField from './AdminSettingField.svelte';
|
import AdminSettingField from './AdminSettingField.svelte';
|
||||||
import AdminSettingRow from './AdminSettingRow.svelte';
|
import AdminSettingRow from './AdminSettingRow.svelte';
|
||||||
import AdminSettingSection from './AdminSettingSection.svelte';
|
import AdminSettingSection from './AdminSettingSection.svelte';
|
||||||
|
import { config as appConfig } from '$lib/stores';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
@@ -51,6 +52,17 @@
|
|||||||
updateTaskConfig(localStorage.token, taskConfig),
|
updateTaskConfig(localStorage.token, taskConfig),
|
||||||
updateChatConfig(localStorage.token, chatConfig)
|
updateChatConfig(localStorage.token, chatConfig)
|
||||||
]);
|
]);
|
||||||
|
appConfig.update((current) =>
|
||||||
|
current
|
||||||
|
? {
|
||||||
|
...current,
|
||||||
|
features: {
|
||||||
|
...current.features,
|
||||||
|
enable_context_compaction: chatConfig.ENABLE_CONTEXT_COMPACTION
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: current
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let workspaceModels: any[] = [];
|
let workspaceModels: any[] = [];
|
||||||
|
|||||||
@@ -220,6 +220,8 @@
|
|||||||
return next;
|
return next;
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
|
$: contextCompactionEnabled = Boolean($config?.features?.enable_context_compaction);
|
||||||
|
|
||||||
const getContextThreshold = () => {
|
const getContextThreshold = () => {
|
||||||
const chatThreshold = Number(params?.compact_token_threshold);
|
const chatThreshold = Number(params?.compact_token_threshold);
|
||||||
if (Number.isFinite(chatThreshold) && chatThreshold > 0) {
|
if (Number.isFinite(chatThreshold) && chatThreshold > 0) {
|
||||||
@@ -229,7 +231,7 @@
|
|||||||
const modelId = atSelectedModel?.id ?? selectedModels.find((id) => id);
|
const modelId = atSelectedModel?.id ?? selectedModels.find((id) => id);
|
||||||
const model = $models.find((item) => item.id === modelId);
|
const model = $models.find((item) => item.id === modelId);
|
||||||
const threshold = Number(model?.info?.params?.compact_token_threshold);
|
const threshold = Number(model?.info?.params?.compact_token_threshold);
|
||||||
return Number.isFinite(threshold) && threshold > 0 ? threshold : 80000;
|
return Number.isFinite(threshold) && threshold > 0 ? threshold : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getContextUsage = () => {
|
const getContextUsage = () => {
|
||||||
@@ -238,7 +240,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const messages = createMessagesList(history, history.currentId);
|
const messages = createMessagesList(history, history.currentId);
|
||||||
const threshold = getContextThreshold();
|
const threshold = contextCompactionEnabled
|
||||||
|
? (getContextThreshold() ?? serverContextUsage?.threshold ?? null)
|
||||||
|
: null;
|
||||||
const systemTokens = estimateTokens($settings?.system ?? '');
|
const systemTokens = estimateTokens($settings?.system ?? '');
|
||||||
let estimatedTokens = systemTokens;
|
let estimatedTokens = systemTokens;
|
||||||
let hasUsageCheckpoint = false;
|
let hasUsageCheckpoint = false;
|
||||||
@@ -276,12 +280,12 @@
|
|||||||
tokens: estimatedTokens,
|
tokens: estimatedTokens,
|
||||||
estimated_tokens: estimatedTokens,
|
estimated_tokens: estimatedTokens,
|
||||||
threshold,
|
threshold,
|
||||||
percent: threshold > 0 ? Math.max(0, Math.round((estimatedTokens / threshold) * 100)) : 0,
|
percent: threshold > 0 ? Math.max(0, Math.round((estimatedTokens / threshold) * 100)) : null,
|
||||||
source: 'estimated'
|
source: 'estimated'
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
$: contextUsage = getContextUsage() ?? serverContextUsage;
|
$: contextUsage = getContextUsage() ?? (contextCompactionEnabled ? serverContextUsage : null);
|
||||||
$: embeddedHeaderTitle = embeddedTitle || $chatTitle || $i18n.t('Chat');
|
$: embeddedHeaderTitle = embeddedTitle || $chatTitle || $i18n.t('Chat');
|
||||||
|
|
||||||
let selectedToolIds = [];
|
let selectedToolIds = [];
|
||||||
@@ -2400,6 +2404,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleManualCompact = async () => {
|
const handleManualCompact = async () => {
|
||||||
|
if (!contextCompactionEnabled) {
|
||||||
|
toast.message($i18n.t('Context compaction is disabled'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!$chatId || !history?.currentId) {
|
if (!$chatId || !history?.currentId) {
|
||||||
toast.message($i18n.t('No chat to compact'));
|
toast.message($i18n.t('No chat to compact'));
|
||||||
return;
|
return;
|
||||||
@@ -2430,7 +2439,9 @@
|
|||||||
? $i18n.t('Chat is too short to compact')
|
? $i18n.t('Chat is too short to compact')
|
||||||
: result?.reason === 'empty'
|
: result?.reason === 'empty'
|
||||||
? $i18n.t('No chat to compact')
|
? $i18n.t('No chat to compact')
|
||||||
: $i18n.t('Nothing to compact');
|
: result?.reason === 'disabled'
|
||||||
|
? $i18n.t('Context compaction is disabled')
|
||||||
|
: $i18n.t('Nothing to compact');
|
||||||
toast.message(skippedReason, { id: toastId });
|
toast.message(skippedReason, { id: toastId });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3751,6 +3762,7 @@
|
|||||||
dropzoneId={messageInputDropzoneId}
|
dropzoneId={messageInputDropzoneId}
|
||||||
chatId={$chatId}
|
chatId={$chatId}
|
||||||
{contextUsage}
|
{contextUsage}
|
||||||
|
{contextCompactionEnabled}
|
||||||
compactHandler={handleManualCompact}
|
compactHandler={handleManualCompact}
|
||||||
statusHandler={handleStatusCommand}
|
statusHandler={handleStatusCommand}
|
||||||
forkHandler={handleForkChat}
|
forkHandler={handleForkChat}
|
||||||
@@ -3866,6 +3878,7 @@
|
|||||||
dropzoneId={messageInputDropzoneId}
|
dropzoneId={messageInputDropzoneId}
|
||||||
chatId={$chatId}
|
chatId={$chatId}
|
||||||
{contextUsage}
|
{contextUsage}
|
||||||
|
{contextCompactionEnabled}
|
||||||
compactHandler={handleManualCompact}
|
compactHandler={handleManualCompact}
|
||||||
statusHandler={handleStatusCommand}
|
statusHandler={handleStatusCommand}
|
||||||
forkHandler={handleForkChat}
|
forkHandler={handleForkChat}
|
||||||
|
|||||||
@@ -121,6 +121,7 @@
|
|||||||
export let forkHandler: Function = () => {};
|
export let forkHandler: Function = () => {};
|
||||||
export let chatId = '';
|
export let chatId = '';
|
||||||
export let contextUsage = null;
|
export let contextUsage = null;
|
||||||
|
export let contextCompactionEnabled = false;
|
||||||
|
|
||||||
export let autoScroll = false;
|
export let autoScroll = false;
|
||||||
export let generating = false;
|
export let generating = false;
|
||||||
@@ -389,6 +390,79 @@
|
|||||||
const trimNumber = (value: number) =>
|
const trimNumber = (value: number) =>
|
||||||
value >= 10 ? String(Math.round(value)) : value.toFixed(1).replace(/\.0$/, '');
|
value >= 10 ? String(Math.round(value)) : value.toFixed(1).replace(/\.0$/, '');
|
||||||
|
|
||||||
|
const estimateTokens = (value) => {
|
||||||
|
if (value === null || value === undefined || value === '') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (typeof value !== 'string') {
|
||||||
|
try {
|
||||||
|
value = JSON.stringify(value);
|
||||||
|
} catch {
|
||||||
|
value = String(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Math.max(1, Math.floor(value.length / 4));
|
||||||
|
};
|
||||||
|
|
||||||
|
const estimateMessagesTokens = (messages) =>
|
||||||
|
messages.reduce((total, message) => {
|
||||||
|
let next = total + 4 + estimateTokens(message.content);
|
||||||
|
next += estimateTokens(message.output);
|
||||||
|
next += estimateTokens(message.tool_calls);
|
||||||
|
next += estimateTokens(message.files);
|
||||||
|
return next;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
const getLocalContextUsage = () => {
|
||||||
|
if (!history?.currentId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = createMessagesList(history, history.currentId);
|
||||||
|
if (!messages.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let summary = '';
|
||||||
|
let startIdx = 0;
|
||||||
|
for (let idx = 0; idx < messages.length; idx += 1) {
|
||||||
|
const value = messages[idx]?.contextSummary ?? messages[idx]?.context_summary;
|
||||||
|
if (typeof value === 'string' && value.trim()) {
|
||||||
|
summary = value;
|
||||||
|
startIdx = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeMessages = messages.slice(startIdx);
|
||||||
|
let estimatedTokens = estimateTokens($settings?.system ?? '');
|
||||||
|
let hasUsageCheckpoint = false;
|
||||||
|
|
||||||
|
for (let idx = activeMessages.length - 1; idx >= 0; idx -= 1) {
|
||||||
|
const usage = activeMessages[idx]?.usage ?? activeMessages[idx]?.info?.usage;
|
||||||
|
const inputTokens = usage?.input_tokens ?? usage?.prompt_tokens;
|
||||||
|
if (inputTokens) {
|
||||||
|
hasUsageCheckpoint = true;
|
||||||
|
estimatedTokens =
|
||||||
|
Number(inputTokens || 0) +
|
||||||
|
Number(usage.output_tokens ?? usage.completion_tokens ?? 0) +
|
||||||
|
estimateMessagesTokens(activeMessages.slice(idx + 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasUsageCheckpoint) {
|
||||||
|
estimatedTokens += estimateTokens(summary) + estimateMessagesTokens(activeMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
tokens: estimatedTokens,
|
||||||
|
estimated_tokens: estimatedTokens,
|
||||||
|
threshold: null,
|
||||||
|
percent: null,
|
||||||
|
source: 'estimated'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const copyStatusChatId = async () => {
|
const copyStatusChatId = async () => {
|
||||||
if (!chatId) return;
|
if (!chatId) return;
|
||||||
await navigator.clipboard.writeText(chatId);
|
await navigator.clipboard.writeText(chatId);
|
||||||
@@ -398,11 +472,18 @@
|
|||||||
}, 1600);
|
}, 1600);
|
||||||
};
|
};
|
||||||
|
|
||||||
$: contextPercent = Math.max(0, Math.round(contextUsage?.percent ?? 0));
|
$: statusContextUsage = contextUsage ?? getLocalContextUsage();
|
||||||
$: contextValue = contextUsage
|
$: contextHasThreshold = Number(statusContextUsage?.threshold) > 0;
|
||||||
? `${contextPercent}% ${formatTokenCount(contextUsage.estimated_tokens || contextUsage.tokens)}/${formatTokenCount(contextUsage.threshold)}`
|
$: contextPercent = contextHasThreshold
|
||||||
|
? Math.max(0, Math.round(statusContextUsage?.percent ?? 0))
|
||||||
|
: null;
|
||||||
|
$: contextTokens = formatTokenCount(statusContextUsage?.estimated_tokens || statusContextUsage?.tokens || 0);
|
||||||
|
$: contextValue = statusContextUsage
|
||||||
|
? contextHasThreshold
|
||||||
|
? `${contextPercent}% ${contextTokens}/${formatTokenCount(statusContextUsage.threshold)}`
|
||||||
|
: `${contextTokens} ${$i18n.t('tokens')}`
|
||||||
: $i18n.t('unknown');
|
: $i18n.t('unknown');
|
||||||
$: contextBarPercent = Math.min(contextPercent, 100);
|
$: contextBarPercent = contextHasThreshold ? Math.min(contextPercent, 100) : 0;
|
||||||
|
|
||||||
const getCommand = () => {
|
const getCommand = () => {
|
||||||
const chatInput = document.getElementById('chat-input');
|
const chatInput = document.getElementById('chat-input');
|
||||||
@@ -1086,12 +1167,12 @@
|
|||||||
char: '/',
|
char: '/',
|
||||||
render: getSuggestionRenderer(CommandSuggestionList, {
|
render: getSuggestionRenderer(CommandSuggestionList, {
|
||||||
i18n,
|
i18n,
|
||||||
canCompact: () => !!history?.currentId,
|
canCompact: () => !!history?.currentId && contextCompactionEnabled,
|
||||||
compactDisabled: () => isActive,
|
compactDisabled: () => isActive,
|
||||||
canStatus: () => !!history?.currentId,
|
canStatus: () => !!history?.currentId,
|
||||||
canFork: () => !!history?.currentId,
|
canFork: () => !!history?.currentId,
|
||||||
forkDisabled: () => isActive,
|
forkDisabled: () => isActive,
|
||||||
contextUsage: () => contextUsage,
|
contextUsage: () => statusContextUsage,
|
||||||
onCompact: compactHandler,
|
onCompact: compactHandler,
|
||||||
onStatus: statusHandler,
|
onStatus: statusHandler,
|
||||||
onFork: forkHandler,
|
onFork: forkHandler,
|
||||||
@@ -1436,14 +1517,16 @@
|
|||||||
{contextValue}
|
{contextValue}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
{#if contextHasThreshold}
|
||||||
class="mt-1.5 h-0.5 overflow-hidden rounded-full bg-gray-100 dark:bg-white/8"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
class="h-full rounded-full bg-gray-300 dark:bg-white/20"
|
class="mt-1.5 h-0.5 overflow-hidden rounded-full bg-gray-100 dark:bg-white/8"
|
||||||
style={`width: ${contextBarPercent}%`}
|
>
|
||||||
></div>
|
<div
|
||||||
</div>
|
class="h-full rounded-full bg-gray-300 dark:bg-white/20"
|
||||||
|
style={`width: ${contextBarPercent}%`}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if messageQueue.length}
|
{#if messageQueue.length}
|
||||||
|
|||||||
@@ -30,7 +30,10 @@
|
|||||||
$: forkAvailable = typeof canFork === 'function' ? canFork() : canFork;
|
$: forkAvailable = typeof canFork === 'function' ? canFork() : canFork;
|
||||||
$: isForkDisabled = typeof forkDisabled === 'function' ? forkDisabled() : forkDisabled;
|
$: isForkDisabled = typeof forkDisabled === 'function' ? forkDisabled() : forkDisabled;
|
||||||
$: resolvedContextUsage = typeof contextUsage === 'function' ? contextUsage() : contextUsage;
|
$: resolvedContextUsage = typeof contextUsage === 'function' ? contextUsage() : contextUsage;
|
||||||
$: contextPercent = Math.max(0, Math.round(resolvedContextUsage?.percent ?? 0));
|
$: contextHasThreshold = Number(resolvedContextUsage?.threshold) > 0;
|
||||||
|
$: contextPercent = contextHasThreshold
|
||||||
|
? Math.max(0, Math.round(resolvedContextUsage?.percent ?? 0))
|
||||||
|
: null;
|
||||||
|
|
||||||
let suggestionElement: any = null;
|
let suggestionElement: any = null;
|
||||||
let filteredItems: any[] = [];
|
let filteredItems: any[] = [];
|
||||||
@@ -85,6 +88,7 @@
|
|||||||
canFork={forkAvailable}
|
canFork={forkAvailable}
|
||||||
forkDisabled={isForkDisabled}
|
forkDisabled={isForkDisabled}
|
||||||
{contextPercent}
|
{contextPercent}
|
||||||
|
{contextHasThreshold}
|
||||||
onSelect={(e) => {
|
onSelect={(e) => {
|
||||||
const { type, data } = e;
|
const { type, data } = e;
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
export let canFork = false;
|
export let canFork = false;
|
||||||
export let forkDisabled = false;
|
export let forkDisabled = false;
|
||||||
export let contextPercent = 0;
|
export let contextPercent = 0;
|
||||||
|
export let contextHasThreshold = false;
|
||||||
|
|
||||||
let selectedIdx = 0;
|
let selectedIdx = 0;
|
||||||
export let filteredItems = [];
|
export let filteredItems = [];
|
||||||
@@ -23,7 +24,9 @@
|
|||||||
let skills = [];
|
let skills = [];
|
||||||
let searchDebounceTimer: ReturnType<typeof setTimeout>;
|
let searchDebounceTimer: ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
$: contextCirclePercent = Math.min(Math.max(0, Math.round(contextPercent)), 100);
|
$: contextCirclePercent = contextHasThreshold
|
||||||
|
? Math.min(Math.max(0, Math.round(contextPercent)), 100)
|
||||||
|
: 0;
|
||||||
$: contextCircleOffset = 50.27 * (1 - contextCirclePercent / 100);
|
$: contextCircleOffset = 50.27 * (1 - contextCirclePercent / 100);
|
||||||
|
|
||||||
$: commandItems = [
|
$: commandItems = [
|
||||||
@@ -144,34 +147,38 @@
|
|||||||
data-selected={commandIdx === selectedIdx}
|
data-selected={commandIdx === selectedIdx}
|
||||||
>
|
>
|
||||||
<span class="app-icon-muted flex items-center justify-center w-4 shrink-0">
|
<span class="app-icon-muted flex items-center justify-center w-4 shrink-0">
|
||||||
<svg class="size-3.5 -rotate-90" viewBox="0 0 20 20" aria-hidden="true">
|
{#if contextHasThreshold}
|
||||||
<circle
|
<svg class="size-3.5 -rotate-90" viewBox="0 0 20 20" aria-hidden="true">
|
||||||
cx="10"
|
<circle
|
||||||
cy="10"
|
cx="10"
|
||||||
r="8"
|
cy="10"
|
||||||
fill="none"
|
r="8"
|
||||||
stroke="currentColor"
|
fill="none"
|
||||||
stroke-width="2"
|
stroke="currentColor"
|
||||||
class="opacity-20"
|
stroke-width="2"
|
||||||
/>
|
class="opacity-20"
|
||||||
<circle
|
/>
|
||||||
cx="10"
|
<circle
|
||||||
cy="10"
|
cx="10"
|
||||||
r="8"
|
cy="10"
|
||||||
fill="none"
|
r="8"
|
||||||
stroke="currentColor"
|
fill="none"
|
||||||
stroke-width="2"
|
stroke="currentColor"
|
||||||
stroke-linecap="round"
|
stroke-width="2"
|
||||||
stroke-dasharray="50.27"
|
stroke-linecap="round"
|
||||||
style={`stroke-dashoffset: ${contextCircleOffset};`}
|
stroke-dasharray="50.27"
|
||||||
/>
|
style={`stroke-dashoffset: ${contextCircleOffset};`}
|
||||||
</svg>
|
/>
|
||||||
|
</svg>
|
||||||
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
<span class="flex-1 min-w-0 flex items-baseline gap-1.5 overflow-hidden">
|
<span class="flex-1 min-w-0 flex items-baseline gap-1.5 overflow-hidden">
|
||||||
<span class="truncate">Compact</span>
|
<span class="truncate">Compact</span>
|
||||||
<span class="app-muted text-[0.625rem] truncate shrink-0">
|
{#if contextHasThreshold}
|
||||||
{contextCirclePercent}% full
|
<span class="app-muted text-[0.625rem] truncate shrink-0">
|
||||||
</span>
|
{contextCirclePercent}% full
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -665,6 +665,21 @@
|
|||||||
title: 'Sub-agents',
|
title: 'Sub-agents',
|
||||||
keywords: ['sub-agents', 'subagents', 'delegation', 'background', 'agents']
|
keywords: ['sub-agents', 'subagents', 'delegation', 'background', 'agents']
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'admin:interface',
|
||||||
|
title: 'Interface',
|
||||||
|
keywords: ['interface', 'ui', 'appearance', 'banners', 'tasks', 'prompt suggestions', 'tags']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'admin:audio',
|
||||||
|
title: 'Audio',
|
||||||
|
keywords: ['audio', 'voice', 'speech', 'tts', 'stt', 'whisper', 'deepgram', 'azure']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'admin:images',
|
||||||
|
title: 'Images',
|
||||||
|
keywords: ['images', 'generation', 'dalle', 'stable diffusion', 'comfyui', 'automatic1111']
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'admin:evaluations',
|
id: 'admin:evaluations',
|
||||||
title: 'Evaluations',
|
title: 'Evaluations',
|
||||||
@@ -700,21 +715,7 @@
|
|||||||
title: 'Pipelines',
|
title: 'Pipelines',
|
||||||
keywords: ['pipelines', 'workflows', 'filters', 'valves', 'middleware']
|
keywords: ['pipelines', 'workflows', 'filters', 'valves', 'middleware']
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'admin:interface',
|
|
||||||
title: 'Interface',
|
|
||||||
keywords: ['interface', 'ui', 'appearance', 'banners', 'tasks', 'prompt suggestions', 'tags']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'admin:audio',
|
|
||||||
title: 'Audio',
|
|
||||||
keywords: ['audio', 'voice', 'speech', 'tts', 'stt', 'whisper', 'deepgram', 'azure']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'admin:images',
|
|
||||||
title: 'Images',
|
|
||||||
keywords: ['images', 'generation', 'dalle', 'stable diffusion', 'comfyui', 'automatic1111']
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'admin:db',
|
id: 'admin:db',
|
||||||
title: 'Database',
|
title: 'Database',
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ type Config = {
|
|||||||
enable_admin_export: boolean;
|
enable_admin_export: boolean;
|
||||||
enable_admin_chat_access: boolean;
|
enable_admin_chat_access: boolean;
|
||||||
enable_admin_analytics: boolean;
|
enable_admin_analytics: boolean;
|
||||||
|
enable_context_compaction?: boolean;
|
||||||
enable_community_sharing: boolean;
|
enable_community_sharing: boolean;
|
||||||
enable_memories: boolean;
|
enable_memories: boolean;
|
||||||
enable_plugins?: boolean;
|
enable_plugins?: boolean;
|
||||||
|
|||||||
Reference in new issue
Block a user