feat: Support for Chat Flow & Agent Support for binding a single chat flow (#765)

Co-authored-by: Yu Yang <72337138+tomasyu985@users.noreply.github.com>
Co-authored-by: zengxiaohui <csu.zengxiaohui@gmail.com>
Co-authored-by: lijunwen.gigoo <lijunwen.gigoo@bytedance.com>
Co-authored-by: lvxinyu.1117 <lvxinyu.1117@bytedance.com>
Co-authored-by: liuyunchao.0510 <liuyunchao.0510@bytedance.com>
Co-authored-by: haozhenfei <37089575+haozhenfei@users.noreply.github.com>
Co-authored-by: July <jiangxujin@bytedance.com>
Co-authored-by: tecvan-fe <fanwenjie.fe@bytedance.com>
This commit is contained in:
Zhj
2025-08-28 21:53:32 +08:00
committed by GitHub
parent bbc615a18e
commit d70101c979
503 changed files with 48036 additions and 3427 deletions

View File

@@ -46,9 +46,9 @@ export const getEnabledNodeTypes = (_params: {
[StandardNodeType.Input]: true,
[StandardNodeType.Comment]: true,
[StandardNodeType.VariableMerge]: true,
// [StandardNodeType.QueryMessageList]: true,
// [StandardNodeType.ClearContext]: true,
// [StandardNodeType.CreateConversation]: true,
[StandardNodeType.QueryMessageList]: true,
[StandardNodeType.ClearContext]: true,
[StandardNodeType.CreateConversation]: true,
[StandardNodeType.VariableAssign]: true,
[StandardNodeType.Http]: true,
[StandardNodeType.DatabaseUpdate]: true,
@@ -57,13 +57,13 @@ export const getEnabledNodeTypes = (_params: {
[StandardNodeType.DatabaseCreate]: true,
// [StandardNodeType.JsonParser]: true,
[StandardNodeType.JsonStringify]: true,
// [StandardNodeType.UpdateConversation]: true,
// [StandardNodeType.DeleteConversation]: true,
// [StandardNodeType.QueryConversationList]: true,
// [StandardNodeType.QueryConversationHistory]: true,
// [StandardNodeType.CreateMessage]: true,
// [StandardNodeType.UpdateMessage]: true,
// [StandardNodeType.DeleteMessage]: true,
[StandardNodeType.UpdateConversation]: true,
[StandardNodeType.DeleteConversation]: true,
[StandardNodeType.QueryConversationList]: true,
[StandardNodeType.QueryConversationHistory]: true,
[StandardNodeType.CreateMessage]: true,
[StandardNodeType.UpdateMessage]: true,
[StandardNodeType.DeleteMessage]: true,
};
const enabledNodeTypes: StandardNodeType[] = Object.keys(nodesMap)
.filter(key => nodesMap[key])

View File

@@ -55,13 +55,8 @@ const flowModeOptions = [
label: I18n.t('wf_chatflow_76'),
value: WorkflowMode.ChatFlow,
},
].filter(item => {
// The open-source version does not currently support conversation streaming
if (item.value === WorkflowMode.ChatFlow && IS_OPEN_SOURCE) {
return false;
}
return true;
});
];
const WorkflowModalFilter: FC<WorkFlowModalModeProps> = props => {
const context = useContext(WorkflowModalContext);
const { i18nText, ModalI18nKey } = useI18nText();

View File

@@ -80,8 +80,7 @@ export const CreateWorkflowBtn: FC<
return (
<>
{/* will support soon */}
{showSingleButton || IS_OPEN_SOURCE ? (
{showSingleButton ? (
<Button
className={className}
color="hgltplus"

View File

@@ -17,11 +17,11 @@
import React, { useEffect, useState, useMemo } from 'react';
import { debounce } from 'lodash-es';
import { useService } from '@flowgram-adapter/free-layout-editor';
import { CONVERSATION_NAME, workflowApi } from '@coze-workflow/base';
import { I18n } from '@coze-arch/i18n';
import { Typography, Select } from '@coze-arch/coze-design';
import { CreateMethod, CreateEnv } from '@coze-arch/bot-api/workflow_api';
import { useService } from '@flowgram-adapter/free-layout-editor';
import { ChatflowService } from '@/services';
@@ -131,7 +131,7 @@ export const Conversations: React.FC<ConversationsProps> = ({
?.defaultValue || '';
const findItem = list.find(item => item.label === defaultName);
// The conversation_name of the start node is selected by default, if not, Default default session is selected by default
handleChange(findItem?.value || '0', findItem);
handleChange(findItem?.value || list[0]?.value, findItem || list[0]);
}
};
@@ -155,7 +155,6 @@ export const Conversations: React.FC<ConversationsProps> = ({
findItem?.value !== chatflowService.selectConversationItem?.value
) {
chatflowService.setSelectConversationItem(findItem);
handleChange(findItem?.value || '0');
}
}, [value, staticList, dynamicList]);

View File

@@ -28,3 +28,9 @@
font-size: 12px;
}
}
.float-button-container {
position: relative;
width: 100%;
padding-left: 28px;
}

View File

@@ -41,7 +41,7 @@ export const TestFormFloatButton = ({
}
return (
<>
<div className={css['float-button-container']}>
<div
className={css['float-button']}
onClick={handleOpenForm}
@@ -56,6 +56,6 @@ export const TestFormFloatButton = ({
</Typography.Text>
<IconCozAdjust className="coz-fg-dim" />
</div>
</>
</div>
);
};

View File

@@ -18,6 +18,7 @@ import React, { Suspense, lazy } from 'react';
import { isEmpty } from 'lodash-es';
import { userStoreService } from '@coze-studio/user-store';
import { type IWorkflow, type IProject } from '@coze-studio/open-chat';
import { IntelligenceType } from '@coze-arch/idl/intelligence_api';
import { I18n } from '@coze-arch/i18n';
import { IconCozIllusAdd } from '@coze-arch/coze-design/illustrations';
@@ -26,7 +27,6 @@ import {
type ProjectConversation,
CreateEnv,
} from '@coze-arch/bot-api/workflow_api';
import { type IWorkflow, type IProject } from '@coze-studio/open-chat';
import { useSkeleton } from './use-skeleton';
@@ -72,8 +72,8 @@ export const ChatHistory = ({
const chatUserInfo = {
id: userInfo?.user_id_str || '',
name: userInfo?.name || '',
avatar: userInfo?.avatar_url || '',
nickname: userInfo?.name || '',
url: userInfo?.avatar_url || '',
};
if (
@@ -123,10 +123,12 @@ export const ChatHistory = ({
}}
areaUi={{
isNeedClearContext: false,
isNeedClearMessage: true,
input: {
isShow: showInputArea,
defaultText,
renderChatInputTopSlot: topSlot,
isNeedAudio: false,
},
renderLoading,
uiTheme: 'chatFlow',

View File

@@ -17,6 +17,7 @@
import { useState, useEffect, useRef, Suspense } from 'react';
import { nanoid } from 'nanoid';
import { debounce } from 'lodash-es';
import cls from 'classnames';
import { connect, mapProps } from '@formily/react';
import type { Editor } from '@coze-common/md-editor-adapter';
@@ -56,23 +57,25 @@ const InnerFullInputAdapter: React.FC<FullInputProps> = ({
const businessKeyRef = useRef(nanoid());
const innerValueRef = useRef<string | undefined>();
const handleChange = (v: string) => {
if (!editorRef.current) {
return;
}
/**
* deltas => md
*/
const content = editorRef.current.getContent();
const { markdown } = delta2md(content.deltas[0], content.deltas);
/**
* Changes may come from user input or initialization, do a diff to ensure performance
*/
if (markdown !== innerValueRef.current) {
innerValueRef.current = markdown;
onChange(markdown);
}
};
const handleChange = useRef(
debounce((v: string) => {
if (!editorRef.current) {
return;
}
/**
* deltas => md
*/
const content = editorRef.current.getContent();
const { markdown } = delta2md(content.deltas[0], content.deltas);
/**
* Changes may come from user input or initialization, do a diff to ensure performance
*/
if (markdown !== innerValueRef.current) {
innerValueRef.current = markdown;
onChange(markdown);
}
}, 500),
).current;
useEffect(() => {
if (value !== innerValueRef.current) {
@@ -84,6 +87,13 @@ const InnerFullInputAdapter: React.FC<FullInputProps> = ({
}
}, [value]);
useEffect(
() => () => {
handleChange.cancel();
},
[handleChange],
);
return (
<Suspense fallback={null}>
<LazyEditorFullInputInner