Merge branch 'main' into feat/attachments

This commit is contained in:
StyleZhang
2024-08-15 10:57:59 +08:00
76 changed files with 1076 additions and 404 deletions

View File

@ -922,6 +922,9 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
</Property>
<Property name='document_id' type='string' key='document_id'>
Document ID
</Property>
<Property name='segment_id' type='string' key='segment_id'>
Document Segment ID
</Property>
@ -965,6 +968,9 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
</Property>
<Property name='document_id' type='string' key='document_id'>
Document ID
</Property>
<Property name='segment_id' type='string' key='segment_id'>
Document Segment ID
</Property>

View File

@ -922,6 +922,9 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
<Property name='dataset_id' type='string' key='dataset_id'>
知识库 ID
</Property>
<Property name='document_id' type='string' key='document_id'>
文档 ID
</Property>
<Property name='segment_id' type='string' key='segment_id'>
文档分段ID
</Property>
@ -965,6 +968,9 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
<Property name='dataset_id' type='string' key='dataset_id'>
知识库 ID
</Property>
<Property name='document_id' type='string' key='document_id'>
文档 ID
</Property>
<Property name='segment_id' type='string' key='segment_id'>
文档分段ID
</Property>

View File

@ -1,4 +1,5 @@
import ReactMarkdown from 'react-markdown'
import ReactEcharts from 'echarts-for-react'
import 'katex/dist/katex.min.css'
import RemarkMath from 'remark-math'
import RemarkBreaks from 'remark-breaks'
@ -30,6 +31,7 @@ const capitalizationLanguageNameMap: Record<string, string> = {
mermaid: 'Mermaid',
markdown: 'MarkDown',
makefile: 'MakeFile',
echarts: 'ECharts',
}
const getCorrectCapitalizationLanguageName = (language: string) => {
if (!language)
@ -107,6 +109,14 @@ const CodeBlock: CodeComponent = memo(({ inline, className, children, ...props }
const match = /language-(\w+)/.exec(className || '')
const language = match?.[1]
const languageShowName = getCorrectCapitalizationLanguageName(language || '')
let chartData = JSON.parse(String('{"title":{"text":"Something went wrong."}}').replace(/\n$/, ''))
if (language === 'echarts') {
try {
chartData = JSON.parse(String(children).replace(/\n$/, ''))
}
catch (error) {
}
}
// Use `useMemo` to ensure that `SyntaxHighlighter` only re-renders when necessary
return useMemo(() => {
@ -136,19 +146,25 @@ const CodeBlock: CodeComponent = memo(({ inline, className, children, ...props }
</div>
{(language === 'mermaid' && isSVG)
? (<Flowchart PrimitiveCode={String(children).replace(/\n$/, '')} />)
: (<SyntaxHighlighter
{...props}
style={atelierHeathLight}
customStyle={{
paddingLeft: 12,
backgroundColor: '#fff',
}}
language={match[1]}
showLineNumbers
PreTag="div"
>
{String(children).replace(/\n$/, '')}
</SyntaxHighlighter>)}
: (
(language === 'echarts')
? (<div style={{ minHeight: '250px', minWidth: '250px' }}><ReactEcharts
option={chartData}
>
</ReactEcharts></div>)
: (<SyntaxHighlighter
{...props}
style={atelierHeathLight}
customStyle={{
paddingLeft: 12,
backgroundColor: '#fff',
}}
language={match[1]}
showLineNumbers
PreTag="div"
>
{String(children).replace(/\n$/, '')}
</SyntaxHighlighter>))}
</div>
)
: (

View File

@ -329,36 +329,36 @@ const EditCustomCollectionModal: FC<Props> = ({
<Button variant='primary' onClick={handleSave}>{t('common.operation.save')}</Button>
</div>
</div>
{showEmojiPicker && <EmojiPicker
onSelect={(icon, icon_background) => {
setEmoji({ content: icon, background: icon_background })
setShowEmojiPicker(false)
}}
onClose={() => {
setShowEmojiPicker(false)
}}
/>}
{credentialsModalShow && (
<ConfigCredentials
positionCenter={isAdd}
credential={credential}
onChange={setCredential}
onHide={() => setCredentialsModalShow(false)}
/>)
}
{isShowTestApi && (
<TestApi
positionCenter={isAdd}
tool={currTool as CustomParamSchema}
customCollection={customCollection}
onHide={() => setIsShowTestApi(false)}
/>
)}
</div>
}
isShowMask={true}
clickOutsideNotOpen={true}
/>
{showEmojiPicker && <EmojiPicker
onSelect={(icon, icon_background) => {
setEmoji({ content: icon, background: icon_background })
setShowEmojiPicker(false)
}}
onClose={() => {
setShowEmojiPicker(false)
}}
/>}
{credentialsModalShow && (
<ConfigCredentials
positionCenter={isAdd}
credential={credential}
onChange={setCredential}
onHide={() => setCredentialsModalShow(false)}
/>)
}
{isShowTestApi && (
<TestApi
positionCenter={isAdd}
tool={currTool as CustomParamSchema}
customCollection={customCollection}
onHide={() => setIsShowTestApi(false)}
/>
)}
</>
)

View File

@ -7,12 +7,16 @@ import {
import type { ValueSelector, Var } from '@/app/components/workflow/types'
type Params = {
onlyLeafNodeVar?: boolean
hideEnv?: boolean
hideChatVar?: boolean
filterVar: (payload: Var, selector: ValueSelector) => boolean
}
const useAvailableVarList = (nodeId: string, {
onlyLeafNodeVar,
filterVar,
hideEnv,
hideChatVar,
}: Params = {
onlyLeafNodeVar: false,
filterVar: () => true,
@ -32,6 +36,8 @@ const useAvailableVarList = (nodeId: string, {
beforeNodes: availableNodes,
isChatMode,
filterVar,
hideEnv,
hideChatVar,
})
return {

View File

@ -23,6 +23,8 @@ const Panel: FC<NodePanelProps<AnswerNodeType>> = ({
const { availableVars, availableNodesWithParent } = useAvailableVarList(id, {
onlyLeafNodeVar: false,
hideChatVar: true,
hideEnv: true,
filterVar,
})

View File

@ -62,30 +62,25 @@ const RunPanel: FC<RunProps> = ({ hideResult, activeTab = 'RESULT', runID, getRe
const formatNodeList = useCallback((list: NodeTracing[]) => {
const allItems = list.reverse()
const result: NodeTracing[] = []
let iterationIndexInfos: {
start: number
end: number
}[] = []
let iterationIndex = 0
allItems.forEach((item) => {
const { node_type, index, execution_metadata } = item
const { node_type, execution_metadata } = item
if (node_type !== BlockEnum.Iteration) {
let isInIteration = false
let isIterationFirstNode = false
iterationIndexInfos.forEach(({ start, end }) => {
if (index >= start && index < end) {
if (index === start)
isIterationFirstNode = true
const isInIteration = !!execution_metadata?.iteration_id
isInIteration = true
}
})
if (isInIteration) {
const iterationDetails = result[result.length - 1].details!
if (isIterationFirstNode)
iterationDetails!.push([item])
const currentIterationIndex = execution_metadata?.iteration_index
const isIterationFirstNode = iterationIndex !== currentIterationIndex || iterationDetails.length === 0
else
if (isIterationFirstNode) {
iterationDetails!.push([item])
iterationIndex = currentIterationIndex!
}
else {
iterationDetails[iterationDetails.length - 1].push(item)
}
return
}
@ -95,26 +90,6 @@ const RunPanel: FC<RunProps> = ({ hideResult, activeTab = 'RESULT', runID, getRe
return
}
const { steps_boundary } = execution_metadata
iterationIndexInfos = []
steps_boundary.forEach((boundary, index) => {
if (index === 0) {
iterationIndexInfos.push({
start: boundary,
end: 0,
})
}
else if (index === steps_boundary.length - 1) {
iterationIndexInfos[iterationIndexInfos.length - 1].end = boundary
}
else {
iterationIndexInfos[iterationIndexInfos.length - 1].end = boundary
iterationIndexInfos.push({
start: boundary,
end: 0,
})
}
})
result.push({
...item,
details: [],

View File

@ -123,7 +123,7 @@ const NodePanel: FC<Props> = ({
<div
className='flex items-center h-[34px] justify-between px-3 bg-gray-100 border-[0.5px] border-gray-200 rounded-lg cursor-pointer'
onClick={handleOnShowIterationDetail}>
<div className='leading-[18px] text-[13px] font-medium text-gray-700'>{t('workflow.nodes.iteration.iteration', { count: nodeInfo.metadata?.iterator_length || (nodeInfo.execution_metadata?.steps_boundary?.length - 1) })}</div>
<div className='leading-[18px] text-[13px] font-medium text-gray-700'>{t('workflow.nodes.iteration.iteration', { count: nodeInfo.metadata?.iterator_length })}</div>
{justShowIterationNavArrow
? (
<RiArrowRightSLine className='w-3.5 h-3.5 text-gray-500' />

View File

@ -94,11 +94,38 @@ const translation = {
},
export: {
title: 'シークレット環境変数をエクスポートしますか?',
checkbox: 'シクレト値をエクスポート',
checkbox: 'シクレト値をエクスポート',
ignore: 'DSLをエクスポート',
export: 'シクレト値を含むDSLをエクスポート',
export: 'シクレト値を含むDSLをエクスポート',
},
},
chatVariable: {
panelTitle: '会話変数',
panelDescription: '会話変数は、LLMが記憶すべき対話情報を保存するために使用されます。この情報には、対話の履歴、アップロードされたファイル、ユーザーの好みなどが含まれます。読み書きが可能です。',
docLink: '詳しくはドキュメントをご覧ください。',
button: '変数を追加',
modal: {
title: '会話変数を追加',
editTitle: '会話変数を編集',
name: '名前',
namePlaceholder: '変数名前',
type: 'タイプ',
value: 'デフォルト値',
valuePlaceholder: 'デフォルト値、設定しない場合は空白にしでください',
description: '説明',
descriptionPlaceholder: '変数の説明',
editInJSON: 'JSONで編集する',
oneByOne: '次々に追加する',
editInForm: 'フォームで編集',
arrayValue: '値',
addArrayValue: '値を追加',
objectKey: 'キー',
objectType: 'タイプ',
objectValue: 'デフォルト値',
},
storedContent: '保存されたコンテンツ',
updatedAt: '更新日は',
},
changeHistory: {
title: '変更履歴',
placeholder: 'まだ何も変更していません',
@ -149,6 +176,7 @@ const translation = {
tabs: {
'searchBlock': 'ブロックを検索',
'blocks': 'ブロック',
'searchTool': '検索ツール',
'tools': 'ツール',
'allTool': 'すべて',
'workflowTool': 'ワークフロー',
@ -171,8 +199,9 @@ const translation = {
'code': 'コード',
'template-transform': 'テンプレート',
'http-request': 'HTTPリクエスト',
'variable-assigner': '変数代入',
'variable-assigner': '変数代入',
'variable-aggregator': '変数集約器',
'assigner': '変数代入',
'iteration-start': 'イテレーション開始',
'iteration': 'イテレーション',
'parameter-extractor': 'パラメーター抽出',
@ -189,6 +218,7 @@ const translation = {
'template-transform': 'Jinjaテンプレート構文を使用してデータを文字列に変換します',
'http-request': 'HTTPプロトコル経由でサーバーリクエストを送信できます',
'variable-assigner': '複数のブランチの変数を1つの変数に集約し、下流のードに対して統一された設定を行います。',
'assigner': '変数代入ノードは、書き込み可能な変数(例えば、会話変数)に値を割り当てるために使用されます。',
'variable-aggregator': '複数のブランチの変数を1つの変数に集約し、下流のードに対して統一された設定を行います。',
'iteration': 'リストオブジェクトに対して複数のステップを実行し、すべての結果が出力されるまで繰り返します。',
'parameter-extractor': '自然言語からツールの呼び出しやHTTPリクエストのための構造化されたパラメーターを抽出するためにLLMを使用します。',
@ -215,6 +245,7 @@ const translation = {
checklistResolved: 'すべての問題が解決されました',
organizeBlocks: 'ブロックを整理',
change: '変更',
optional: '(オプション)',
},
nodes: {
common: {
@ -406,6 +437,17 @@ const translation = {
},
setAssignVariable: '代入された変数を設定',
},
assigner: {
'assignedVariable': '代入された変数',
'writeMode': '書き込みモード',
'writeModeTip': '代入された変数が配列の場合, 末尾に追記モードを追加する。',
'over-write': '上書き',
'append': '追記',
'plus': 'プラス',
'clear': 'クリア',
'setVariable': '変数を設定する',
'variable': '変数',
},
tool: {
toAuthorize: '承認するには',
inputVars: '入力変数',

View File

@ -1,6 +1,6 @@
{
"name": "dify-web",
"version": "0.6.16",
"version": "0.7.0",
"private": true,
"engines": {
"node": ">=18.17.0"

View File

@ -24,7 +24,8 @@ export type NodeTracing = {
total_tokens: number
total_price: number
currency: string
steps_boundary: number[]
iteration_id?: string
iteration_index?: number
}
metadata: {
iterator_length: number