chore: allow users to enable/disable MCP servers (#5015)
This commit is contained in:
parent
16514050b9
commit
2bc8fccaf0
@ -2,7 +2,7 @@
|
|||||||
"name": "@janhq/conversational-extension",
|
"name": "@janhq/conversational-extension",
|
||||||
"productName": "Conversational",
|
"productName": "Conversational",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Enables conversations and state persistence via your filesystem.",
|
"description": "Enables conversations and state persistence via your file system.",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"author": "Jan <service@jan.ai>",
|
"author": "Jan <service@jan.ai>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"name": "@janhq/hardware-management-extension",
|
"name": "@janhq/hardware-management-extension",
|
||||||
"productName": "Hardware Management",
|
"productName": "Hardware Management",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Manages Better Hardware settings.",
|
"description": "Manages hardware settings.",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"node": "dist/node/index.cjs.js",
|
"node": "dist/node/index.cjs.js",
|
||||||
"author": "Jan <service@jan.ai>",
|
"author": "Jan <service@jan.ai>",
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"name": "@janhq/model-extension",
|
"name": "@janhq/model-extension",
|
||||||
"productName": "Model Management",
|
"productName": "Model Management",
|
||||||
"version": "1.0.36",
|
"version": "1.0.36",
|
||||||
"description": "Handles model lists, their details, and settings.",
|
"description": "Handles model list, and settings.",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"author": "Jan <service@jan.ai>",
|
"author": "Jan <service@jan.ai>",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
|
|||||||
@ -34,9 +34,15 @@ pub async fn run_mcp_commands(
|
|||||||
log::info!("MCP Servers: {server_map:#?}");
|
log::info!("MCP Servers: {server_map:#?}");
|
||||||
|
|
||||||
let exe_path = env::current_exe().expect("Failed to get current exe path");
|
let exe_path = env::current_exe().expect("Failed to get current exe path");
|
||||||
let exe_parent_path = exe_path.parent().expect("Executable must have a parent directory");
|
let exe_parent_path = exe_path
|
||||||
|
.parent()
|
||||||
|
.expect("Executable must have a parent directory");
|
||||||
let bin_path = exe_parent_path.to_path_buf();
|
let bin_path = exe_parent_path.to_path_buf();
|
||||||
for (name, config) in server_map {
|
for (name, config) in server_map {
|
||||||
|
if let Some(false) = extract_active_status(config) {
|
||||||
|
log::info!("Server {name} is not active, skipping.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if let Some((command, args, envs)) = extract_command_args(config) {
|
if let Some((command, args, envs)) = extract_command_args(config) {
|
||||||
let mut cmd = Command::new(command.clone());
|
let mut cmd = Command::new(command.clone());
|
||||||
if command.clone() == "npx" {
|
if command.clone() == "npx" {
|
||||||
@ -96,6 +102,12 @@ fn extract_command_args(
|
|||||||
Some((command, args, envs))
|
Some((command, args, envs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extract_active_status(config: &Value) -> Option<bool> {
|
||||||
|
let obj = config.as_object()?;
|
||||||
|
let active = obj.get("active")?.as_bool()?;
|
||||||
|
Some(active)
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn restart_mcp_servers(app: AppHandle, state: State<'_, AppState>) -> Result<(), String> {
|
pub async fn restart_mcp_servers(app: AppHandle, state: State<'_, AppState>) -> Result<(), String> {
|
||||||
let app_path = get_jan_data_folder_path(app.clone());
|
let app_path = get_jan_data_folder_path(app.clone());
|
||||||
|
|||||||
@ -8,6 +8,7 @@ export type MCPServerConfig = {
|
|||||||
command: string
|
command: string
|
||||||
args: string[]
|
args: string[]
|
||||||
env: Record<string, string>
|
env: Record<string, string>
|
||||||
|
active?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the structure of all MCP servers
|
// Define the structure of all MCP servers
|
||||||
|
|||||||
59
web-app/src/hooks/useProxyConfig.ts
Normal file
59
web-app/src/hooks/useProxyConfig.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { create } from 'zustand'
|
||||||
|
import { persist, createJSONStorage } from 'zustand/middleware'
|
||||||
|
import { localStoregeKey } from '@/constants/localStorage'
|
||||||
|
|
||||||
|
type ProxyConfigState = {
|
||||||
|
proxyEnabled: boolean
|
||||||
|
proxyUrl: string
|
||||||
|
proxyUsername: string
|
||||||
|
proxyPassword: string
|
||||||
|
proxyIgnoreSSL: boolean
|
||||||
|
verifyProxySSL: boolean
|
||||||
|
verifyProxyHostSSL: boolean
|
||||||
|
verifyPeerSSL: boolean
|
||||||
|
verifyHostSSL: boolean
|
||||||
|
noProxy: string
|
||||||
|
// Function to set the proxy configuration
|
||||||
|
setProxyEnabled: (proxyEnabled: boolean) => void
|
||||||
|
setProxyUrl: (proxyUrl: string) => void
|
||||||
|
setProxyUsername: (proxyUsername: string) => void
|
||||||
|
setProxyPassword: (proxyPassword: string) => void
|
||||||
|
setProxyIgnoreSSL: (proxyIgnoreSSL: boolean) => void
|
||||||
|
setVerifyProxySSL: (verifyProxySSL: boolean) => void
|
||||||
|
setVerifyProxyHostSSL: (verifyProxyHostSSL: boolean) => void
|
||||||
|
setVerifyPeerSSL: (verifyPeerSSL: boolean) => void
|
||||||
|
setVerifyHostSSL: (verifyHostSSL: boolean) => void
|
||||||
|
setNoProxy: (noProxy: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useProxyConfig = create<ProxyConfigState>()(
|
||||||
|
persist(
|
||||||
|
(set) => ({
|
||||||
|
proxyEnabled: false,
|
||||||
|
proxyUrl: '',
|
||||||
|
proxyUsername: '',
|
||||||
|
proxyPassword: '',
|
||||||
|
proxyIgnoreSSL: false,
|
||||||
|
verifyProxySSL: true,
|
||||||
|
verifyProxyHostSSL: true,
|
||||||
|
verifyPeerSSL: true,
|
||||||
|
verifyHostSSL: true,
|
||||||
|
noProxy: '',
|
||||||
|
setProxyEnabled: (proxyEnabled) => set({ proxyEnabled }),
|
||||||
|
setProxyUrl: (proxyUrl) => set({ proxyUrl }),
|
||||||
|
setProxyUsername: (proxyUsername) => set({ proxyUsername }),
|
||||||
|
setProxyPassword: (proxyPassword) => set({ proxyPassword }),
|
||||||
|
setProxyIgnoreSSL: (proxyIgnoreSSL) => set({ proxyIgnoreSSL }),
|
||||||
|
setVerifyProxySSL: (verifyProxySSL) => set({ verifyProxySSL }),
|
||||||
|
setVerifyProxyHostSSL: (verifyProxyHostSSL) =>
|
||||||
|
set({ verifyProxyHostSSL }),
|
||||||
|
setVerifyPeerSSL: (verifyPeerSSL) => set({ verifyPeerSSL }),
|
||||||
|
setVerifyHostSSL: (verifyHostSSL) => set({ verifyHostSSL }),
|
||||||
|
setNoProxy: (noProxy) => set({ noProxy }),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: localStoregeKey.settingLocalApiServer,
|
||||||
|
storage: createJSONStorage(() => localStorage),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
@ -7,46 +7,15 @@ import HeaderPage from '@/containers/HeaderPage'
|
|||||||
import SettingsMenu from '@/containers/SettingsMenu'
|
import SettingsMenu from '@/containers/SettingsMenu'
|
||||||
import { t } from 'i18next'
|
import { t } from 'i18next'
|
||||||
import { RenderMarkdown } from '@/containers/RenderMarkdown'
|
import { RenderMarkdown } from '@/containers/RenderMarkdown'
|
||||||
|
import { ExtensionManager } from '@/lib/extension'
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export const Route = createFileRoute(route.settings.extensions as any)({
|
export const Route = createFileRoute(route.settings.extensions as any)({
|
||||||
component: Extensions,
|
component: Extensions,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mockExtension = [
|
|
||||||
{
|
|
||||||
name: 'Jan Assistant',
|
|
||||||
version: '1.0.2',
|
|
||||||
description:
|
|
||||||
'Powers the default AI assistant that works with all your installed models.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Conversational',
|
|
||||||
version: '1.0.0',
|
|
||||||
description:
|
|
||||||
'Enables conversations and state persistence via your filesystem.',
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: 'Engine Management',
|
|
||||||
version: '1.0.3',
|
|
||||||
description: 'Manages AI engines and their configurations.',
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: 'Hardware Management',
|
|
||||||
version: '1.0.0',
|
|
||||||
description: 'Manages Better Hardware settings.',
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: 'Model Management',
|
|
||||||
version: '1.0.36',
|
|
||||||
description: 'Handles model lists, their details, and settings.',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
function Extensions() {
|
function Extensions() {
|
||||||
|
const extensions = ExtensionManager.getInstance().listExtensions()
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full">
|
||||||
<HeaderPage>
|
<HeaderPage>
|
||||||
@ -69,13 +38,13 @@ function Extensions() {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{mockExtension.map((item, i) => {
|
{extensions.map((item, i) => {
|
||||||
return (
|
return (
|
||||||
<CardItem
|
<CardItem
|
||||||
key={i}
|
key={i}
|
||||||
title={
|
title={
|
||||||
<div className="flex items-center gap-x-2">
|
<div className="flex items-center gap-x-2">
|
||||||
<h1 className="text-main-view-fg">{item.name}</h1>
|
<h1 className="text-main-view-fg">{item.productName ?? item.name}</h1>
|
||||||
<div className="bg-main-view-fg/10 px-1 py-0.5 rounded text-main-view-fg/70 text-xs">
|
<div className="bg-main-view-fg/10 px-1 py-0.5 rounded text-main-view-fg/70 text-xs">
|
||||||
v{item.version}
|
v{item.version}
|
||||||
</div>
|
</div>
|
||||||
@ -83,7 +52,7 @@ function Extensions() {
|
|||||||
}
|
}
|
||||||
description={
|
description={
|
||||||
<RenderMarkdown
|
<RenderMarkdown
|
||||||
content={item.description}
|
content={item.description ?? ""}
|
||||||
components={{
|
components={{
|
||||||
// Make links open in a new tab
|
// Make links open in a new tab
|
||||||
a: ({ ...props }) => (
|
a: ({ ...props }) => (
|
||||||
|
|||||||
@ -7,7 +7,9 @@ import { Switch } from '@/components/ui/switch'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Input } from '@/components/ui/input'
|
import { Input } from '@/components/ui/input'
|
||||||
import { EyeOff, Eye } from 'lucide-react'
|
import { EyeOff, Eye } from 'lucide-react'
|
||||||
import { useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
|
import { useProxyConfig } from '@/hooks/useProxyConfig'
|
||||||
|
import { configurePullOptions } from '@/services/models'
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export const Route = createFileRoute(route.settings.https_proxy as any)({
|
export const Route = createFileRoute(route.settings.https_proxy as any)({
|
||||||
@ -17,6 +19,65 @@ export const Route = createFileRoute(route.settings.https_proxy as any)({
|
|||||||
function HTTPSProxy() {
|
function HTTPSProxy() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [showPassword, setShowPassword] = useState(false)
|
const [showPassword, setShowPassword] = useState(false)
|
||||||
|
const {
|
||||||
|
proxyUrl,
|
||||||
|
proxyEnabled,
|
||||||
|
proxyUsername,
|
||||||
|
proxyPassword,
|
||||||
|
proxyIgnoreSSL,
|
||||||
|
verifyProxySSL,
|
||||||
|
verifyProxyHostSSL,
|
||||||
|
verifyPeerSSL,
|
||||||
|
verifyHostSSL,
|
||||||
|
noProxy,
|
||||||
|
setProxyEnabled,
|
||||||
|
setProxyUsername,
|
||||||
|
setProxyPassword,
|
||||||
|
setProxyIgnoreSSL,
|
||||||
|
setVerifyProxySSL,
|
||||||
|
setVerifyProxyHostSSL,
|
||||||
|
setVerifyPeerSSL,
|
||||||
|
setVerifyHostSSL,
|
||||||
|
setNoProxy,
|
||||||
|
setProxyUrl,
|
||||||
|
} = useProxyConfig()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (proxyUrl && !proxyEnabled) {
|
||||||
|
setProxyEnabled(true)
|
||||||
|
} else if (!proxyUrl && proxyEnabled) {
|
||||||
|
setProxyEnabled(false)
|
||||||
|
}
|
||||||
|
}, [proxyEnabled, proxyUrl, setProxyEnabled])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handler = setTimeout(() => {
|
||||||
|
configurePullOptions({
|
||||||
|
proxyUrl,
|
||||||
|
proxyEnabled,
|
||||||
|
proxyUsername,
|
||||||
|
proxyPassword,
|
||||||
|
proxyIgnoreSSL,
|
||||||
|
verifyProxySSL,
|
||||||
|
verifyProxyHostSSL,
|
||||||
|
verifyPeerSSL,
|
||||||
|
verifyHostSSL,
|
||||||
|
noProxy,
|
||||||
|
})
|
||||||
|
}, 300)
|
||||||
|
return () => clearTimeout(handler)
|
||||||
|
}, [
|
||||||
|
noProxy,
|
||||||
|
proxyEnabled,
|
||||||
|
proxyIgnoreSSL,
|
||||||
|
proxyPassword,
|
||||||
|
proxyUrl,
|
||||||
|
proxyUsername,
|
||||||
|
verifyHostSSL,
|
||||||
|
verifyPeerSSL,
|
||||||
|
verifyProxyHostSSL,
|
||||||
|
verifyProxySSL,
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full">
|
||||||
@ -38,6 +99,8 @@ function HTTPSProxy() {
|
|||||||
<Input
|
<Input
|
||||||
className="w-full"
|
className="w-full"
|
||||||
placeholder="http://<user>:<password>@<domain or IP>:<port>"
|
placeholder="http://<user>:<password>@<domain or IP>:<port>"
|
||||||
|
value={proxyUrl}
|
||||||
|
onChange={(e) => setProxyUrl(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -49,12 +112,18 @@ function HTTPSProxy() {
|
|||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<p>Credentials for your proxy server (if required).</p>
|
<p>Credentials for your proxy server (if required).</p>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Input placeholder="Username" />
|
<Input
|
||||||
|
placeholder="Username"
|
||||||
|
value={proxyUsername}
|
||||||
|
onChange={(e) => setProxyUsername(e.target.value)}
|
||||||
|
/>
|
||||||
<div className="relative shrink-0 w-1/2">
|
<div className="relative shrink-0 w-1/2">
|
||||||
<Input
|
<Input
|
||||||
type={showPassword ? 'text' : 'password'}
|
type={showPassword ? 'text' : 'password'}
|
||||||
placeholder="Password"
|
placeholder="Password"
|
||||||
className="pr-16"
|
className="pr-16"
|
||||||
|
value={proxyPassword}
|
||||||
|
onChange={(e) => setProxyPassword(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<div className="absolute right-2 top-1/2 transform -translate-y-1/2 flex items-center gap-1">
|
<div className="absolute right-2 top-1/2 transform -translate-y-1/2 flex items-center gap-1">
|
||||||
<button
|
<button
|
||||||
@ -79,7 +148,11 @@ function HTTPSProxy() {
|
|||||||
description={
|
description={
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<p>List of hosts that should bypass the proxy.</p>
|
<p>List of hosts that should bypass the proxy.</p>
|
||||||
<Input placeholder="localhost, 127.0.0.1" />
|
<Input
|
||||||
|
placeholder="localhost, 127.0.0.1"
|
||||||
|
value={noProxy}
|
||||||
|
onChange={(e) => setNoProxy(e.target.value)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -90,27 +163,54 @@ function HTTPSProxy() {
|
|||||||
<CardItem
|
<CardItem
|
||||||
title="Ignore SSL Certificates"
|
title="Ignore SSL Certificates"
|
||||||
description="Allow self-signed or unverified certificates (may be required for certain proxies). Enable this reduces security. Only use this if you trust your proxy server."
|
description="Allow self-signed or unverified certificates (may be required for certain proxies). Enable this reduces security. Only use this if you trust your proxy server."
|
||||||
actions={<Switch />}
|
actions={
|
||||||
|
<Switch
|
||||||
|
checked={proxyIgnoreSSL}
|
||||||
|
onCheckedChange={(checked) => setProxyIgnoreSSL(checked)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<CardItem
|
<CardItem
|
||||||
title="Proxy SSL"
|
title="Proxy SSL"
|
||||||
description="Validate SSL certificate when connecting to the proxy server."
|
description="Validate SSL certificate when connecting to the proxy server."
|
||||||
actions={<Switch />}
|
actions={
|
||||||
|
<Switch
|
||||||
|
checked={verifyProxySSL}
|
||||||
|
onCheckedChange={(checked) => setVerifyProxySSL(checked)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<CardItem
|
<CardItem
|
||||||
title="Proxy Host SSL"
|
title="Proxy Host SSL"
|
||||||
description="Validate SSL certificate of the proxy server host."
|
description="Validate SSL certificate of the proxy server host."
|
||||||
actions={<Switch />}
|
actions={
|
||||||
|
<Switch
|
||||||
|
checked={verifyProxyHostSSL}
|
||||||
|
onCheckedChange={(checked) =>
|
||||||
|
setVerifyProxyHostSSL(checked)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<CardItem
|
<CardItem
|
||||||
title="Peer SSL"
|
title="Peer SSL"
|
||||||
description="Validate SSL certificate of the peer connections."
|
description="Validate SSL certificate of the peer connections."
|
||||||
actions={<Switch />}
|
actions={
|
||||||
|
<Switch
|
||||||
|
checked={verifyPeerSSL}
|
||||||
|
onCheckedChange={(checked) => setVerifyPeerSSL(checked)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<CardItem
|
<CardItem
|
||||||
title="Host SSL"
|
title="Host SSL"
|
||||||
description="Validate SSL certificate of destination hosts."
|
description="Validate SSL certificate of destination hosts."
|
||||||
actions={<Switch />}
|
actions={
|
||||||
|
<Switch
|
||||||
|
checked={verifyHostSSL}
|
||||||
|
onCheckedChange={(checked) => setVerifyHostSSL(checked)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -127,6 +127,16 @@ function MCPServers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toggleServer = (serverKey: string, active: boolean) => {
|
||||||
|
if (serverKey) {
|
||||||
|
// Save single server
|
||||||
|
editServer(serverKey, {
|
||||||
|
...(mcpServers[serverKey] as MCPServerConfig),
|
||||||
|
active,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full">
|
||||||
<HeaderPage>
|
<HeaderPage>
|
||||||
@ -245,7 +255,12 @@ function MCPServers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-2">
|
<div className="ml-2">
|
||||||
<Switch />
|
<Switch
|
||||||
|
checked={config.active === false ? false : true}
|
||||||
|
onCheckedChange={(checked) =>
|
||||||
|
toggleServer(key, checked)
|
||||||
|
}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -167,3 +167,54 @@ export const deleteModel = async (id: string) => {
|
|||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the proxy options for model downloads.
|
||||||
|
* @param param0
|
||||||
|
*/
|
||||||
|
export const configurePullOptions = async ({
|
||||||
|
proxyEnabled,
|
||||||
|
proxyUrl,
|
||||||
|
proxyUsername,
|
||||||
|
proxyPassword,
|
||||||
|
proxyIgnoreSSL,
|
||||||
|
verifyProxySSL,
|
||||||
|
verifyProxyHostSSL,
|
||||||
|
verifyPeerSSL,
|
||||||
|
verifyHostSSL,
|
||||||
|
noProxy,
|
||||||
|
}: ProxyOptions) => {
|
||||||
|
const extension = ExtensionManager.getInstance().get<ModelExtension>(
|
||||||
|
ExtensionTypeEnum.Model
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!extension) throw new Error('Model extension not found')
|
||||||
|
try {
|
||||||
|
await extension.configurePullOptions(
|
||||||
|
proxyEnabled
|
||||||
|
? {
|
||||||
|
proxy_username: proxyUsername,
|
||||||
|
proxy_password: proxyPassword,
|
||||||
|
proxy_url: proxyUrl,
|
||||||
|
verify_proxy_ssl: proxyIgnoreSSL ? false : verifyProxySSL,
|
||||||
|
verify_proxy_host_ssl: proxyIgnoreSSL ? false : verifyProxyHostSSL,
|
||||||
|
verify_peer_ssl: proxyIgnoreSSL ? false : verifyPeerSSL,
|
||||||
|
verify_host_ssl: proxyIgnoreSSL ? false : verifyHostSSL,
|
||||||
|
no_proxy: noProxy,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
proxy_username: '',
|
||||||
|
proxy_password: '',
|
||||||
|
proxy_url: '',
|
||||||
|
verify_proxy_ssl: false,
|
||||||
|
verify_proxy_host_ssl: false,
|
||||||
|
verify_peer_ssl: false,
|
||||||
|
verify_host_ssl: false,
|
||||||
|
no_proxy: '',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to configure pull options:', error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
17
web-app/src/types/modelProviders.d.ts
vendored
17
web-app/src/types/modelProviders.d.ts
vendored
@ -51,3 +51,20 @@ type ProviderObject = {
|
|||||||
* The model provider type
|
* The model provider type
|
||||||
*/
|
*/
|
||||||
type ModelProvider = ProviderObject
|
type ModelProvider = ProviderObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy configuration options
|
||||||
|
* @description This type defines the structure of the proxy configuration options.
|
||||||
|
*/
|
||||||
|
type ProxyOptions = {
|
||||||
|
proxyEnabled: boolean
|
||||||
|
proxyUrl: string
|
||||||
|
proxyUsername: string
|
||||||
|
proxyPassword: string
|
||||||
|
proxyIgnoreSSL: boolean
|
||||||
|
verifyProxySSL: boolean
|
||||||
|
verifyProxyHostSSL: boolean
|
||||||
|
verifyPeerSSL: boolean
|
||||||
|
verifyHostSSL: boolean
|
||||||
|
noProxy: string
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user