|
|
|
|
@@ -113,7 +113,6 @@
|
|
|
|
|
import Tooltip from '../common/Tooltip.svelte';
|
|
|
|
|
import Sidebar from '../icons/Sidebar.svelte';
|
|
|
|
|
import Image from '../common/Image.svelte';
|
|
|
|
|
import { getBanners } from '$lib/apis/configs';
|
|
|
|
|
|
|
|
|
|
export let chatIdProp = '';
|
|
|
|
|
|
|
|
|
|
@@ -330,107 +329,117 @@
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let settingDefaults = false;
|
|
|
|
|
const setDefaults = async () => {
|
|
|
|
|
if (!$tools) {
|
|
|
|
|
tools.set(await getTools(localStorage.token));
|
|
|
|
|
}
|
|
|
|
|
if (!$functions) {
|
|
|
|
|
functions.set(await getFunctions(localStorage.token));
|
|
|
|
|
}
|
|
|
|
|
if (!$skills) {
|
|
|
|
|
skills.set(await getSkills(localStorage.token));
|
|
|
|
|
}
|
|
|
|
|
if (selectedModels.length !== 1 && !atSelectedModel) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (settingDefaults) return;
|
|
|
|
|
settingDefaults = true;
|
|
|
|
|
|
|
|
|
|
const model = atSelectedModel ?? $models.find((m) => m.id === selectedModels[0]);
|
|
|
|
|
if (model) {
|
|
|
|
|
// Set Default Tools
|
|
|
|
|
if (model?.info?.meta?.toolIds) {
|
|
|
|
|
const defaultIds = [
|
|
|
|
|
...new Set(
|
|
|
|
|
[...(model?.info?.meta?.toolIds ?? [])].filter((id) => $tools.find((t) => t.id === id))
|
|
|
|
|
)
|
|
|
|
|
];
|
|
|
|
|
try {
|
|
|
|
|
if (!$tools) {
|
|
|
|
|
tools.set(await getTools(localStorage.token));
|
|
|
|
|
}
|
|
|
|
|
if (!$functions) {
|
|
|
|
|
functions.set(await getFunctions(localStorage.token));
|
|
|
|
|
}
|
|
|
|
|
if (!$skills) {
|
|
|
|
|
skills.set(await getSkills(localStorage.token));
|
|
|
|
|
}
|
|
|
|
|
if (selectedModels.length !== 1 && !atSelectedModel) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Separate unauthenticated OAuth tools
|
|
|
|
|
const unauthed = [];
|
|
|
|
|
const authed = [];
|
|
|
|
|
for (const id of defaultIds) {
|
|
|
|
|
const tool = $tools.find((t) => t.id === id);
|
|
|
|
|
if (tool && tool.authenticated === false) {
|
|
|
|
|
const parts = id.split(':');
|
|
|
|
|
const serverId = parts.at(-1) ?? id;
|
|
|
|
|
const authType =
|
|
|
|
|
parts.length > 1 ? (parts[0] === 'server' ? parts[1] : parts[0]) : null;
|
|
|
|
|
unauthed.push({ id, name: tool.name ?? id, serverId, authType });
|
|
|
|
|
} else {
|
|
|
|
|
authed.push(id);
|
|
|
|
|
const model = atSelectedModel ?? $models.find((m) => m.id === selectedModels[0]);
|
|
|
|
|
if (model) {
|
|
|
|
|
// Set Default Tools
|
|
|
|
|
if (model?.info?.meta?.toolIds) {
|
|
|
|
|
const defaultIds = [
|
|
|
|
|
...new Set(
|
|
|
|
|
[...(model?.info?.meta?.toolIds ?? [])].filter((id) =>
|
|
|
|
|
$tools.find((t) => t.id === id)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Separate unauthenticated OAuth tools
|
|
|
|
|
const unauthed = [];
|
|
|
|
|
const authed = [];
|
|
|
|
|
for (const id of defaultIds) {
|
|
|
|
|
const tool = $tools.find((t) => t.id === id);
|
|
|
|
|
if (tool && tool.authenticated === false) {
|
|
|
|
|
const parts = id.split(':');
|
|
|
|
|
const serverId = parts.at(-1) ?? id;
|
|
|
|
|
const authType =
|
|
|
|
|
parts.length > 1 ? (parts[0] === 'server' ? parts[1] : parts[0]) : null;
|
|
|
|
|
unauthed.push({ id, name: tool.name ?? id, serverId, authType });
|
|
|
|
|
} else {
|
|
|
|
|
authed.push(id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
selectedToolIds = authed;
|
|
|
|
|
pendingOAuthTools = unauthed;
|
|
|
|
|
} else if ($settings?.tools) {
|
|
|
|
|
selectedToolIds = $settings.tools;
|
|
|
|
|
} else {
|
|
|
|
|
selectedToolIds = selectedToolIds.filter((id) => !id.startsWith('direct_server:'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set Default Skills
|
|
|
|
|
if (model?.info?.meta?.skillIds) {
|
|
|
|
|
selectedSkillIds = [
|
|
|
|
|
...new Set(
|
|
|
|
|
[...(model?.info?.meta?.skillIds ?? [])].filter((id) =>
|
|
|
|
|
($skills ?? []).find((s) => s.id === id && s.is_active)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
];
|
|
|
|
|
} else {
|
|
|
|
|
selectedSkillIds = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set Default Filters (Toggleable only)
|
|
|
|
|
if (model?.info?.meta?.defaultFilterIds) {
|
|
|
|
|
selectedFilterIds = model.info.meta.defaultFilterIds.filter((id) =>
|
|
|
|
|
model?.filters?.find((f) => f.id === id)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set Default Features
|
|
|
|
|
if (model?.info?.meta?.defaultFeatureIds) {
|
|
|
|
|
if (
|
|
|
|
|
model.info?.meta?.capabilities?.['image_generation'] &&
|
|
|
|
|
$config?.features?.enable_image_generation &&
|
|
|
|
|
($user?.role === 'admin' || $user?.permissions?.features?.image_generation)
|
|
|
|
|
) {
|
|
|
|
|
imageGenerationEnabled = model.info.meta.defaultFeatureIds.includes('image_generation');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
model.info?.meta?.capabilities?.['web_search'] &&
|
|
|
|
|
$config?.features?.enable_web_search &&
|
|
|
|
|
($user?.role === 'admin' || $user?.permissions?.features?.web_search)
|
|
|
|
|
) {
|
|
|
|
|
webSearchEnabled = model.info.meta.defaultFeatureIds.includes('web_search');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
model.info?.meta?.capabilities?.['code_interpreter'] &&
|
|
|
|
|
$config?.features?.enable_code_interpreter &&
|
|
|
|
|
($user?.role === 'admin' || $user?.permissions?.features?.code_interpreter)
|
|
|
|
|
) {
|
|
|
|
|
codeInterpreterEnabled = model.info.meta.defaultFeatureIds.includes('code_interpreter');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
selectedToolIds = authed;
|
|
|
|
|
pendingOAuthTools = unauthed;
|
|
|
|
|
} else if ($settings?.tools) {
|
|
|
|
|
selectedToolIds = $settings.tools;
|
|
|
|
|
} else {
|
|
|
|
|
selectedToolIds = selectedToolIds.filter((id) => !id.startsWith('direct_server:'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set Default Skills
|
|
|
|
|
if (model?.info?.meta?.skillIds) {
|
|
|
|
|
selectedSkillIds = [
|
|
|
|
|
...new Set(
|
|
|
|
|
[...(model?.info?.meta?.skillIds ?? [])].filter((id) =>
|
|
|
|
|
($skills ?? []).find((s) => s.id === id && s.is_active)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
];
|
|
|
|
|
} else {
|
|
|
|
|
selectedSkillIds = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set Default Filters (Toggleable only)
|
|
|
|
|
if (model?.info?.meta?.defaultFilterIds) {
|
|
|
|
|
selectedFilterIds = model.info.meta.defaultFilterIds.filter((id) =>
|
|
|
|
|
model?.filters?.find((f) => f.id === id)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set Default Features
|
|
|
|
|
if (model?.info?.meta?.defaultFeatureIds) {
|
|
|
|
|
if (
|
|
|
|
|
model.info?.meta?.capabilities?.['image_generation'] &&
|
|
|
|
|
$config?.features?.enable_image_generation &&
|
|
|
|
|
($user?.role === 'admin' || $user?.permissions?.features?.image_generation)
|
|
|
|
|
) {
|
|
|
|
|
imageGenerationEnabled = model.info.meta.defaultFeatureIds.includes('image_generation');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
model.info?.meta?.capabilities?.['web_search'] &&
|
|
|
|
|
$config?.features?.enable_web_search &&
|
|
|
|
|
($user?.role === 'admin' || $user?.permissions?.features?.web_search)
|
|
|
|
|
) {
|
|
|
|
|
webSearchEnabled = model.info.meta.defaultFeatureIds.includes('web_search');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
model.info?.meta?.capabilities?.['code_interpreter'] &&
|
|
|
|
|
$config?.features?.enable_code_interpreter &&
|
|
|
|
|
($user?.role === 'admin' || $user?.permissions?.features?.code_interpreter)
|
|
|
|
|
) {
|
|
|
|
|
codeInterpreterEnabled = model.info.meta.defaultFeatureIds.includes('code_interpreter');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set Default Terminal — only if the referenced terminal actually exists
|
|
|
|
|
if (model?.info?.meta?.terminalId) {
|
|
|
|
|
const tid = model.info.meta.terminalId;
|
|
|
|
|
if (isTerminalAvailable(tid)) {
|
|
|
|
|
selectedTerminalId.set(tid);
|
|
|
|
|
// Set Default Terminal — only if the referenced terminal actually exists
|
|
|
|
|
if (model?.info?.meta?.terminalId) {
|
|
|
|
|
const tid = model.info.meta.terminalId;
|
|
|
|
|
if (isTerminalAvailable(tid)) {
|
|
|
|
|
selectedTerminalId.set(tid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
settingDefaults = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -796,13 +805,6 @@
|
|
|
|
|
if (p.url.pathname === '/') {
|
|
|
|
|
await tick();
|
|
|
|
|
initNewChat();
|
|
|
|
|
|
|
|
|
|
// Re-fetch banners on navigation to homepage so newly configured banners appear
|
|
|
|
|
try {
|
|
|
|
|
banners.set(await getBanners(localStorage.token).catch(() => []));
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('Failed to refresh banners:', e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stopAudio();
|
|
|
|
|
|