You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

129 lines
5.6 KiB

<template>
<div class="node-config">
<el-divider content-position="left">模型配置</el-divider>
<el-form-item label="选择模型">
<el-select :model-value="modelValue.model || ''" @change="onModelSelect" placeholder="从模型管理中选择或手动输入" filterable clearable allow-create>
<template #header>
<div style="padding: 4px 0; color: #909399; font-size: 12px;">
仅显示已启用的 LLM 模型来自模型管理
</div>
</template>
<el-option-group label="大语言模型 (LLM)">
<el-option
v-for="m in llmModels"
:key="m.id"
:label="`${m.display_name || m.model_name} (${getProviderName(m.provider_id)})`"
:value="m.model_name"
>
<span style="display: flex; justify-content: space-between; align-items: center;">
<span>{{ m.display_name || m.model_name }}</span>
<el-tag size="small" type="info" style="margin-left: 8px;">{{ getProviderName(m.provider_id) }}</el-tag>
</span>
</el-option>
</el-option-group>
</el-select>
</el-form-item>
<!-- 选中模型后显示其默认参数提示 -->
<div v-if="selectedModelInfo" style="margin-bottom: 12px; padding: 8px 12px; background: #f0f9ff; border-radius: 6px; font-size: 12px; color: #606266;">
<span v-if="(selectedModelInfo.default_params || {}).temperature !== undefined">
Temperature={{ selectedModelInfo.default_params.temperature }}
</span>
<span v-if="(selectedModelInfo.default_params || {}).max_tokens" style="margin-left: 8px;">
MaxTokens={{ selectedModelInfo.default_params.max_tokens }}
</span>
<el-tag v-if="(selectedModelInfo.capabilities || {}).vision" size="small" type="primary" effect="plain" style="margin-left: 8px;">Vision</el-tag>
<el-tag v-if="(selectedModelInfo.capabilities || {}).function_calling" size="small" type="primary" effect="plain" style="margin-left: 4px;">FC</el-tag>
</div>
<el-form-item label="系统提示词">
<el-input :model-value="modelValue.system_prompt" type="textarea" :rows="4" @input="(e: any) => update('system_prompt', e)" placeholder="输入系统提示词,定义AI角色和行为" />
</el-form-item>
<el-form-item label="温度">
<el-slider :model-value="modelValue.temperature ?? 0.7" :min="0" :max="2" :step="0.1" @change="update('temperature', $event)" />
</el-form-item>
<el-form-item label="最大Token数">
<el-input-number :model-value="modelValue.max_tokens ?? 2000" :min="1" :max="200000" :step="256" @change="update('max_tokens', $event)" />
</el-form-item>
<el-divider content-position="left">记忆配置</el-divider>
<el-form-item label="上下文长度">
<el-input-number :model-value="modelValue.context_length ?? 5" :min="1" :max="20" :step="1" @change="update('context_length', $event)" />
</el-form-item>
<el-form-item label="记忆模式">
<el-select :model-value="modelValue.memory_mode || 'short_term'" @change="update('memory_mode', $event)">
<el-option label="无记忆" value="none" />
<el-option label="短期记忆" value="short_term" />
<el-option label="长期记忆" value="long_term" />
</el-select>
</el-form-item>
<el-divider content-position="left">高级选项</el-divider>
<el-form-item label="流式输出">
<el-switch :model-value="modelValue.stream ?? true" @change="update('stream', $event)" />
</el-form-item>
<el-form-item label="函数调用">
<el-switch :model-value="modelValue.tool_call ?? false" @change="update('tool_call', $event)" />
</el-form-item>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
const props = defineProps<{
modelValue: any
modelList: any[]
}>()
const emit = defineEmits(['change', 'update:modelValue'])
function update(key: string, val: any) {
emit('change')
emit('update:modelValue', { ...props.modelValue, [key]: val })
}
// 过滤出 LLM 类型的模型
const llmModels = computed(() => {
return (props.modelList || []).filter((m: any) => m.model_type === 'llm' && m.is_active !== false)
})
// 当前选中的模型信息
const selectedModelInfo = computed(() => {
const modelName = props.modelValue?.model
if (!modelName) return null
return llmModels.value.find((m: any) => m.model_name === modelName)
})
function getProviderName(providerId: string): string {
// providerId 可能是 UUID 字符串,这里无法直接查供应商名
// 显示 ID 前缀作为标识
return providerId ? String(providerId).slice(0, 8) + '...' : '-'
}
function onModelSelect(val: string) {
// 如果选择了已管理的模型,同时保存 model_name 和 model_instance_id
const model = val ? llmModels.value.find((m: any) => m.model_name === val) : null
if (model) {
// 从模型管理选择:保存 model + model_instance_id
const updated = { ...props.modelValue, model: val, model_instance_id: model.id }
// 自动填入默认参数
const params = model.default_params || {}
if (params.temperature !== undefined && !updated.temperature) updated.temperature = params.temperature
if (params.max_tokens && !updated.max_tokens) updated.max_tokens = params.max_tokens
if ((model.capabilities || {}).function_calling && updated.tool_call === false) updated.tool_call = true
emit('update:modelValue', updated)
} else {
// 手动输入或清空:只保存 model,清除 model_instance_id
const updated = { ...props.modelValue, model: val, model_instance_id: undefined }
emit('update:modelValue', updated)
}
}
</script>