feat: add McpServerInputDialog component for variable input and handling

This commit is contained in:
CaptainB 2025-09-25 16:56:02 +08:00
parent 7a0daeda24
commit f5fbbfc06c
2 changed files with 117 additions and 2 deletions

View File

@ -0,0 +1,62 @@
<template>
<el-dialog
width="600"
title="设置变量"
v-model="dialogVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:append-to-body="true"
>
<el-form label-position="top" ref="formRef" :model="form" require-asterisk-position="right">
<el-form-item v-for="item in input_field_list" :label="item" :key="item" :prop="item"
:rules="{ required: true, message: $t('dynamicsForm.tip.requiredMessage'), trigger: 'blur' }">
<el-input v-model="form[item]"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
<el-button type="primary" @click="submit(formRef)" :loading="loading">
{{ $t('common.save') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { FormInstance } from 'element-plus'
const emit = defineEmits<{
(e: 'refresh', value: any): void;
}>();
const dialogVisible = ref(false)
const loading = ref(false)
const formRef = ref<FormInstance>()
const form = ref<any>({})
const input_field_list = ref<string[]>([])
function open(vars: string[]) {
dialogVisible.value = true
input_field_list.value = vars
}
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid) => {
if (valid) {
emit('refresh', form.value)
dialogVisible.value = false
}
})
}
defineExpose({open})
</script>
<style scoped lang="scss">
</style>

View File

@ -246,6 +246,7 @@
</div>
</template>
</NodeContainer>
<McpServerInputDialog ref="mcpServerInputDialogRef" @refresh="handleMcpVariables" />
</template>
<script setup lang="ts">
import { cloneDeep, set } from 'lodash'
@ -256,6 +257,7 @@ import { t } from '@/locales'
import { MsgError, MsgSuccess } from '@/utils/message'
import TooltipLabel from '@/components/dynamics-form/items/label/TooltipLabel.vue'
import NodeCascader from '@/workflow/common/NodeCascader.vue'
import McpServerInputDialog from "./component/McpServerInputDialog.vue";
import { useRoute } from 'vue-router'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
import { resetUrl } from '@/utils/common'
@ -339,12 +341,22 @@ function getTools() {
}
try {
JSON.parse(form_data.value.mcp_servers)
const vars = extractPlaceholders(form_data.value.mcp_servers)
if (vars.length > 0) {
mcpServerInputDialogRef.value.open(vars)
return
}
} catch (e) {
MsgError(t('views.applicationWorkflow.nodes.mcpNode.mcpServerTip'))
return
}
loadSharedApi({ type: 'application', systemType: apiType.value })
.getMcpTools(id, form_data.value.mcp_servers, loading)
// tool
_getTools(form_data.value.mcp_servers)
}
function _getTools(mcp_servers: any) {
loadSharedApi({ type: 'application', systemType: apiType.value })
.getMcpTools(id, mcp_servers, loading)
.then((res: any) => {
form_data.value.mcp_tools = res.data
MsgSuccess(t('views.applicationWorkflow.nodes.mcpNode.getToolsSuccess'))
@ -355,6 +367,47 @@ function getTools() {
})
}
const mcpServerInputDialogRef = ref()
// JSON {{...}}
function extractPlaceholders(input: unknown): string[] {
const re = /\{\{\s*([a-zA-Z_][\w.]*)\s*\}\}/g; // {{ path.like.this }}
const found = new Set<string>();
const visit = (v: unknown) => {
if (typeof v === 'string') {
let m: RegExpExecArray | null;
while ((m = re.exec(v)) !== null) found.add(m[1]);
} else if (Array.isArray(v)) {
v.forEach(visit);
} else if (v && typeof v === 'object') {
Object.values(v as Record<string, unknown>).forEach(visit);
}
};
// JSON /
if (typeof input === 'string') {
try {
visit(JSON.parse(input));
} catch {
visit(input);
}
} else {
visit(input);
}
return [...found];
}
function handleMcpVariables(vars: any) {
let mcp_servers = form_data.value.mcp_servers
for (const item in vars) {
mcp_servers = mcp_servers.replace(`{{${item}}}`, vars[item])
}
// tool
_getTools(mcp_servers)
}
function changeTool() {
form_data.value.mcp_server = form_data.value.mcp_tools.find(
(item: any) => item.name === form_data.value.mcp_tool,