|
@@ -15,13 +15,119 @@
|
|
|
(val) => (state.nodeData.modelConfig.pluginInstanceName = val.name)
|
|
|
"
|
|
|
/>
|
|
|
- <template v-for="item in state.nodeData.chatModelMessages">
|
|
|
+ <div class="_p-title">
|
|
|
+ <div class="text-sm">上下文</div>
|
|
|
+ </div>
|
|
|
+ <varsSelect :node="props.node" @setVars="setContent" />
|
|
|
+ <template v-for="(item, index) in state.nodeData.chatModelMessages">
|
|
|
<paramsTextarea
|
|
|
v-model="item.text"
|
|
|
:node="node"
|
|
|
class="mt-4 max-h-100"
|
|
|
- :title="item.role"
|
|
|
- />
|
|
|
+ :delFunc="
|
|
|
+ item.role === 'system'
|
|
|
+ ? undefined
|
|
|
+ : () => state.nodeData.chatModelMessages.splice(index, 1)
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <template #title>
|
|
|
+ <template v-if="item.role !== 'system'">
|
|
|
+ <span
|
|
|
+ class="__hover flex items-center"
|
|
|
+ @click="item.role = item.role === 'user' ? 'assistant' : 'user'"
|
|
|
+ >
|
|
|
+ {{ item.role.toUpperCase()
|
|
|
+ }}<SvgIcon name="switch" color="text-gray-700" />
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ <template v-else>{{ item.role.toUpperCase() }}</template>
|
|
|
+ <template v-if="item.role === 'system'">
|
|
|
+ <el-tooltip content="为对话提供高层指导" placement="top">
|
|
|
+ <SvgIcon name="czr_tip" size="14" class="ml-2" />
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="item.role === 'user'">
|
|
|
+ <el-tooltip
|
|
|
+ content="向模型提供指令、查询或任何基于文本的输入"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <SvgIcon name="czr_tip" size="14" class="ml-2" />
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="item.role === 'assistant'">
|
|
|
+ <el-tooltip content="基于用户消息的模型回复" placement="top">
|
|
|
+ <SvgIcon name="czr_tip" size="14" class="ml-2" />
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </paramsTextarea>
|
|
|
+ </template>
|
|
|
+ <a-button
|
|
|
+ style="margin-top: 8px"
|
|
|
+ class="w-full"
|
|
|
+ @click="
|
|
|
+ state.nodeData.chatModelMessages.push({
|
|
|
+ role: 'user',
|
|
|
+ text: '',
|
|
|
+ id: v4(),
|
|
|
+ })
|
|
|
+ "
|
|
|
+ >
|
|
|
+ 添加消息
|
|
|
+ </a-button>
|
|
|
+ <div class="_p-title">
|
|
|
+ <div class="text-sm">记忆</div>
|
|
|
+ <el-tooltip content="聊天记忆设置" placement="top">
|
|
|
+ <SvgIcon name="czr_tip" size="14" class="mr-auto ml-2" />
|
|
|
+ </el-tooltip>
|
|
|
+ <a-switch
|
|
|
+ v-model:checked="state.nodeData.isMemory"
|
|
|
+ size="small"
|
|
|
+ @change="onSwitchMemory"
|
|
|
+ ></a-switch>
|
|
|
+ </div>
|
|
|
+ <template v-if="state.nodeData.isMemory && state.nodeData.memory">
|
|
|
+ <paramsTextarea
|
|
|
+ v-model="state.nodeData.memory.query_prompt_template"
|
|
|
+ :node="node"
|
|
|
+ class="mt-4 max-h-100"
|
|
|
+ >
|
|
|
+ <template #title>
|
|
|
+ USER
|
|
|
+ <el-tooltip
|
|
|
+ content="向模型提供指令、查询或任何基于文本的输入"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <SvgIcon name="czr_tip" size="14" class="ml-2" />
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </paramsTextarea>
|
|
|
+ <div class="mt-2 flex items-center">
|
|
|
+ <a-switch
|
|
|
+ v-model:checked="state.nodeData.memory.window.enabled"
|
|
|
+ size="small"
|
|
|
+ ></a-switch>
|
|
|
+ <span class="text-sm">记忆窗口</span>
|
|
|
+ <a-row class="ml-auto flex-1" justify="end">
|
|
|
+ <a-col :span="14">
|
|
|
+ <a-slider
|
|
|
+ v-model:value="state.nodeData.memory.window.size"
|
|
|
+ :min="1"
|
|
|
+ :max="100"
|
|
|
+ :disabled="!state.nodeData.memory.window.enabled"
|
|
|
+ />
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="6">
|
|
|
+ <a-input-number
|
|
|
+ v-model:value="state.nodeData.memory.window.size"
|
|
|
+ :min="1"
|
|
|
+ :max="100"
|
|
|
+ :disabled="!state.nodeData.memory.window.enabled"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
<div class="_p-title">
|
|
|
<div class="text-sm">输出变量</div>
|
|
@@ -32,12 +138,15 @@
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { getCurrentInstance, reactive, ref, watch } from 'vue'
|
|
|
-import { useWorkflowStore } from '@/stores'
|
|
|
import paramsTextarea from '@/views/workflow/instance/component/params-textarea/index.vue'
|
|
|
import varsOut from '@/views/workflow/instance/component/vars/vars-out.vue'
|
|
|
import { pluginGetInstanceList } from '@/api/modules/model'
|
|
|
+import { v4 } from 'uuid'
|
|
|
+import SvgIcon from '@/components/SvgIcon/index.vue'
|
|
|
+import varsSelect from '@/views/workflow/instance/component/vars/vars-select.vue'
|
|
|
+import { VarsSource } from '@/views/workflow/types'
|
|
|
+import nodeDefault from '@/views/workflow/instance/llm/default'
|
|
|
|
|
|
-const WorkflowStore = useWorkflowStore()
|
|
|
const emit = defineEmits([])
|
|
|
const props = defineProps({
|
|
|
node: <any>{},
|
|
@@ -71,6 +180,29 @@ watch(
|
|
|
},
|
|
|
{ immediate: true },
|
|
|
)
|
|
|
+const setContent = (val) => {
|
|
|
+ if (val) {
|
|
|
+ state.nodeData.context = {
|
|
|
+ enabled: true,
|
|
|
+ variable_selector:
|
|
|
+ val.source === VarsSource.Root
|
|
|
+ ? [val.key.split('.')[0], val.key.split('.')[1]]
|
|
|
+ : [val.nodeId, val.key],
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ state.nodeData.context = {
|
|
|
+ enabled: false,
|
|
|
+ variable_selector: [],
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+const onSwitchMemory = (val) => {
|
|
|
+ if (val) {
|
|
|
+ if (!state.nodeData.memory) {
|
|
|
+ state.nodeData.memory = nodeDefault.defaultValue().memory
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|