refactor: Enums
This commit is contained in:
parent
7f5284d597
commit
ee9efae203
|
|
@ -919,11 +919,11 @@ export class MCPClient {
|
||||||
async runHealthCheck(server: HealthCheckParams): Promise<void> {
|
async runHealthCheck(server: HealthCheckParams): Promise<void> {
|
||||||
const trimmedUrl = server.url.trim();
|
const trimmedUrl = server.url.trim();
|
||||||
const logs: MCPConnectionLog[] = [];
|
const logs: MCPConnectionLog[] = [];
|
||||||
let currentPhase: MCPConnectionPhase = MCPConnectionPhase.Idle;
|
let currentPhase: MCPConnectionPhase = MCPConnectionPhase.IDLE;
|
||||||
|
|
||||||
if (!trimmedUrl) {
|
if (!trimmedUrl) {
|
||||||
mcpStore.updateHealthCheck(server.id, {
|
mcpStore.updateHealthCheck(server.id, {
|
||||||
status: HealthCheckStatus.Error,
|
status: HealthCheckStatus.ERROR,
|
||||||
message: 'Please enter a server URL first.',
|
message: 'Please enter a server URL first.',
|
||||||
logs: []
|
logs: []
|
||||||
});
|
});
|
||||||
|
|
@ -932,8 +932,8 @@ export class MCPClient {
|
||||||
|
|
||||||
// Initial connecting state
|
// Initial connecting state
|
||||||
mcpStore.updateHealthCheck(server.id, {
|
mcpStore.updateHealthCheck(server.id, {
|
||||||
status: HealthCheckStatus.Connecting,
|
status: HealthCheckStatus.CONNECTING,
|
||||||
phase: MCPConnectionPhase.TransportCreating,
|
phase: MCPConnectionPhase.TRANSPORT_CREATING,
|
||||||
logs: []
|
logs: []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -957,7 +957,7 @@ export class MCPClient {
|
||||||
currentPhase = phase;
|
currentPhase = phase;
|
||||||
logs.push(log);
|
logs.push(log);
|
||||||
mcpStore.updateHealthCheck(server.id, {
|
mcpStore.updateHealthCheck(server.id, {
|
||||||
status: HealthCheckStatus.Connecting,
|
status: HealthCheckStatus.CONNECTING,
|
||||||
phase,
|
phase,
|
||||||
logs: [...logs]
|
logs: [...logs]
|
||||||
});
|
});
|
||||||
|
|
@ -976,7 +976,7 @@ export class MCPClient {
|
||||||
);
|
);
|
||||||
|
|
||||||
mcpStore.updateHealthCheck(server.id, {
|
mcpStore.updateHealthCheck(server.id, {
|
||||||
status: HealthCheckStatus.Success,
|
status: HealthCheckStatus.SUCCESS,
|
||||||
tools,
|
tools,
|
||||||
serverInfo: connection.serverInfo,
|
serverInfo: connection.serverInfo,
|
||||||
capabilities,
|
capabilities,
|
||||||
|
|
@ -992,12 +992,12 @@ export class MCPClient {
|
||||||
const message = error instanceof Error ? error.message : 'Unknown error occurred';
|
const message = error instanceof Error ? error.message : 'Unknown error occurred';
|
||||||
logs.push({
|
logs.push({
|
||||||
timestamp: new Date(),
|
timestamp: new Date(),
|
||||||
phase: MCPConnectionPhase.Error,
|
phase: MCPConnectionPhase.ERROR,
|
||||||
message: `Connection failed: ${message}`,
|
message: `Connection failed: ${message}`,
|
||||||
level: MCPLogLevel.Error
|
level: MCPLogLevel.ERROR
|
||||||
});
|
});
|
||||||
mcpStore.updateHealthCheck(server.id, {
|
mcpStore.updateHealthCheck(server.id, {
|
||||||
status: HealthCheckStatus.Error,
|
status: HealthCheckStatus.ERROR,
|
||||||
message,
|
message,
|
||||||
phase: currentPhase,
|
phase: currentPhase,
|
||||||
logs
|
logs
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ChatMessageMcpPromptContent, RemoveButton } from '$lib/components/app';
|
import { ChatMessageMcpPromptContent, RemoveButton } from '$lib/components/app';
|
||||||
import type { DatabaseMessageExtraMcpPrompt } from '$lib/types';
|
import type { DatabaseMessageExtraMcpPrompt } from '$lib/types';
|
||||||
|
import { McpPromptVariant } from '$lib/enums';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
class?: string;
|
class?: string;
|
||||||
|
|
@ -22,7 +23,12 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="group relative {className}">
|
<div class="group relative {className}">
|
||||||
<ChatMessageMcpPromptContent {prompt} variant="attachment" {isLoading} {loadError} />
|
<ChatMessageMcpPromptContent
|
||||||
|
{prompt}
|
||||||
|
variant={McpPromptVariant.ATTACHMENT}
|
||||||
|
{isLoading}
|
||||||
|
{loadError}
|
||||||
|
/>
|
||||||
|
|
||||||
{#if !readonly && onRemove}
|
{#if !readonly && onRemove}
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReasoningSegment = {
|
type ReasoningSegment = {
|
||||||
type: 'text' | 'reasoning' | 'reasoning_pending';
|
type:
|
||||||
|
| AgenticSectionType.TEXT
|
||||||
|
| AgenticSectionType.REASONING
|
||||||
|
| AgenticSectionType.REASONING_PENDING;
|
||||||
content: string;
|
content: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -90,7 +93,7 @@
|
||||||
if (startIndex === -1) {
|
if (startIndex === -1) {
|
||||||
const remainingText = rawContent.slice(cursor);
|
const remainingText = rawContent.slice(cursor);
|
||||||
if (remainingText) {
|
if (remainingText) {
|
||||||
segments.push({ type: 'text', content: remainingText });
|
segments.push({ type: AgenticSectionType.TEXT, content: remainingText });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +101,7 @@
|
||||||
if (startIndex > cursor) {
|
if (startIndex > cursor) {
|
||||||
const textBefore = rawContent.slice(cursor, startIndex);
|
const textBefore = rawContent.slice(cursor, startIndex);
|
||||||
if (textBefore) {
|
if (textBefore) {
|
||||||
segments.push({ type: 'text', content: textBefore });
|
segments.push({ type: AgenticSectionType.TEXT, content: textBefore });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,14 +111,14 @@
|
||||||
if (endIndex === -1) {
|
if (endIndex === -1) {
|
||||||
const pendingContent = rawContent.slice(contentStart);
|
const pendingContent = rawContent.slice(contentStart);
|
||||||
segments.push({
|
segments.push({
|
||||||
type: 'reasoning_pending',
|
type: AgenticSectionType.REASONING_PENDING,
|
||||||
content: stripPartialMarker(pendingContent)
|
content: stripPartialMarker(pendingContent)
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const reasoningContent = rawContent.slice(contentStart, endIndex);
|
const reasoningContent = rawContent.slice(contentStart, endIndex);
|
||||||
segments.push({ type: 'reasoning', content: reasoningContent });
|
segments.push({ type: AgenticSectionType.REASONING, content: reasoningContent });
|
||||||
cursor = endIndex + REASONING_TAGS.END.length;
|
cursor = endIndex + REASONING_TAGS.END.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ChatMessageActions, ChatMessageMcpPromptContent } from '$lib/components/app';
|
import { ChatMessageActions, ChatMessageMcpPromptContent } from '$lib/components/app';
|
||||||
import { MessageRole } from '$lib/enums';
|
import { MessageRole, McpPromptVariant } from '$lib/enums';
|
||||||
import type { DatabaseMessageExtraMcpPrompt } from '$lib/types';
|
import type { DatabaseMessageExtraMcpPrompt } from '$lib/types';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
@ -44,7 +44,11 @@
|
||||||
class="group flex flex-col items-end gap-3 md:gap-2 {className}"
|
class="group flex flex-col items-end gap-3 md:gap-2 {className}"
|
||||||
role="group"
|
role="group"
|
||||||
>
|
>
|
||||||
<ChatMessageMcpPromptContent prompt={mcpPrompt} variant="message" class="w-full max-w-[80%]" />
|
<ChatMessageMcpPromptContent
|
||||||
|
prompt={mcpPrompt}
|
||||||
|
variant={McpPromptVariant.MESSAGE}
|
||||||
|
class="w-full max-w-[80%]"
|
||||||
|
/>
|
||||||
|
|
||||||
{#if message.timestamp}
|
{#if message.timestamp}
|
||||||
<div class="max-w-[80%]">
|
<div class="max-w-[80%]">
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
import { getFaviconUrl } from '$lib/utils';
|
import { getFaviconUrl } from '$lib/utils';
|
||||||
import { mcpStore } from '$lib/stores/mcp.svelte';
|
import { mcpStore } from '$lib/stores/mcp.svelte';
|
||||||
import { SvelteMap } from 'svelte/reactivity';
|
import { SvelteMap } from 'svelte/reactivity';
|
||||||
|
import { McpPromptVariant } from '$lib/enums';
|
||||||
|
|
||||||
interface ContentPart {
|
interface ContentPart {
|
||||||
text: string;
|
text: string;
|
||||||
|
|
@ -13,7 +14,7 @@
|
||||||
interface Props {
|
interface Props {
|
||||||
class?: string;
|
class?: string;
|
||||||
prompt: DatabaseMessageExtraMcpPrompt;
|
prompt: DatabaseMessageExtraMcpPrompt;
|
||||||
variant?: 'message' | 'attachment';
|
variant?: McpPromptVariant;
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
loadError?: string;
|
loadError?: string;
|
||||||
}
|
}
|
||||||
|
|
@ -21,7 +22,7 @@
|
||||||
let {
|
let {
|
||||||
class: className = '',
|
class: className = '',
|
||||||
prompt,
|
prompt,
|
||||||
variant = 'message',
|
variant = McpPromptVariant.MESSAGE,
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
loadError
|
loadError
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
@ -99,7 +100,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
let showArgBadges = $derived(hasArguments && !isLoading && !loadError);
|
let showArgBadges = $derived(hasArguments && !isLoading && !loadError);
|
||||||
let isAttachment = $derived(variant === 'attachment');
|
let isAttachment = $derived(variant === McpPromptVariant.ATTACHMENT);
|
||||||
let textSizeClass = $derived(isAttachment ? 'text-sm' : 'text-md');
|
let textSizeClass = $derived(isAttachment ? 'text-sm' : 'text-md');
|
||||||
let maxHeightStyle = $derived(
|
let maxHeightStyle = $derived(
|
||||||
isAttachment
|
isAttachment
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
let healthyEnabledMcpServers = $derived(
|
let healthyEnabledMcpServers = $derived(
|
||||||
enabledMcpServersForChat.filter((s) => {
|
enabledMcpServersForChat.filter((s) => {
|
||||||
const healthState = mcpStore.getHealthCheckState(s.id);
|
const healthState = mcpStore.getHealthCheckState(s.id);
|
||||||
return healthState.status !== HealthCheckStatus.Error;
|
return healthState.status !== HealthCheckStatus.ERROR;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
let hasEnabledMcpServers = $derived(enabledMcpServersForChat.length > 0);
|
let hasEnabledMcpServers = $derived(enabledMcpServersForChat.length > 0);
|
||||||
|
|
|
||||||
|
|
@ -27,41 +27,41 @@
|
||||||
|
|
||||||
let healthState = $derived<HealthCheckState>(mcpStore.getHealthCheckState(server.id));
|
let healthState = $derived<HealthCheckState>(mcpStore.getHealthCheckState(server.id));
|
||||||
let displayName = $derived(mcpStore.getServerLabel(server));
|
let displayName = $derived(mcpStore.getServerLabel(server));
|
||||||
let isIdle = $derived(healthState.status === HealthCheckStatus.Idle);
|
let isIdle = $derived(healthState.status === HealthCheckStatus.IDLE);
|
||||||
let isHealthChecking = $derived(healthState.status === HealthCheckStatus.Connecting);
|
let isHealthChecking = $derived(healthState.status === HealthCheckStatus.CONNECTING);
|
||||||
let isConnected = $derived(healthState.status === HealthCheckStatus.Success);
|
let isConnected = $derived(healthState.status === HealthCheckStatus.SUCCESS);
|
||||||
let isError = $derived(healthState.status === HealthCheckStatus.Error);
|
let isError = $derived(healthState.status === HealthCheckStatus.ERROR);
|
||||||
let showSkeleton = $derived(isIdle || isHealthChecking);
|
let showSkeleton = $derived(isIdle || isHealthChecking);
|
||||||
let errorMessage = $derived(
|
let errorMessage = $derived(
|
||||||
healthState.status === HealthCheckStatus.Error ? healthState.message : undefined
|
healthState.status === HealthCheckStatus.ERROR ? healthState.message : undefined
|
||||||
);
|
);
|
||||||
let tools = $derived(healthState.status === HealthCheckStatus.Success ? healthState.tools : []);
|
let tools = $derived(healthState.status === HealthCheckStatus.SUCCESS ? healthState.tools : []);
|
||||||
|
|
||||||
let connectionLogs = $derived(
|
let connectionLogs = $derived(
|
||||||
healthState.status === HealthCheckStatus.Connecting ||
|
healthState.status === HealthCheckStatus.CONNECTING ||
|
||||||
healthState.status === HealthCheckStatus.Success ||
|
healthState.status === HealthCheckStatus.SUCCESS ||
|
||||||
healthState.status === HealthCheckStatus.Error
|
healthState.status === HealthCheckStatus.ERROR
|
||||||
? healthState.logs
|
? healthState.logs
|
||||||
: []
|
: []
|
||||||
);
|
);
|
||||||
|
|
||||||
let serverInfo = $derived(
|
let serverInfo = $derived(
|
||||||
healthState.status === HealthCheckStatus.Success ? healthState.serverInfo : undefined
|
healthState.status === HealthCheckStatus.SUCCESS ? healthState.serverInfo : undefined
|
||||||
);
|
);
|
||||||
let capabilities = $derived(
|
let capabilities = $derived(
|
||||||
healthState.status === HealthCheckStatus.Success ? healthState.capabilities : undefined
|
healthState.status === HealthCheckStatus.SUCCESS ? healthState.capabilities : undefined
|
||||||
);
|
);
|
||||||
let transportType = $derived(
|
let transportType = $derived(
|
||||||
healthState.status === HealthCheckStatus.Success ? healthState.transportType : undefined
|
healthState.status === HealthCheckStatus.SUCCESS ? healthState.transportType : undefined
|
||||||
);
|
);
|
||||||
let protocolVersion = $derived(
|
let protocolVersion = $derived(
|
||||||
healthState.status === HealthCheckStatus.Success ? healthState.protocolVersion : undefined
|
healthState.status === HealthCheckStatus.SUCCESS ? healthState.protocolVersion : undefined
|
||||||
);
|
);
|
||||||
let connectionTimeMs = $derived(
|
let connectionTimeMs = $derived(
|
||||||
healthState.status === HealthCheckStatus.Success ? healthState.connectionTimeMs : undefined
|
healthState.status === HealthCheckStatus.SUCCESS ? healthState.connectionTimeMs : undefined
|
||||||
);
|
);
|
||||||
let instructions = $derived(
|
let instructions = $derived(
|
||||||
healthState.status === HealthCheckStatus.Success ? healthState.instructions : undefined
|
healthState.status === HealthCheckStatus.SUCCESS ? healthState.instructions : undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
let isEditing = $state(!server.url.trim());
|
let isEditing = $state(!server.url.trim());
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,14 @@
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
const transportLabels: Record<MCPTransportType, string> = {
|
const transportLabels: Record<MCPTransportType, string> = {
|
||||||
[MCPTransportType.Websocket]: 'WebSocket',
|
[MCPTransportType.WEBSOCKET]: 'WebSocket',
|
||||||
[MCPTransportType.StreamableHttp]: 'HTTP',
|
[MCPTransportType.STREAMABLE_HTTP]: 'HTTP',
|
||||||
[MCPTransportType.SSE]: 'SSE'
|
[MCPTransportType.SSE]: 'SSE'
|
||||||
};
|
};
|
||||||
|
|
||||||
const transportIcons: Record<MCPTransportType, typeof Cable> = {
|
const transportIcons: Record<MCPTransportType, typeof Cable> = {
|
||||||
[MCPTransportType.Websocket]: Zap,
|
[MCPTransportType.WEBSOCKET]: Zap,
|
||||||
[MCPTransportType.StreamableHttp]: Globe,
|
[MCPTransportType.STREAMABLE_HTTP]: Globe,
|
||||||
[MCPTransportType.SSE]: Radio
|
[MCPTransportType.SSE]: Radio
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -26,3 +26,7 @@ export { MCPConnectionPhase, MCPLogLevel, MCPTransportType, HealthCheckStatus }
|
||||||
export { ModelModality } from './model';
|
export { ModelModality } from './model';
|
||||||
|
|
||||||
export { ServerRole, ServerModelStatus } from './server';
|
export { ServerRole, ServerModelStatus } from './server';
|
||||||
|
|
||||||
|
export { ParameterSource, SyncableParameterType } from './settings';
|
||||||
|
|
||||||
|
export { ColorMode, McpPromptVariant, UrlPrefix } from './ui';
|
||||||
|
|
|
||||||
|
|
@ -2,32 +2,32 @@
|
||||||
* Connection lifecycle phases for MCP protocol
|
* Connection lifecycle phases for MCP protocol
|
||||||
*/
|
*/
|
||||||
export enum MCPConnectionPhase {
|
export enum MCPConnectionPhase {
|
||||||
Idle = 'idle',
|
IDLE = 'idle',
|
||||||
TransportCreating = 'transport_creating',
|
TRANSPORT_CREATING = 'transport_creating',
|
||||||
TransportReady = 'transport_ready',
|
TRANSPORT_READY = 'transport_ready',
|
||||||
Initializing = 'initializing',
|
INITIALIZING = 'initializing',
|
||||||
CapabilitiesExchanged = 'capabilities_exchanged',
|
CAPABILITIES_EXCHANGED = 'capabilities_exchanged',
|
||||||
ListingTools = 'listing_tools',
|
LISTING_TOOLS = 'listing_tools',
|
||||||
Connected = 'connected',
|
CONNECTED = 'connected',
|
||||||
Error = 'error',
|
ERROR = 'error',
|
||||||
Disconnected = 'disconnected'
|
DISCONNECTED = 'disconnected'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log level for connection events
|
* Log level for connection events
|
||||||
*/
|
*/
|
||||||
export enum MCPLogLevel {
|
export enum MCPLogLevel {
|
||||||
Info = 'info',
|
INFO = 'info',
|
||||||
Warn = 'warn',
|
WARN = 'warn',
|
||||||
Error = 'error'
|
ERROR = 'error'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transport types for MCP connections
|
* Transport types for MCP connections
|
||||||
*/
|
*/
|
||||||
export enum MCPTransportType {
|
export enum MCPTransportType {
|
||||||
Websocket = 'websocket',
|
WEBSOCKET = 'websocket',
|
||||||
StreamableHttp = 'streamable_http',
|
STREAMABLE_HTTP = 'streamable_http',
|
||||||
SSE = 'sse'
|
SSE = 'sse'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,8 +35,8 @@ export enum MCPTransportType {
|
||||||
* Health check status for MCP servers
|
* Health check status for MCP servers
|
||||||
*/
|
*/
|
||||||
export enum HealthCheckStatus {
|
export enum HealthCheckStatus {
|
||||||
Idle = 'idle',
|
IDLE = 'idle',
|
||||||
Connecting = 'connecting',
|
CONNECTING = 'connecting',
|
||||||
Success = 'success',
|
SUCCESS = 'success',
|
||||||
Error = 'error'
|
ERROR = 'error'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
/**
|
||||||
|
* Parameter source - indicates whether a parameter uses default or custom value
|
||||||
|
*/
|
||||||
|
export enum ParameterSource {
|
||||||
|
DEFAULT = 'default',
|
||||||
|
CUSTOM = 'custom'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syncable parameter type - data types for parameters that can be synced with server
|
||||||
|
*/
|
||||||
|
export enum SyncableParameterType {
|
||||||
|
NUMBER = 'number',
|
||||||
|
STRING = 'string',
|
||||||
|
BOOLEAN = 'boolean'
|
||||||
|
}
|
||||||
|
|
@ -3,3 +3,22 @@ export enum ColorMode {
|
||||||
DARK = 'dark',
|
DARK = 'dark',
|
||||||
SYSTEM = 'system'
|
SYSTEM = 'system'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MCP prompt display variant
|
||||||
|
*/
|
||||||
|
export enum McpPromptVariant {
|
||||||
|
MESSAGE = 'message',
|
||||||
|
ATTACHMENT = 'attachment'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL prefixes for protocol detection
|
||||||
|
*/
|
||||||
|
export enum UrlPrefix {
|
||||||
|
DATA = 'data:',
|
||||||
|
HTTP = 'http://',
|
||||||
|
HTTPS = 'https://',
|
||||||
|
WEBSOCKET = 'ws://',
|
||||||
|
WEBSOCKET_SECURE = 'wss://'
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import type { Root as HastRoot } from 'hast';
|
import type { Root as HastRoot } from 'hast';
|
||||||
import { visit } from 'unist-util-visit';
|
import { visit } from 'unist-util-visit';
|
||||||
import type { DatabaseMessage, DatabaseMessageExtraImageFile } from '$lib/types/database';
|
import type { DatabaseMessage, DatabaseMessageExtraImageFile } from '$lib/types/database';
|
||||||
import { AttachmentType } from '$lib/enums';
|
import { AttachmentType, UrlPrefix } from '$lib/enums';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rehype plugin to resolve attachment image sources.
|
* Rehype plugin to resolve attachment image sources.
|
||||||
|
|
@ -14,7 +14,7 @@ export function rehypeResolveAttachmentImages(options: { message?: DatabaseMessa
|
||||||
const src = String(node.properties.src);
|
const src = String(node.properties.src);
|
||||||
|
|
||||||
// Skip data URLs and external URLs
|
// Skip data URLs and external URLs
|
||||||
if (src.startsWith('data:') || src.startsWith('http')) {
|
if (src.startsWith(UrlPrefix.DATA) || src.startsWith(UrlPrefix.HTTP)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ export class MCPService {
|
||||||
private static createLog(
|
private static createLog(
|
||||||
phase: MCPConnectionPhase,
|
phase: MCPConnectionPhase,
|
||||||
message: string,
|
message: string,
|
||||||
level: MCPLogLevel = MCPLogLevel.Info,
|
level: MCPLogLevel = MCPLogLevel.INFO,
|
||||||
details?: unknown
|
details?: unknown
|
||||||
): MCPConnectionLog {
|
): MCPConnectionLog {
|
||||||
return {
|
return {
|
||||||
|
|
@ -100,7 +100,7 @@ export class MCPService {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
transport: new WebSocketClientTransport(url),
|
transport: new WebSocketClientTransport(url),
|
||||||
type: MCPTransportType.Websocket
|
type: MCPTransportType.WEBSOCKET
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +112,7 @@ export class MCPService {
|
||||||
requestInit,
|
requestInit,
|
||||||
sessionId: config.sessionId
|
sessionId: config.sessionId
|
||||||
}),
|
}),
|
||||||
type: MCPTransportType.StreamableHttp
|
type: MCPTransportType.STREAMABLE_HTTP
|
||||||
};
|
};
|
||||||
} catch (httpError) {
|
} catch (httpError) {
|
||||||
console.warn(`[MCPService] StreamableHTTP failed, trying SSE transport...`, httpError);
|
console.warn(`[MCPService] StreamableHTTP failed, trying SSE transport...`, httpError);
|
||||||
|
|
@ -169,9 +169,9 @@ export class MCPService {
|
||||||
|
|
||||||
// Phase: Creating transport
|
// Phase: Creating transport
|
||||||
onPhase?.(
|
onPhase?.(
|
||||||
MCPConnectionPhase.TransportCreating,
|
MCPConnectionPhase.TRANSPORT_CREATING,
|
||||||
this.createLog(
|
this.createLog(
|
||||||
MCPConnectionPhase.TransportCreating,
|
MCPConnectionPhase.TRANSPORT_CREATING,
|
||||||
`Creating transport for ${serverConfig.url}`
|
`Creating transport for ${serverConfig.url}`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
@ -181,8 +181,8 @@ export class MCPService {
|
||||||
|
|
||||||
// Phase: Transport ready
|
// Phase: Transport ready
|
||||||
onPhase?.(
|
onPhase?.(
|
||||||
MCPConnectionPhase.TransportReady,
|
MCPConnectionPhase.TRANSPORT_READY,
|
||||||
this.createLog(MCPConnectionPhase.TransportReady, `Transport ready (${transportType})`),
|
this.createLog(MCPConnectionPhase.TRANSPORT_READY, `Transport ready (${transportType})`),
|
||||||
{ transportType }
|
{ transportType }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -199,8 +199,8 @@ export class MCPService {
|
||||||
|
|
||||||
// Phase: Initializing
|
// Phase: Initializing
|
||||||
onPhase?.(
|
onPhase?.(
|
||||||
MCPConnectionPhase.Initializing,
|
MCPConnectionPhase.INITIALIZING,
|
||||||
this.createLog(MCPConnectionPhase.Initializing, 'Sending initialize request...')
|
this.createLog(MCPConnectionPhase.INITIALIZING, 'Sending initialize request...')
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`[MCPService][${serverName}] Connecting to server...`);
|
console.log(`[MCPService][${serverName}] Connecting to server...`);
|
||||||
|
|
@ -213,11 +213,11 @@ export class MCPService {
|
||||||
|
|
||||||
// Phase: Capabilities exchanged
|
// Phase: Capabilities exchanged
|
||||||
onPhase?.(
|
onPhase?.(
|
||||||
MCPConnectionPhase.CapabilitiesExchanged,
|
MCPConnectionPhase.CAPABILITIES_EXCHANGED,
|
||||||
this.createLog(
|
this.createLog(
|
||||||
MCPConnectionPhase.CapabilitiesExchanged,
|
MCPConnectionPhase.CAPABILITIES_EXCHANGED,
|
||||||
'Capabilities exchanged successfully',
|
'Capabilities exchanged successfully',
|
||||||
MCPLogLevel.Info,
|
MCPLogLevel.INFO,
|
||||||
{
|
{
|
||||||
serverCapabilities,
|
serverCapabilities,
|
||||||
serverInfo
|
serverInfo
|
||||||
|
|
@ -233,8 +233,8 @@ export class MCPService {
|
||||||
|
|
||||||
// Phase: Listing tools
|
// Phase: Listing tools
|
||||||
onPhase?.(
|
onPhase?.(
|
||||||
MCPConnectionPhase.ListingTools,
|
MCPConnectionPhase.LISTING_TOOLS,
|
||||||
this.createLog(MCPConnectionPhase.ListingTools, 'Listing available tools...')
|
this.createLog(MCPConnectionPhase.LISTING_TOOLS, 'Listing available tools...')
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`[MCPService][${serverName}] Connected, listing tools...`);
|
console.log(`[MCPService][${serverName}] Connected, listing tools...`);
|
||||||
|
|
@ -251,9 +251,9 @@ export class MCPService {
|
||||||
|
|
||||||
// Phase: Connected
|
// Phase: Connected
|
||||||
onPhase?.(
|
onPhase?.(
|
||||||
MCPConnectionPhase.Connected,
|
MCPConnectionPhase.CONNECTED,
|
||||||
this.createLog(
|
this.createLog(
|
||||||
MCPConnectionPhase.Connected,
|
MCPConnectionPhase.CONNECTED,
|
||||||
`Connection established with ${tools.length} tools (${connectionTimeMs}ms)`
|
`Connection established with ${tools.length} tools (${connectionTimeMs}ms)`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -13,77 +13,157 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { normalizeFloatingPoint } from '$lib/utils';
|
import { normalizeFloatingPoint } from '$lib/utils';
|
||||||
import type {
|
import type { SyncableParameter, ParameterRecord, ParameterInfo, ParameterValue } from '$lib/types';
|
||||||
SyncableParameter,
|
import { SyncableParameterType, ParameterSource } from '$lib/enums';
|
||||||
ParameterRecord,
|
|
||||||
ParameterInfo,
|
|
||||||
ParameterValue,
|
|
||||||
ParameterSource
|
|
||||||
} from '$lib/types';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapping of webui setting keys to server parameter keys
|
* Mapping of webui setting keys to server parameter keys
|
||||||
* Only parameters that should be synced from server are included
|
* Only parameters that should be synced from server are included
|
||||||
*/
|
*/
|
||||||
export const SYNCABLE_PARAMETERS: SyncableParameter[] = [
|
export const SYNCABLE_PARAMETERS: SyncableParameter[] = [
|
||||||
{ key: 'temperature', serverKey: 'temperature', type: 'number', canSync: true },
|
{
|
||||||
{ key: 'top_k', serverKey: 'top_k', type: 'number', canSync: true },
|
key: 'temperature',
|
||||||
{ key: 'top_p', serverKey: 'top_p', type: 'number', canSync: true },
|
serverKey: 'temperature',
|
||||||
{ key: 'min_p', serverKey: 'min_p', type: 'number', canSync: true },
|
type: SyncableParameterType.NUMBER,
|
||||||
{ key: 'dynatemp_range', serverKey: 'dynatemp_range', type: 'number', canSync: true },
|
canSync: true
|
||||||
{ key: 'dynatemp_exponent', serverKey: 'dynatemp_exponent', type: 'number', canSync: true },
|
},
|
||||||
{ key: 'xtc_probability', serverKey: 'xtc_probability', type: 'number', canSync: true },
|
{ key: 'top_k', serverKey: 'top_k', type: SyncableParameterType.NUMBER, canSync: true },
|
||||||
{ key: 'xtc_threshold', serverKey: 'xtc_threshold', type: 'number', canSync: true },
|
{ key: 'top_p', serverKey: 'top_p', type: SyncableParameterType.NUMBER, canSync: true },
|
||||||
{ key: 'typ_p', serverKey: 'typ_p', type: 'number', canSync: true },
|
{ key: 'min_p', serverKey: 'min_p', type: SyncableParameterType.NUMBER, canSync: true },
|
||||||
{ key: 'repeat_last_n', serverKey: 'repeat_last_n', type: 'number', canSync: true },
|
{
|
||||||
{ key: 'repeat_penalty', serverKey: 'repeat_penalty', type: 'number', canSync: true },
|
key: 'dynatemp_range',
|
||||||
{ key: 'presence_penalty', serverKey: 'presence_penalty', type: 'number', canSync: true },
|
serverKey: 'dynatemp_range',
|
||||||
{ key: 'frequency_penalty', serverKey: 'frequency_penalty', type: 'number', canSync: true },
|
type: SyncableParameterType.NUMBER,
|
||||||
{ key: 'dry_multiplier', serverKey: 'dry_multiplier', type: 'number', canSync: true },
|
canSync: true
|
||||||
{ key: 'dry_base', serverKey: 'dry_base', type: 'number', canSync: true },
|
},
|
||||||
{ key: 'dry_allowed_length', serverKey: 'dry_allowed_length', type: 'number', canSync: true },
|
{
|
||||||
{ key: 'dry_penalty_last_n', serverKey: 'dry_penalty_last_n', type: 'number', canSync: true },
|
key: 'dynatemp_exponent',
|
||||||
{ key: 'max_tokens', serverKey: 'max_tokens', type: 'number', canSync: true },
|
serverKey: 'dynatemp_exponent',
|
||||||
{ key: 'samplers', serverKey: 'samplers', type: 'string', canSync: true },
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'xtc_probability',
|
||||||
|
serverKey: 'xtc_probability',
|
||||||
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'xtc_threshold',
|
||||||
|
serverKey: 'xtc_threshold',
|
||||||
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{ key: 'typ_p', serverKey: 'typ_p', type: SyncableParameterType.NUMBER, canSync: true },
|
||||||
|
{
|
||||||
|
key: 'repeat_last_n',
|
||||||
|
serverKey: 'repeat_last_n',
|
||||||
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'repeat_penalty',
|
||||||
|
serverKey: 'repeat_penalty',
|
||||||
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'presence_penalty',
|
||||||
|
serverKey: 'presence_penalty',
|
||||||
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'frequency_penalty',
|
||||||
|
serverKey: 'frequency_penalty',
|
||||||
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'dry_multiplier',
|
||||||
|
serverKey: 'dry_multiplier',
|
||||||
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{ key: 'dry_base', serverKey: 'dry_base', type: SyncableParameterType.NUMBER, canSync: true },
|
||||||
|
{
|
||||||
|
key: 'dry_allowed_length',
|
||||||
|
serverKey: 'dry_allowed_length',
|
||||||
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'dry_penalty_last_n',
|
||||||
|
serverKey: 'dry_penalty_last_n',
|
||||||
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{ key: 'max_tokens', serverKey: 'max_tokens', type: SyncableParameterType.NUMBER, canSync: true },
|
||||||
|
{ key: 'samplers', serverKey: 'samplers', type: SyncableParameterType.STRING, canSync: true },
|
||||||
{
|
{
|
||||||
key: 'pasteLongTextToFileLen',
|
key: 'pasteLongTextToFileLen',
|
||||||
serverKey: 'pasteLongTextToFileLen',
|
serverKey: 'pasteLongTextToFileLen',
|
||||||
type: 'number',
|
type: SyncableParameterType.NUMBER,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'pdfAsImage',
|
||||||
|
serverKey: 'pdfAsImage',
|
||||||
|
type: SyncableParameterType.BOOLEAN,
|
||||||
canSync: true
|
canSync: true
|
||||||
},
|
},
|
||||||
{ key: 'pdfAsImage', serverKey: 'pdfAsImage', type: 'boolean', canSync: true },
|
|
||||||
{
|
{
|
||||||
key: 'showThoughtInProgress',
|
key: 'showThoughtInProgress',
|
||||||
serverKey: 'showThoughtInProgress',
|
serverKey: 'showThoughtInProgress',
|
||||||
type: 'boolean',
|
type: SyncableParameterType.BOOLEAN,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'keepStatsVisible',
|
||||||
|
serverKey: 'keepStatsVisible',
|
||||||
|
type: SyncableParameterType.BOOLEAN,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'showMessageStats',
|
||||||
|
serverKey: 'showMessageStats',
|
||||||
|
type: SyncableParameterType.BOOLEAN,
|
||||||
canSync: true
|
canSync: true
|
||||||
},
|
},
|
||||||
{ key: 'keepStatsVisible', serverKey: 'keepStatsVisible', type: 'boolean', canSync: true },
|
|
||||||
{ key: 'showMessageStats', serverKey: 'showMessageStats', type: 'boolean', canSync: true },
|
|
||||||
{
|
{
|
||||||
key: 'askForTitleConfirmation',
|
key: 'askForTitleConfirmation',
|
||||||
serverKey: 'askForTitleConfirmation',
|
serverKey: 'askForTitleConfirmation',
|
||||||
type: 'boolean',
|
type: SyncableParameterType.BOOLEAN,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'disableAutoScroll',
|
||||||
|
serverKey: 'disableAutoScroll',
|
||||||
|
type: SyncableParameterType.BOOLEAN,
|
||||||
canSync: true
|
canSync: true
|
||||||
},
|
},
|
||||||
{ key: 'disableAutoScroll', serverKey: 'disableAutoScroll', type: 'boolean', canSync: true },
|
|
||||||
{
|
{
|
||||||
key: 'renderUserContentAsMarkdown',
|
key: 'renderUserContentAsMarkdown',
|
||||||
serverKey: 'renderUserContentAsMarkdown',
|
serverKey: 'renderUserContentAsMarkdown',
|
||||||
type: 'boolean',
|
type: SyncableParameterType.BOOLEAN,
|
||||||
|
canSync: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'autoMicOnEmpty',
|
||||||
|
serverKey: 'autoMicOnEmpty',
|
||||||
|
type: SyncableParameterType.BOOLEAN,
|
||||||
canSync: true
|
canSync: true
|
||||||
},
|
},
|
||||||
{ key: 'autoMicOnEmpty', serverKey: 'autoMicOnEmpty', type: 'boolean', canSync: true },
|
|
||||||
{
|
{
|
||||||
key: 'pyInterpreterEnabled',
|
key: 'pyInterpreterEnabled',
|
||||||
serverKey: 'pyInterpreterEnabled',
|
serverKey: 'pyInterpreterEnabled',
|
||||||
type: 'boolean',
|
type: SyncableParameterType.BOOLEAN,
|
||||||
canSync: true
|
canSync: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'enableContinueGeneration',
|
key: 'enableContinueGeneration',
|
||||||
serverKey: 'enableContinueGeneration',
|
serverKey: 'enableContinueGeneration',
|
||||||
type: 'boolean',
|
type: SyncableParameterType.BOOLEAN,
|
||||||
canSync: true
|
canSync: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
@ -196,7 +276,7 @@ export class ParameterSyncService {
|
||||||
const isUserOverride = userOverrides.has(key);
|
const isUserOverride = userOverrides.has(key);
|
||||||
|
|
||||||
// Simple logic: either using default (from props) or custom (user override)
|
// Simple logic: either using default (from props) or custom (user override)
|
||||||
const source: ParameterSource = isUserOverride ? 'custom' : 'default';
|
const source = isUserOverride ? ParameterSource.CUSTOM : ParameterSource.DEFAULT;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
value: currentValue,
|
value: currentValue,
|
||||||
|
|
@ -228,11 +308,11 @@ export class ParameterSyncService {
|
||||||
if (!param) return false;
|
if (!param) return false;
|
||||||
|
|
||||||
switch (param.type) {
|
switch (param.type) {
|
||||||
case 'number':
|
case SyncableParameterType.NUMBER:
|
||||||
return typeof value === 'number' && !isNaN(value);
|
return typeof value === 'number' && !isNaN(value);
|
||||||
case 'string':
|
case SyncableParameterType.STRING:
|
||||||
return typeof value === 'string';
|
return typeof value === 'string';
|
||||||
case 'boolean':
|
case SyncableParameterType.BOOLEAN:
|
||||||
return typeof value === 'boolean';
|
return typeof value === 'boolean';
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ class MCPStore {
|
||||||
*/
|
*/
|
||||||
getServerLabel(server: MCPServerSettingsEntry): string {
|
getServerLabel(server: MCPServerSettingsEntry): string {
|
||||||
const healthState = this.getHealthCheckState(server.id);
|
const healthState = this.getHealthCheckState(server.id);
|
||||||
if (healthState?.status === HealthCheckStatus.Success) {
|
if (healthState?.status === HealthCheckStatus.SUCCESS) {
|
||||||
return (
|
return (
|
||||||
healthState.serverInfo?.title || healthState.serverInfo?.name || server.name || server.url
|
healthState.serverInfo?.title || healthState.serverInfo?.name || server.name || server.url
|
||||||
);
|
);
|
||||||
|
|
@ -175,7 +175,7 @@ class MCPStore {
|
||||||
return servers.some((s) => {
|
return servers.some((s) => {
|
||||||
const state = this.getHealthCheckState(s.id);
|
const state = this.getHealthCheckState(s.id);
|
||||||
return (
|
return (
|
||||||
state.status === HealthCheckStatus.Idle || state.status === HealthCheckStatus.Connecting
|
state.status === HealthCheckStatus.IDLE || state.status === HealthCheckStatus.CONNECTING
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@ export type {
|
||||||
SettingsFieldConfig,
|
SettingsFieldConfig,
|
||||||
SettingsChatServiceOptions,
|
SettingsChatServiceOptions,
|
||||||
SettingsConfigType,
|
SettingsConfigType,
|
||||||
ParameterSource,
|
|
||||||
ParameterValue,
|
ParameterValue,
|
||||||
ParameterRecord,
|
ParameterRecord,
|
||||||
ParameterInfo,
|
ParameterInfo,
|
||||||
|
|
|
||||||
|
|
@ -136,20 +136,20 @@ export interface MCPConnection {
|
||||||
* Extended health check state with detailed connection info
|
* Extended health check state with detailed connection info
|
||||||
*/
|
*/
|
||||||
export type HealthCheckState =
|
export type HealthCheckState =
|
||||||
| { status: import('$lib/enums/mcp').HealthCheckStatus.Idle }
|
| { status: import('$lib/enums/mcp').HealthCheckStatus.IDLE }
|
||||||
| {
|
| {
|
||||||
status: import('$lib/enums/mcp').HealthCheckStatus.Connecting;
|
status: import('$lib/enums/mcp').HealthCheckStatus.CONNECTING;
|
||||||
phase: MCPConnectionPhase;
|
phase: MCPConnectionPhase;
|
||||||
logs: MCPConnectionLog[];
|
logs: MCPConnectionLog[];
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
status: import('$lib/enums/mcp').HealthCheckStatus.Error;
|
status: import('$lib/enums/mcp').HealthCheckStatus.ERROR;
|
||||||
message: string;
|
message: string;
|
||||||
phase?: MCPConnectionPhase;
|
phase?: MCPConnectionPhase;
|
||||||
logs: MCPConnectionLog[];
|
logs: MCPConnectionLog[];
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
status: import('$lib/enums/mcp').HealthCheckStatus.Success;
|
status: import('$lib/enums/mcp').HealthCheckStatus.SUCCESS;
|
||||||
tools: MCPToolInfo[];
|
tools: MCPToolInfo[];
|
||||||
serverInfo?: MCPServerInfo;
|
serverInfo?: MCPServerInfo;
|
||||||
capabilities?: MCPCapabilitiesInfo;
|
capabilities?: MCPCapabilitiesInfo;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import type { SETTING_CONFIG_DEFAULT } from '$lib/constants/settings-config';
|
||||||
import type { ChatMessagePromptProgress, ChatMessageTimings } from './chat';
|
import type { ChatMessagePromptProgress, ChatMessageTimings } from './chat';
|
||||||
import type { OpenAIToolDefinition } from './mcp';
|
import type { OpenAIToolDefinition } from './mcp';
|
||||||
import type { DatabaseMessageExtra } from './database';
|
import type { DatabaseMessageExtra } from './database';
|
||||||
|
import type { ParameterSource, SyncableParameterType } from '$lib/enums';
|
||||||
|
|
||||||
export type SettingsConfigValue = string | number | boolean;
|
export type SettingsConfigValue = string | number | boolean;
|
||||||
|
|
||||||
|
|
@ -72,8 +73,8 @@ export type SettingsConfigType = typeof SETTING_CONFIG_DEFAULT & {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameter synchronization types for server defaults and user overrides
|
* Parameter synchronization types for server defaults and user overrides
|
||||||
|
* Note: ParameterSource and SyncableParameterType enums are imported from '$lib/enums'
|
||||||
*/
|
*/
|
||||||
export type ParameterSource = 'default' | 'custom';
|
|
||||||
export type ParameterValue = string | number | boolean;
|
export type ParameterValue = string | number | boolean;
|
||||||
export type ParameterRecord = Record<string, ParameterValue>;
|
export type ParameterRecord = Record<string, ParameterValue>;
|
||||||
|
|
||||||
|
|
@ -87,6 +88,6 @@ export interface ParameterInfo {
|
||||||
export interface SyncableParameter {
|
export interface SyncableParameter {
|
||||||
key: string;
|
key: string;
|
||||||
serverKey: string;
|
serverKey: string;
|
||||||
type: 'number' | 'string' | 'boolean';
|
type: SyncableParameterType;
|
||||||
canSync: boolean;
|
canSync: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { MCPServerSettingsEntry } from '$lib/types';
|
import type { MCPServerSettingsEntry } from '$lib/types';
|
||||||
import { MCPTransportType, MCPLogLevel } from '$lib/enums';
|
import { MCPTransportType, MCPLogLevel, UrlPrefix } from '$lib/enums';
|
||||||
import { DEFAULT_MCP_CONFIG } from '$lib/constants/mcp';
|
import { DEFAULT_MCP_CONFIG } from '$lib/constants/mcp';
|
||||||
import { Info, AlertTriangle, XCircle } from '@lucide/svelte';
|
import { Info, AlertTriangle, XCircle } from '@lucide/svelte';
|
||||||
import type { Component } from 'svelte';
|
import type { Component } from 'svelte';
|
||||||
|
|
@ -11,9 +11,10 @@ import type { Component } from 'svelte';
|
||||||
export function detectMcpTransportFromUrl(url: string): MCPTransportType {
|
export function detectMcpTransportFromUrl(url: string): MCPTransportType {
|
||||||
const normalized = url.trim().toLowerCase();
|
const normalized = url.trim().toLowerCase();
|
||||||
|
|
||||||
return normalized.startsWith('ws://') || normalized.startsWith('wss://')
|
return normalized.startsWith(UrlPrefix.WEBSOCKET) ||
|
||||||
? MCPTransportType.Websocket
|
normalized.startsWith(UrlPrefix.WEBSOCKET_SECURE)
|
||||||
: MCPTransportType.StreamableHttp;
|
? MCPTransportType.WEBSOCKET
|
||||||
|
: MCPTransportType.STREAMABLE_HTTP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -70,9 +71,9 @@ export function parseMcpServerSettings(rawServers: unknown): MCPServerSettingsEn
|
||||||
*/
|
*/
|
||||||
export function getMcpLogLevelIcon(level: MCPLogLevel): Component {
|
export function getMcpLogLevelIcon(level: MCPLogLevel): Component {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case MCPLogLevel.Error:
|
case MCPLogLevel.ERROR:
|
||||||
return XCircle;
|
return XCircle;
|
||||||
case MCPLogLevel.Warn:
|
case MCPLogLevel.WARN:
|
||||||
return AlertTriangle;
|
return AlertTriangle;
|
||||||
default:
|
default:
|
||||||
return Info;
|
return Info;
|
||||||
|
|
@ -87,9 +88,9 @@ export function getMcpLogLevelIcon(level: MCPLogLevel): Component {
|
||||||
*/
|
*/
|
||||||
export function getMcpLogLevelClass(level: MCPLogLevel): string {
|
export function getMcpLogLevelClass(level: MCPLogLevel): string {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case MCPLogLevel.Error:
|
case MCPLogLevel.ERROR:
|
||||||
return 'text-destructive';
|
return 'text-destructive';
|
||||||
case MCPLogLevel.Warn:
|
case MCPLogLevel.WARN:
|
||||||
return 'text-yellow-600 dark:text-yellow-500';
|
return 'text-yellow-600 dark:text-yellow-500';
|
||||||
default:
|
default:
|
||||||
return 'text-muted-foreground';
|
return 'text-muted-foreground';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue