mirror of
https://github.com/EthanMarti/infio-copilot.git
synced 2026-01-16 08:21:55 +00:00
add mcp tools
This commit is contained in:
parent
ec6c4cde83
commit
1dffe5292a
@ -783,7 +783,6 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
|
||||
model: undefined,
|
||||
},
|
||||
})
|
||||
console.log('Updated chat messages:', newChatMessages);
|
||||
}
|
||||
setChatMessages(newChatMessages);
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ const CustomModeView = () => {
|
||||
const [roleDefinition, setRoleDefinition] = useState<string>('')
|
||||
|
||||
// Selected tool groups
|
||||
const [selectedTools, setSelectedTools] = useState<GroupEntry[]>([])
|
||||
const [selectedTools, setSelectedTools] = useState<GroupEntry[]>([]);
|
||||
|
||||
// Custom instructions
|
||||
const [customInstructions, setCustomInstructions] = useState<string>('')
|
||||
@ -87,7 +87,7 @@ const CustomModeView = () => {
|
||||
setModeName(builtinMode.slug);
|
||||
setRoleDefinition(builtinMode.roleDefinition);
|
||||
setCustomInstructions(builtinMode.customInstructions || '');
|
||||
setSelectedTools(builtinMode.groups);
|
||||
setSelectedTools(builtinMode.groups as GroupEntry[]);
|
||||
setCustomModeId(''); // Built-in modes don't have custom IDs
|
||||
} else {
|
||||
setIsBuiltinMode(false);
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { Server } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
import { useSettings } from "../../../contexts/SettingsContext"
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, SearchWebToolArgs } from "../../../types/apply"
|
||||
import { ApplyStatus, UseMcpToolArgs } from "../../../types/apply"
|
||||
|
||||
export default function UseMcpToolBlock({
|
||||
applyStatus,
|
||||
@ -14,16 +13,13 @@ export default function UseMcpToolBlock({
|
||||
finish
|
||||
}: {
|
||||
applyStatus: ApplyStatus
|
||||
onApply: (args: SearchWebToolArgs) => void
|
||||
onApply: (args: UseMcpToolArgs) => void
|
||||
serverName: string,
|
||||
toolName: string,
|
||||
parameters: Record<string, unknown>,
|
||||
finish: boolean
|
||||
}) {
|
||||
|
||||
const { settings } = useSettings()
|
||||
|
||||
|
||||
React.useEffect(() => {
|
||||
if (finish && applyStatus === ApplyStatus.Idle) {
|
||||
onApply({
|
||||
@ -43,7 +39,7 @@ export default function UseMcpToolBlock({
|
||||
<div className={'infio-chat-code-block-header'}>
|
||||
<div className={'infio-chat-code-block-header-filename'}>
|
||||
<Server size={14} className="infio-chat-code-block-header-icon" />
|
||||
use mcp tool from
|
||||
{t('mcpHub.useMcpToolFrom')}
|
||||
<span className="infio-mcp-tool-server-name">{serverName}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -56,7 +52,7 @@ export default function UseMcpToolBlock({
|
||||
<span className="infio-mcp-tool-name">{toolName}</span>
|
||||
</div>
|
||||
</div>
|
||||
参数: <div className="infio-mcp-tool-parameters">
|
||||
{t('mcpHub.parameters')}: <div className="infio-mcp-tool-parameters">
|
||||
<pre className="infio-json-pre"><code>{JSON.stringify(parameters, null, 2)}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -21,10 +21,8 @@ const McpHubView = () => {
|
||||
|
||||
const fetchServers = async () => {
|
||||
const hub = await getMcpHub()
|
||||
console.log('Fetching MCP Servers from hub:', hub)
|
||||
if (hub) {
|
||||
const serversData = hub.getAllServers()
|
||||
console.log('Fetched MCP Servers:', serversData)
|
||||
setMcpServers(serversData)
|
||||
}
|
||||
}
|
||||
@ -65,7 +63,7 @@ const McpHubView = () => {
|
||||
const handleDelete = async (serverName: string) => {
|
||||
const hub = await getMcpHub();
|
||||
if (hub) {
|
||||
if (confirm(t('mcpHub.deleteConfirm', { name: serverName }))) {
|
||||
if (confirm(t('mcpHub.deleteConfirm').replace('{name}', serverName) as string)) {
|
||||
await hub.deleteServer(serverName, "global")
|
||||
const updatedServers = hub.getAllServers()
|
||||
setMcpServers(updatedServers)
|
||||
@ -103,9 +101,9 @@ const McpHubView = () => {
|
||||
// 清空表单
|
||||
setNewServerName('')
|
||||
setNewServerConfig('')
|
||||
new Notice(t('mcpHub.createSuccess', { name: newServerName }))
|
||||
new Notice(t('mcpHub.createSuccess').replace('{name}', newServerName) as string)
|
||||
} catch (error) {
|
||||
new Notice(t('mcpHub.createFailed', { error: error.message }))
|
||||
new Notice(t('mcpHub.createFailed').replace('{error}', error.message) as string)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +95,6 @@ class LLMManager implements LLMManagerInterface {
|
||||
request: LLMRequestNonStreaming,
|
||||
options?: LLMOptions,
|
||||
): Promise<LLMResponseNonStreaming> {
|
||||
console.log("model", model)
|
||||
switch (model.provider) {
|
||||
case ApiProvider.Infio:
|
||||
return await this.infioProvider.generateResponse(
|
||||
|
||||
@ -140,14 +140,10 @@ export class McpHub {
|
||||
|
||||
public async onload() {
|
||||
// Ensure the MCP configuration directory exists
|
||||
console.log("McpHub: Loading MCP Hub")
|
||||
await this.ensureMcpFileExists()
|
||||
console.log("McpHub: file exists")
|
||||
await this.watchMcpSettingsFile();
|
||||
console.log("McpHub: watchMcpSettingsFile")
|
||||
// this.setupWorkspaceWatcher();
|
||||
await this.initializeGlobalMcpServers();
|
||||
console.log("McpHub: initializeGlobalMcpServers")
|
||||
}
|
||||
|
||||
/**
|
||||
@ -156,7 +152,6 @@ export class McpHub {
|
||||
*/
|
||||
public registerClient(): void {
|
||||
this.refCount++
|
||||
console.log(`McpHub: Client registered. Ref count: ${this.refCount}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,9 +160,7 @@ export class McpHub {
|
||||
*/
|
||||
public async unregisterClient(): Promise<void> {
|
||||
this.refCount--
|
||||
console.log(`McpHub: Client unregistered. Ref count: ${this.refCount}`)
|
||||
if (this.refCount <= 0) {
|
||||
console.log("McpHub: Last client unregistered. Disposing hub.")
|
||||
await this.dispose()
|
||||
}
|
||||
}
|
||||
@ -336,7 +329,7 @@ export class McpHub {
|
||||
// which should create it, then something is wrong.
|
||||
// However, getMcpSettingsFilePath should handle creation.
|
||||
// This check is more of a safeguard.
|
||||
console.log("MCP config file does not exist, skipping initialization.");
|
||||
// console.log("MCP config file does not exist, skipping initialization.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -646,6 +639,7 @@ export class McpHub {
|
||||
alwaysAllow: alwaysAllowConfig.includes(tool.name),
|
||||
}))
|
||||
|
||||
// @ts-expect-error - 服务器返回的工具对象中 name 是可选的,但 McpTool 类型要求它是必需的
|
||||
return tools
|
||||
} catch (error) {
|
||||
console.error(`Failed to fetch tools for ${serverName}:`, error)
|
||||
@ -660,6 +654,7 @@ export class McpHub {
|
||||
return []
|
||||
}
|
||||
const response = await connection.client.request({ method: "resources/list" }, ListResourcesResultSchema)
|
||||
// @ts-expect-error - 服务器返回的资源对象中 name 是可选的,但 McpResource 类型要求它是必需的
|
||||
return response?.resources || []
|
||||
} catch (error) {
|
||||
// console.error(`Failed to fetch resources for ${serverName}:`, error)
|
||||
@ -680,6 +675,7 @@ export class McpHub {
|
||||
{ method: "resources/templates/list" },
|
||||
ListResourceTemplatesResultSchema,
|
||||
)
|
||||
// @ts-expect-error - 服务器返回的资源模板对象中 name 是可选的,但 McpResourceTemplate 类型要求它是必需的
|
||||
return response?.resourceTemplates || []
|
||||
} catch (error) {
|
||||
// console.error(`Failed to fetch resource templates for ${serverName}:`, error)
|
||||
@ -1194,6 +1190,7 @@ export class McpHub {
|
||||
if (connection.server.disabled) {
|
||||
throw new Error(`Server "${serverName}" is disabled`)
|
||||
}
|
||||
// @ts-expect-error - 服务器返回的资源对象中 name 是可选的,但 McpResourceResponse 类型要求它是必需的
|
||||
return await connection.client.request(
|
||||
{
|
||||
method: "resources/read",
|
||||
@ -1231,6 +1228,7 @@ export class McpHub {
|
||||
timeout = 60 * 1000
|
||||
}
|
||||
|
||||
// @ts-expect-error - 服务器返回的工具调用对象中 name 是可选的,但 McpToolCallResponse 类型要求它是必需的
|
||||
return await connection.client.request(
|
||||
{
|
||||
method: "tools/call",
|
||||
|
||||
@ -381,8 +381,8 @@ export default {
|
||||
disable: "Disable Server",
|
||||
restart: "Restart Server",
|
||||
delete: "Delete Server",
|
||||
deleteConfirm: "Are you sure you want to delete server \"{name}\"?",
|
||||
createSuccess: "Server \"{name}\" created successfully",
|
||||
deleteConfirm: "Are you sure you want to delete server {name}?",
|
||||
createSuccess: "Server {name} created successfully",
|
||||
createFailed: "Failed to create server: {error}",
|
||||
serverNameRequired: "Server name cannot be empty",
|
||||
configRequired: "Configuration cannot be empty",
|
||||
@ -396,6 +396,7 @@ export default {
|
||||
noResources: "No resources available",
|
||||
noErrors: "No error records",
|
||||
parameters: "Parameters",
|
||||
toolNoDescription: "No description"
|
||||
toolNoDescription: "No description",
|
||||
useMcpToolFrom: "Use MCP tool from",
|
||||
}
|
||||
}
|
||||
|
||||
@ -396,7 +396,8 @@ export default {
|
||||
noResources: "没有可用资源",
|
||||
noErrors: "没有错误记录",
|
||||
parameters: "参数",
|
||||
toolNoDescription: "无描述"
|
||||
toolNoDescription: "无描述",
|
||||
useMcpToolFrom: "Use MCP tool from",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -22,7 +22,7 @@ export type ModeConfig = {
|
||||
name: string
|
||||
roleDefinition: string
|
||||
customInstructions?: string
|
||||
groups: readonly GroupEntry[] // Now supports both simple strings and tuples with options
|
||||
groups: GroupEntry[] // Now supports both simple strings and tuples with options
|
||||
source?: "global" | "project" // Where this mode was loaded from
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ export function getToolsForMode(groups: readonly GroupEntry[]): string[] {
|
||||
}
|
||||
|
||||
// Main modes configuration as an ordered array
|
||||
export const defaultModes: readonly ModeConfig[] = [
|
||||
export const defaultModes: ModeConfig[] = [
|
||||
{
|
||||
slug: "ask",
|
||||
name: "Ask",
|
||||
@ -107,7 +107,7 @@ export const defaultModes: readonly ModeConfig[] = [
|
||||
customInstructions:
|
||||
"You can conduct thorough research by analyzing available information, connecting related concepts, and applying structured reasoning methods. Help users explore topics in depth by considering multiple angles, identifying relevant evidence, and evaluating the reliability of sources. Use step-by-step analysis when tackling complex problems, explaining your thought process clearly. Create visual representations like Mermaid diagrams when they help clarify relationships between ideas. Use Markdown tables to present statistical data or comparative information when appropriate. Present balanced viewpoints while highlighting the strength of evidence behind different conclusions.",
|
||||
},
|
||||
] as const
|
||||
]
|
||||
|
||||
// Export the default mode slug
|
||||
export const defaultModeSlug = defaultModes[0].slug
|
||||
|
||||
@ -41,7 +41,7 @@ export async function onEnt(
|
||||
}
|
||||
|
||||
const postData = JSON.stringify(payload)
|
||||
const apiUrl = new URL(`https://hubs.infio.app/e1/api/event`)
|
||||
const apiUrl = new URL(`https://hubs.infio.app/api/event`)
|
||||
|
||||
const options = {
|
||||
hostname: apiUrl.hostname,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user