Commit eb28bfb2 by archer

perf: ts

parent ffd4e194
......@@ -7,15 +7,16 @@ WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json ./
COPY pnpm-lock.yaml* ./
RUN pnpm config set registry https://registry.npmmirror.com/
RUN \
[ -f pnpm-lock.yaml ] && pnpm install || \
[ -f pnpm-lock.yaml ] && pnpm fetch || \
(echo "Lockfile not found." && exit 1)
# Rebuild the source code only when needed
FROM node:current-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY pnpm-lock.yaml* ./
COPY package.json ./
COPY . .
# Next.js collects completely anonymous telemetry data about general usage.
......@@ -23,7 +24,10 @@ COPY . .
# Uncomment the following line in case you want to disable telemetry during the build.
ENV NEXT_TELEMETRY_DISABLED 1
RUN npm install -g pnpm && pnpm run build
RUN npm install -g pnpm
RUN \
[ -f pnpm-lock.yaml ] && (pnpm --offline install && pnpm run build) || \
(echo "Lockfile not found." && exit 1)
# Production image, copy all the files and run next
FROM node:current-alpine AS runner
......
......@@ -520,14 +520,16 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
modules: [
{
moduleId: 'userChatInput',
flowType: 'questionInput',
position: {
x: 464.32198615344566,
y: 1602.2698463081606
x: 506.7143912167368,
y: 1601.0230108651226
},
flowType: 'questionInput',
inputs: [
{
key: 'userChatInput',
type: 'systemInput',
label: '用户问题',
connected: true
}
],
......@@ -548,19 +550,25 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'history',
flowType: 'historyNode',
position: {
x: 452.5466249541586,
y: 1276.3930310334215
},
flowType: 'historyNode',
inputs: [
{
key: 'maxContext',
type: 'numberInput',
label: '最长记录数',
value: 6,
min: 0,
max: 50,
connected: true
},
{
key: 'history',
type: 'hidden',
label: '聊天记录',
connected: true
}
],
......@@ -581,51 +589,111 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'chatModule',
flowType: 'chatNode',
position: {
x: 998.0312473867093,
y: 803.8586941051353
},
flowType: 'chatNode',
inputs: [
{
key: 'model',
type: 'custom',
label: '对话模型',
value: 'gpt-3.5-turbo',
list: [],
connected: true
},
{
key: 'temperature',
type: 'slider',
label: '温度',
value: 0,
min: 0,
max: 10,
step: 1,
markList: [
{
label: '严谨',
value: 0
},
{
label: '发散',
value: 10
}
],
connected: true
},
{
key: 'maxToken',
type: 'custom',
label: '回复上限',
value: 2000,
min: 100,
max: 4000,
step: 50,
markList: [
{
label: '100',
value: 100
},
{
label: '4000',
value: 4000
}
],
connected: true
},
{
key: 'systemPrompt',
type: 'textarea',
label: '系统提示词',
valueType: 'string',
description:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
placeholder:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
value: '',
connected: true
},
{
key: 'limitPrompt',
type: 'textarea',
valueType: 'string',
label: '限定词',
description:
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"',
placeholder:
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"',
value: '',
connected: true
},
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: false
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
valueType: 'kb_quote',
connected: false
},
{
key: 'history',
type: 'target',
label: '聊天记录',
valueType: 'chat_history',
connected: true
},
{
key: 'userChatInput',
type: 'target',
label: '用户问题',
required: true,
valueType: 'string',
connected: true
}
],
......@@ -657,14 +725,16 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
modules: [
{
moduleId: 'userGuide',
flowType: 'userGuide',
position: {
x: 447.98520778293346,
x: 454.98510354678695,
y: 721.4016845336229
},
flowType: 'userGuide',
inputs: [
{
key: 'welcomeText',
type: 'input',
label: '开场白',
value: '你好,我是 laf 助手,有什么可以帮助你的么?',
connected: true
}
......@@ -673,14 +743,16 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'userChatInput',
flowType: 'questionInput',
position: {
x: 464.32198615344566,
y: 1602.2698463081606
},
flowType: 'questionInput',
inputs: [
{
key: 'userChatInput',
type: 'systemInput',
label: '用户问题',
connected: true
}
],
......@@ -705,19 +777,25 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'history',
flowType: 'historyNode',
position: {
x: 452.5466249541586,
y: 1276.3930310334215
},
flowType: 'historyNode',
inputs: [
{
key: 'maxContext',
type: 'numberInput',
label: '最长记录数',
value: 6,
min: 0,
max: 50,
connected: true
},
{
key: 'history',
type: 'hidden',
label: '聊天记录',
connected: true
}
],
......@@ -738,33 +816,74 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'kbSearch',
flowType: 'kbSearchNode',
position: {
x: 956.0838440206068,
y: 887.462827870246
},
flowType: 'kbSearchNode',
inputs: [
{
key: 'kbList',
type: 'custom',
label: '关联的知识库',
value: [],
list: [],
connected: true
},
{
key: 'similarity',
type: 'slider',
label: '相似度',
value: 0.8,
min: 0,
max: 1,
step: 0.01,
markList: [
{
label: '100',
value: 100
},
{
label: '1',
value: 1
}
],
connected: true
},
{
key: 'limit',
type: 'slider',
label: '单次搜索上限',
description: '最多取 n 条记录作为本次问题引用',
value: 5,
min: 1,
max: 20,
step: 1,
markList: [
{
label: '1',
value: 1
},
{
label: '20',
value: 20
}
],
connected: true
},
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: false
},
{
key: 'userChatInput',
type: 'target',
label: '用户问题',
required: true,
valueType: 'string',
connected: true
}
],
......@@ -776,7 +895,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
valueType: 'boolean',
targets: [
{
moduleId: 'chatModule',
moduleId: '2752oj',
key: 'switch'
}
]
......@@ -810,51 +929,111 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'chatModule',
flowType: 'chatNode',
position: {
x: 1564.2820496250988,
y: 842.3852152224699
x: 1546.0823206390796,
y: 1008.9827344021824
},
flowType: 'chatNode',
inputs: [
{
key: 'model',
type: 'custom',
label: '对话模型',
value: 'gpt-3.5-turbo',
list: [],
connected: true
},
{
key: 'temperature',
type: 'slider',
label: '温度',
value: 0,
min: 0,
max: 10,
step: 1,
markList: [
{
label: '严谨',
value: 0
},
{
label: '发散',
value: 10
}
],
connected: true
},
{
key: 'maxToken',
type: 'custom',
label: '回复上限',
value: 2000,
min: 100,
max: 4000,
step: 50,
markList: [
{
label: '100',
value: 100
},
{
label: '4000',
value: 4000
}
],
connected: true
},
{
key: 'systemPrompt',
type: 'textarea',
label: '系统提示词',
valueType: 'string',
description:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
placeholder:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
value: '',
connected: true
},
{
key: 'limitPrompt',
type: 'textarea',
valueType: 'string',
label: '限定词',
description:
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"',
placeholder:
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"',
value: '',
connected: true
},
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: true
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
valueType: 'kb_quote',
connected: true
},
{
key: 'history',
type: 'target',
label: '聊天记录',
valueType: 'chat_history',
connected: true
},
{
key: 'userChatInput',
type: 'target',
label: '用户问题',
required: true,
valueType: 'string',
connected: true
}
],
......@@ -875,6 +1054,34 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
targets: []
}
]
},
{
moduleId: '2752oj',
flowType: 'answerNode',
position: {
x: 1542.9271243684725,
y: 702.7819618017722
},
inputs: [
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: true
},
{
key: 'text',
value: '搜索结果为空',
type: 'textarea',
valueType: 'string',
label: '回复的内容',
description:
'可以使用 \\n 来实现换行。也可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
connected: true
}
],
outputs: []
}
]
},
......@@ -886,14 +1093,16 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
modules: [
{
moduleId: 'userGuide',
flowType: 'userGuide',
position: {
x: 447.98520778293346,
y: 721.4016845336229
},
flowType: 'userGuide',
inputs: [
{
key: 'welcomeText',
type: 'input',
label: '开场白',
value: '你好,我可以为你翻译各种语言,请告诉我你需要翻译成什么语言?',
connected: true
}
......@@ -902,14 +1111,16 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'variable',
flowType: 'variable',
position: {
x: 444.0369195277651,
y: 1008.5185781784537
},
flowType: 'variable',
inputs: [
{
key: 'variables',
type: 'systemInput',
label: '变量输入',
value: [
{
id: '35c640eb-cf22-431f-bb57-3fc21643880e',
......@@ -948,14 +1159,16 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'userChatInput',
flowType: 'questionInput',
position: {
x: 464.32198615344566,
y: 1602.2698463081606
},
flowType: 'questionInput',
inputs: [
{
key: 'userChatInput',
type: 'systemInput',
label: '用户问题',
connected: true
}
],
......@@ -976,19 +1189,25 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'history',
flowType: 'historyNode',
position: {
x: 452.5466249541586,
y: 1276.3930310334215
},
flowType: 'historyNode',
inputs: [
{
key: 'maxContext',
type: 'numberInput',
label: '最长记录数',
value: 10,
min: 0,
max: 50,
connected: true
},
{
key: 'history',
type: 'hidden',
label: '聊天记录',
connected: true
}
],
......@@ -1009,51 +1228,111 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'chatModule',
flowType: 'chatNode',
position: {
x: 981.9682828103937,
y: 890.014595014464
},
flowType: 'chatNode',
inputs: [
{
key: 'model',
type: 'custom',
label: '对话模型',
value: 'gpt-3.5-turbo',
list: [],
connected: true
},
{
key: 'temperature',
type: 'slider',
label: '温度',
value: 0,
min: 0,
max: 10,
step: 1,
markList: [
{
label: '严谨',
value: 0
},
{
label: '发散',
value: 10
}
],
connected: true
},
{
key: 'maxToken',
type: 'custom',
label: '回复上限',
value: 2000,
min: 100,
max: 4000,
step: 50,
markList: [
{
label: '100',
value: 100
},
{
label: '4000',
value: 4000
}
],
connected: true
},
{
key: 'systemPrompt',
type: 'textarea',
label: '系统提示词',
valueType: 'string',
description:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
placeholder:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
value: '',
connected: true
},
{
key: 'limitPrompt',
type: 'textarea',
valueType: 'string',
label: '限定词',
description:
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"',
placeholder:
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"',
value: '将我的问题直接翻译成英语{{language}}',
connected: true
},
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: false
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
valueType: 'kb_quote',
connected: false
},
{
key: 'history',
type: 'target',
label: '聊天记录',
valueType: 'chat_history',
connected: true
},
{
key: 'userChatInput',
type: 'target',
label: '用户问题',
required: true,
valueType: 'string',
connected: true
}
],
......@@ -1085,14 +1364,16 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
modules: [
{
moduleId: '7z5g5h',
flowType: 'questionInput',
position: {
x: 198.56612928723575,
y: 1622.7034463081607
},
flowType: 'questionInput',
inputs: [
{
key: 'userChatInput',
type: 'systemInput',
label: '用户问题',
connected: true
}
],
......@@ -1121,19 +1402,25 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'xj0c9p',
flowType: 'historyNode',
position: {
x: 194.99102398958047,
y: 1801.3545999721096
},
flowType: 'historyNode',
inputs: [
{
key: 'maxContext',
type: 'numberInput',
label: '最长记录数',
value: 6,
min: 0,
max: 50,
connected: true
},
{
key: 'history',
type: 'hidden',
label: '聊天记录',
connected: true
}
],
......@@ -1154,28 +1441,43 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'remuj3',
flowType: 'classifyQuestion',
position: {
x: 672.9092284362648,
y: 1077.557793775116
},
flowType: 'classifyQuestion',
inputs: [
{
key: 'systemPrompt',
type: 'textarea',
valueType: 'string',
label: '系统提示词',
description:
'你可以添加一些特定内容的介绍,从而更好的识别用户的问题类型。这个内容通常是给模型介绍一个它不知道的内容。',
placeholder: '例如: \n1. Laf 是一个云函数开发平台……\n2. Sealos 是一个集群操作系统',
value:
'laf 是云开发平台,可以快速的开发应用\nlaf 是一个开源的 BaaS 开发平台(Backend as a Service)\nlaf 是一个开箱即用的 serverless 开发平台\nlaf 是一个集「函数计算」、「数据库」、「对象存储」等于一身的一站式开发平台\nlaf 可以是开源版的腾讯云开发、开源版的 Google Firebase、开源版的 UniCloud',
connected: true
},
{
key: 'history',
type: 'target',
label: '聊天记录',
valueType: 'chat_history',
connected: true
},
{
key: 'userChatInput',
type: 'target',
label: '用户问题',
required: true,
valueType: 'string',
connected: true
},
{
key: 'agents',
type: 'custom',
label: '',
value: [
{
value: '打招呼、问候等问题',
......@@ -1246,19 +1548,27 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'a99p6z',
flowType: 'answerNode',
position: {
x: 1304.2886011902247,
y: 776.1589509539264
},
flowType: 'answerNode',
inputs: [
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: true
},
{
key: 'text',
value: '你好,我是 laf 助手,有什么可以帮助你的?',
type: 'textarea',
valueType: 'string',
label: '回复的内容',
description:
'可以使用 \\n 来实现换行。也可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
connected: true
}
],
......@@ -1266,19 +1576,27 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'iejcou',
flowType: 'answerNode',
position: {
x: 1294.2531189034548,
y: 2127.1297123368286
},
flowType: 'answerNode',
inputs: [
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: true
},
{
key: 'text',
value: '你好,我仅能回答 laf 相关问题,请问你有什么问题么?',
type: 'textarea',
valueType: 'string',
label: '回复的内容',
description:
'可以使用 \\n 来实现换行。也可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
connected: true
}
],
......@@ -1286,52 +1604,112 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'nlfwkc',
flowType: 'chatNode',
position: {
x: 1821.979893659983,
y: 1104.6583548423682
},
flowType: 'chatNode',
inputs: [
{
key: 'model',
type: 'custom',
label: '对话模型',
value: 'gpt-3.5-turbo-16k',
list: [],
connected: true
},
{
key: 'temperature',
type: 'slider',
label: '温度',
value: 0,
min: 0,
max: 10,
step: 1,
markList: [
{
label: '严谨',
value: 0
},
{
label: '发散',
value: 10
}
],
connected: true
},
{
key: 'maxToken',
type: 'custom',
label: '回复上限',
value: 8000,
min: 100,
max: 4000,
step: 50,
markList: [
{
label: '100',
value: 100
},
{
label: '4000',
value: 4000
}
],
connected: true
},
{
key: 'systemPrompt',
type: 'textarea',
label: '系统提示词',
valueType: 'string',
description:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
placeholder:
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}',
value: '知识库是关于 laf 的内容。',
connected: true
},
{
key: 'limitPrompt',
type: 'textarea',
valueType: 'string',
label: '限定词',
description:
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"',
placeholder:
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"',
value:
'我的问题都是关于 laf 的。根据知识库回答我的问题,与 laf 无关问题,直接回复:“我不清楚,我仅能回答 laf 相关的问题。”。',
connected: true
},
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: true
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
valueType: 'kb_quote',
connected: true
},
{
key: 'history',
type: 'target',
label: '聊天记录',
valueType: 'chat_history',
connected: true
},
{
key: 'userChatInput',
type: 'target',
label: '用户问题',
required: true,
valueType: 'string',
connected: true
}
],
......@@ -1355,19 +1733,25 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 's4v9su',
flowType: 'historyNode',
position: {
x: 193.3803955457983,
y: 1116.251200765746
},
flowType: 'historyNode',
inputs: [
{
key: 'maxContext',
type: 'numberInput',
label: '最长记录数',
value: 2,
min: 0,
max: 50,
connected: true
},
{
key: 'history',
type: 'hidden',
label: '聊天记录',
connected: true
}
],
......@@ -1388,37 +1772,78 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'fljhzy',
flowType: 'kbSearchNode',
position: {
x: 1305.5374262228029,
y: 1120.0404921820218
},
flowType: 'kbSearchNode',
inputs: [
{
key: 'kbList',
type: 'custom',
label: '关联的知识库',
value: [
{
kbId: '646627f4f7b896cfd8910e24'
}
],
list: [],
connected: true
},
{
key: 'similarity',
type: 'slider',
label: '相似度',
value: 0.76,
min: 0,
max: 1,
step: 0.01,
markList: [
{
label: '100',
value: 100
},
{
label: '1',
value: 1
}
],
connected: true
},
{
key: 'limit',
type: 'slider',
label: '单次搜索上限',
description: '最多取 n 条记录作为本次问题引用',
value: 5,
min: 1,
max: 20,
step: 1,
markList: [
{
label: '1',
value: 1
},
{
label: '20',
value: 20
}
],
connected: true
},
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: true
},
{
key: 'userChatInput',
type: 'target',
label: '用户问题',
required: true,
valueType: 'string',
connected: true
}
],
......@@ -1464,14 +1889,16 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'q9equb',
flowType: 'userGuide',
position: {
x: 191.4857498376603,
y: 856.6847387508401
},
flowType: 'userGuide',
inputs: [
{
key: 'welcomeText',
type: 'input',
label: '开场白',
value:
'你好,我是 laf 助手,有什么可以帮助你的?\n[laf 是什么?有什么用?]\n[laf 在线体验地址]\n[官网地址是多少]',
connected: true
......@@ -1481,19 +1908,27 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: 'tc90wz',
flowType: 'answerNode',
position: {
x: 1828.4596416688908,
y: 765.3628156185887
},
flowType: 'answerNode',
inputs: [
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: true
},
{
key: 'text',
value: '对不起,我找不到你的问题,请更加详细的描述你的问题。',
type: 'textarea',
valueType: 'string',
label: '回复的内容',
description:
'可以使用 \\n 来实现换行。也可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
connected: true
}
],
......@@ -1501,19 +1936,27 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
},
{
moduleId: '5v78ap',
flowType: 'answerNode',
position: {
x: 1294.814522053934,
y: 1822.7626988141562
},
flowType: 'answerNode',
inputs: [
{
key: 'switch',
type: 'target',
label: '触发器',
valueType: 'any',
connected: true
},
{
key: 'text',
value: '这是一个商务问题',
type: 'textarea',
valueType: 'string',
label: '回复的内容',
description:
'可以使用 \\n 来实现换行。也可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容',
connected: true
}
],
......
......@@ -25,42 +25,60 @@ const chatModelInput = ({
{
key: 'model',
value: model,
type: 'custom',
label: '对话模型',
connected: true
},
{
key: 'temperature',
value: temperature,
label: '温度',
type: 'slider',
connected: true
},
{
key: 'maxToken',
value: maxToken,
type: 'custom',
label: '回复上限',
connected: true
},
{
key: 'systemPrompt',
value: systemPrompt,
type: 'textarea',
label: '系统提示词',
connected: true
},
{
key: 'limitPrompt',
label: '限定词',
type: 'textarea',
value: limitPrompt,
connected: true
},
{
key: 'switch',
type: 'target',
label: '触发器',
connected: kbList.length > 0
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
connected: kbList.length > 0
},
{
key: 'history',
type: 'target',
label: '聊天记录',
connected: true
},
{
key: 'userChatInput',
type: 'target',
label: '用户问题',
connected: true
}
];
......
......@@ -22,7 +22,7 @@ const NodeExtract = ({
const [editExtractFiled, setEditExtractField] = useState<ContextExtractAgentItemType>();
return (
<NodeCard minW={'380px'} moduleId={moduleId} {...props}>
<NodeCard minW={'400px'} moduleId={moduleId} {...props}>
<Divider text="Input" />
<Container>
<RenderInput
......@@ -64,11 +64,14 @@ const NodeExtract = ({
</Thead>
<Tbody>
{extractKeys.map((item, index) => (
<Tr key={index} position={'relative'}>
<Tr
key={index}
position={'relative'}
whiteSpace={'pre-wrap'}
wordBreak={'break-all'}
>
<Td>{item.key}</Td>
<Td whiteSpace={'pre-wrap'} wordBreak={'break-all'}>
{item.desc}
</Td>
<Td>{item.desc}</Td>
<Td>{item.required ? '✔' : ''}</Td>
<Td whiteSpace={'nowrap'}>
<MyIcon
......@@ -139,24 +142,6 @@ const NodeExtract = ({
const newInputs = exists
? extracts.map((item) => (item.key === editExtractFiled.key ? data : item))
: extracts.concat(data);
const newOutputs = exists
? outputs.map((output) =>
output.key === editExtractFiled.key
? {
...output,
key: data.key,
label: `提取结果-${data.desc}`
}
: output
)
: outputs.concat({
key: data.key,
label: `提取结果-${data.desc}`,
description: '无法提取时不会返回',
valueType: FlowValueTypeEnum.string,
type: FlowOutputItemTypeEnum.source,
targets: []
});
onChangeNode({
moduleId,
......@@ -167,15 +152,63 @@ const NodeExtract = ({
value: newInputs
}
});
onChangeNode({
moduleId,
type: 'outputs',
key: '',
value: newOutputs
});
if (editExtractFiled.key && editExtractFiled.key !== data.key) {
onDelEdge({ moduleId, sourceHandle: editExtractFiled.key });
if (!exists) {
onChangeNode({
moduleId,
type: 'outputs',
key: '',
value: outputs.concat({
key: data.key,
label: `提取结果-${data.desc}`,
description: '无法提取时不会返回',
valueType: FlowValueTypeEnum.string,
type: FlowOutputItemTypeEnum.source,
targets: []
})
});
} else {
if (editExtractFiled.key === data.key) {
// update
onChangeNode({
moduleId,
type: 'outputs',
key: '',
value: outputs.map((output) =>
output.key === data.key
? {
...output,
label: `提取结果-${data.desc}`
}
: output
)
});
} else {
// del and push
const newOutputs = outputs.filter((output) => output.key !== editExtractFiled.key);
onChangeNode({
moduleId,
type: 'outputs',
key: '',
value: newOutputs
});
setTimeout(() => {
onChangeNode({
moduleId,
type: 'outputs',
key: '',
value: newOutputs.concat({
key: data.key,
label: `提取结果-${data.desc}`,
description: '无法提取时不会返回',
valueType: FlowValueTypeEnum.string,
type: FlowOutputItemTypeEnum.source,
targets: []
})
});
}, 10);
}
}
setEditExtractField(undefined);
......@@ -186,4 +219,4 @@ const NodeExtract = ({
);
};
export default NodeExtract;
export default React.memo(NodeExtract);
......@@ -34,7 +34,6 @@ const ExtractFieldModal = ({
const { register, handleSubmit } = useForm<ContextExtractAgentItemType>({
defaultValues: defaultField
});
const isEdit = useMemo(() => !!defaultField.key, [defaultField]);
return (
<MyModal isOpen={true} onClose={onClose}>
......@@ -56,17 +55,11 @@ const ExtractFieldModal = ({
</Flex>
<Flex mt={5} alignItems={'center'}>
<Box flex={'0 0 70px'}>字段 key</Box>
<MyTooltip label={isEdit ? '不支持修改 key' : ''} shouldWrapChildren={false}>
<Input
isDisabled={isEdit}
placeholder="name/age/sql"
{...register('key', { required: '字段 key 不能为空' })}
/>
</MyTooltip>
<Input
placeholder="name/age/sql"
{...register('key', { required: '字段 key 不能为空' })}
/>
</Flex>
<Box mt={1} pl={'70px'} color={'myGray.600'} fontSize={'sm'}>
注意: key 字段创建后无法修改
</Box>
</ModalBody>
<ModalFooter>
......
......@@ -114,11 +114,13 @@ export const Label = ({
key: data.key,
value: data
});
onChangeNode({
moduleId,
type: 'delInput',
key: editField.key,
value: ''
setTimeout(() => {
onChangeNode({
moduleId,
type: 'delInput',
key: editField.key,
value: ''
});
});
}
setEditField(undefined);
......
......@@ -77,12 +77,31 @@ const Label = ({
defaultField={editField}
onClose={() => setEditField(undefined)}
onSubmit={(data) => {
onChangeNode({
moduleId,
type: 'outputs',
key: '',
value: outputs.map((output) => (output.key === outputKey ? data : output))
});
if (editField.key === data.key) {
onChangeNode({
moduleId,
type: 'outputs',
key: '',
value: outputs.map((output) => (output.key === outputKey ? data : output))
});
} else {
const storeOutputs = outputs.filter((output) => output.key !== editField.key);
onChangeNode({
moduleId,
type: 'outputs',
key: '',
value: storeOutputs
});
setTimeout(() => {
onChangeNode({
moduleId,
type: 'outputs',
key: '',
value: storeOutputs.concat(data)
});
}, 10);
}
setEditField(undefined);
}}
......
......@@ -42,4 +42,4 @@ const SourceHandle = ({ handleKey, valueType, ...props }: Props) => {
);
};
export default SourceHandle;
export default React.memo(SourceHandle);
......@@ -3,10 +3,12 @@ import { Flex, Box, IconButton } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import { useUserStore } from '@/store/user';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import MyIcon from '@/components/Icon';
import Avatar from '@/components/Avatar';
const SliderApps = ({ appId }: { appId: string }) => {
const { t } = useTranslation();
const router = useRouter();
const { myApps, loadMyApps } = useUserStore();
......@@ -33,7 +35,7 @@ const SliderApps = ({ appId }: { appId: string }) => {
borderRadius={'50%'}
aria-label={''}
/>
退出聊天
{t('chat.Exit Chat')}
</Flex>
<Box mt={5}>
{myApps.map((item) => (
......
import type { AppModuleItemType, VariableItemType } from '@/types/app';
import { chatModelList, vectorModelList } from '@/store/static';
import { FlowModuleTypeEnum, SpecialInputKeyEnum } from '@/constants/flow';
import {
FlowInputItemTypeEnum,
FlowModuleTypeEnum,
FlowValueTypeEnum,
SpecialInputKeyEnum
} from '@/constants/flow';
import { SystemInputEnum } from '@/constants/app';
import { TaskResponseKeyEnum } from '@/constants/chat';
import type { SelectedKbType } from '@/types/plugin';
......@@ -153,42 +158,60 @@ const chatModelInput = (formData: EditFormType): FlowInputItemType[] => [
{
key: 'model',
value: formData.chatModel.model,
type: 'custom',
label: '对话模型',
connected: true
},
{
key: 'temperature',
value: formData.chatModel.temperature,
type: 'slider',
label: '温度',
connected: true
},
{
key: 'maxToken',
value: formData.chatModel.maxToken,
type: 'custom',
label: '回复上限',
connected: true
},
{
key: 'systemPrompt',
value: formData.chatModel.systemPrompt,
type: 'textarea',
label: '系统提示词',
connected: true
},
{
key: 'limitPrompt',
type: 'textarea',
value: formData.chatModel.limitPrompt,
label: '限定词',
connected: true
},
{
key: 'switch',
type: 'target',
label: '触发器',
connected: formData.kb.list.length > 0
},
{
key: 'quoteQA',
type: 'target',
label: '引用内容',
connected: formData.kb.list.length > 0
},
{
key: 'history',
type: 'target',
label: '聊天记录',
connected: true
},
{
key: 'userChatInput',
type: 'target',
label: '用户问题',
connected: true
}
];
......@@ -200,6 +223,8 @@ const welcomeTemplate = (formData: EditFormType): AppModuleItemType[] =>
inputs: [
{
key: 'welcomeText',
type: 'input',
label: '开场白',
value: formData.guide.welcome.text,
connected: true
}
......@@ -222,6 +247,8 @@ const variableTemplate = (formData: EditFormType): AppModuleItemType[] =>
{
key: 'variables',
value: formData.variables,
type: 'systemInput',
label: '变量输入',
connected: true
}
],
......@@ -240,7 +267,9 @@ const simpleChatTemplate = (formData: EditFormType): AppModuleItemType[] => [
inputs: [
{
key: 'userChatInput',
connected: true
connected: true,
label: '用户问题',
type: 'target'
}
],
outputs: [
......@@ -266,10 +295,14 @@ const simpleChatTemplate = (formData: EditFormType): AppModuleItemType[] => [
{
key: 'maxContext',
value: 6,
connected: true
connected: true,
type: 'numberInput',
label: '最长记录数'
},
{
key: 'history',
type: 'hidden',
label: '聊天记录',
connected: true
}
],
......@@ -312,6 +345,8 @@ const kbTemplate = (formData: EditFormType): AppModuleItemType[] => [
inputs: [
{
key: 'userChatInput',
label: '用户问题',
type: 'target',
connected: true
}
],
......@@ -342,10 +377,14 @@ const kbTemplate = (formData: EditFormType): AppModuleItemType[] => [
{
key: 'maxContext',
value: 6,
connected: true
connected: true,
type: 'numberInput',
label: '最长记录数'
},
{
key: 'history',
type: 'hidden',
label: '聊天记录',
connected: true
}
],
......@@ -372,24 +411,34 @@ const kbTemplate = (formData: EditFormType): AppModuleItemType[] => [
{
key: 'kbList',
value: formData.kb.list,
type: FlowInputItemTypeEnum.custom,
label: '关联的知识库',
connected: true
},
{
key: 'similarity',
value: formData.kb.searchSimilarity,
type: FlowInputItemTypeEnum.slider,
label: '相似度',
connected: true
},
{
key: 'limit',
value: formData.kb.searchLimit,
type: FlowInputItemTypeEnum.slider,
label: '单次搜索上限',
connected: true
},
{
key: 'switch',
type: FlowInputItemTypeEnum.target,
label: '触发器',
connected: false
},
{
key: 'userChatInput',
type: FlowInputItemTypeEnum.target,
label: '用户问题',
connected: true
}
],
......@@ -442,11 +491,16 @@ const kbTemplate = (formData: EditFormType): AppModuleItemType[] => [
inputs: [
{
key: 'switch',
type: FlowInputItemTypeEnum.target,
label: '触发器',
connected: true
},
{
key: SpecialInputKeyEnum.answerText,
value: formData.kb.searchEmptyText,
type: FlowInputItemTypeEnum.textarea,
valueType: FlowValueTypeEnum.string,
label: '回复的内容',
connected: true
}
],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment