mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-21 11:43:56 +00:00
V4.9.5 feature (#4520)
* readme * Add queue log * Test interactive (#4509) * Support nested node interaction (#4503) * feat: Add a new InteractiveContext type and update InteractiveBasicType, adding an optional context property to support more complex interaction state management. * feat: Enhance workflow interactivity by adding InteractiveContext support and updating dispatch logic to manage nested contexts and entry nodes more effectively. * feat: Refactor dispatchWorkFlow to utilize InteractiveContext for improved context management * feat: Enhance entry node resolution by adding validation for entryNodeIds and recursive search in InteractiveContext * feat: Remove workflowDepth from InteractiveContext and update recovery logic to utilize parentContext for improved context management * feat: Update getWorkflowEntryNodeIds to use lastInteractive for improved context handling in runtime nodes * feat: Add lastInteractive support to enhance context management across workflow components * feat: Enhance interactive workflow by adding stopForInteractive flag and improving memory edge validation in runtime logic * feat: Refactor InteractiveContext by removing interactiveAppId and updating runtime edge handling in dispatchRunApp for improved context management * feat: Simplify runtime node and edge initialization in dispatchRunApp by using ternary operators for improved readability and maintainability * feat: Improve memory edge validation in initWorkflowEdgeStatus by adding detailed comments for better understanding of subset checks and recursive context searching * feat: Remove commented-out current level information from InteractiveContext for cleaner code and improved readability * feat: Simplify stopForInteractive check in dispatchWorkFlow for improved code clarity and maintainability * feat: Remove stopForInteractive handling and related references for improved code clarity and maintainability * feat: Add interactive response handling in dispatchRunAppNode for enhanced workflow interactivity * feat: Add context property to InteractiveBasicType and InteractiveNodeType for improved interactivity management * feat: remove comments * feat: Remove the node property from ChatDispatchProps to simplify type definitions * feat: Remove workflowInteractiveResponse from dispatchRunAppNode for cleaner code * feat: Refactor interactive value handling in chat history processing for improved clarity * feat: Simplify initWorkflowEdgeStatus logic for better readability and maintainability * feat: Add workflowInteractiveResponse to dispatchWorkFlow for enhanced functionality * feat: Enhance interactive response handling with nested children support * feat: Remove commented-out code for interactive node handling to improve clarity * feat: remove InteractiveContext type * feat: Refactor UserSelectInteractive and UserInputInteractive params for improved structure and clarity * feat: remove * feat: The front end supports extracting the deepest interaction parameters to enhance interaction processing * feat: The front end supports extracting the deepest interaction parameters to enhance interaction processing * fix: handle undefined interactive values in runtimeEdges and runtimeNodes initialization * fix: handle undefined interactive values in runtimeNodes and runtimeEdges initialization * fix: update runtimeNodes and runtimeEdges initialization to use last interactive value * fix: remove unused imports and replace getLastInteractiveValue with lastInteractive in runtimeEdges initialization * fix: import WorkflowInteractiveResponseType and handle lastInteractive as undefined in chatTest * feat: implement extractDeepestInteractive function and refactor usage in AIResponseBox and ChatBox utils * fix: refactor initWorkflowEdgeStatus and getWorkflowEntryNodeIds calls in dispatchRunAppNode for recovery handling * fix: ensure lastInteractive is handled consistently as undefined in runtimeEdges and runtimeNodes initialization * fix: update dispatchFormInput and dispatchUserSelect to use lastInteractive consistently * fix: update condition checks in dispatchFormInput and dispatchUserSelect to ensure lastInteractive type is validated correctly * fix: refactor dispatchRunAppNode to replace isRecovery with childrenInteractive for improved clarity in runtimeNodes and runtimeEdges initialization * refactor: streamline runtimeNodes and runtimeEdges initialization in dispatchRunAppNode for improved readability and maintainability * fix: update rewriteNodeOutputByHistories function to accept runtimeNodes and interactive as parameters for improved clarity * fix: simplify interactiveResponse assignment in dispatchWorkFlow for improved clarity * fix: update entryNodeIds check in getWorkflowEntryNodeIds to ensure it's an array for improved reliability * remove some invalid code --------- Co-authored-by: Theresa <63280168+sd0ric4@users.noreply.github.com> * update doc * update log * fix: update debug workflow to conditionally include nextStepSkipNodes… (#4511) * fix: update debug workflow to conditionally include nextStepSkipNodes based on lastInteractive for improved debugging accuracy * fix : type error * remove invalid code * fix: QA queue * fix: interactive * Test log (#4519) * add log (#4504) * add log * update log i18n * update log * delete template * add i18NT * add team operation log --------- Co-authored-by: gggaaallleee <91131304+gggaaallleee@users.noreply.github.com> * remove search * update doc --------- Co-authored-by: Theresa <63280168+sd0ric4@users.noreply.github.com> Co-authored-by: gggaaallleee <91131304+gggaaallleee@users.noreply.github.com>
This commit is contained in:
@@ -23,7 +23,7 @@ import { WorkflowResponseType } from '../../../../service/core/workflow/dispatch
|
||||
import { AiChatQuoteRoleType } from '../template/system/aiChat/type';
|
||||
import { LafAccountType, OpenaiAccountType } from '../../../support/user/team/type';
|
||||
import { CompletionFinishReason } from '../../ai/type';
|
||||
|
||||
import { WorkflowInteractiveResponseType } from '../template/system/interactive/type';
|
||||
export type ExternalProviderType = {
|
||||
openaiAccount?: OpenaiAccountType;
|
||||
externalWorkflowVariables?: Record<string, string>;
|
||||
@@ -55,6 +55,7 @@ export type ChatDispatchProps = {
|
||||
variables: Record<string, any>; // global variable
|
||||
query: UserChatItemValueItemType[]; // trigger query
|
||||
chatConfig: AppSchema['chatConfig'];
|
||||
lastInteractive?: WorkflowInteractiveResponseType; // last interactive response
|
||||
stream: boolean;
|
||||
maxRunTimes: number;
|
||||
isToolCall?: boolean;
|
||||
|
@@ -10,7 +10,19 @@ import { FlowNodeOutputItemType, ReferenceValueType } from '../type/io';
|
||||
import { ChatItemType, NodeOutputItemType } from '../../../core/chat/type';
|
||||
import { ChatItemValueTypeEnum, ChatRoleEnum } from '../../../core/chat/constants';
|
||||
import { replaceVariable, valToStr } from '../../../common/string/tools';
|
||||
import {
|
||||
InteractiveNodeResponseType,
|
||||
WorkflowInteractiveResponseType
|
||||
} from '../template/system/interactive/type';
|
||||
|
||||
export const extractDeepestInteractive = (
|
||||
interactive: WorkflowInteractiveResponseType
|
||||
): WorkflowInteractiveResponseType => {
|
||||
if (interactive?.type === 'childrenInteractive' && interactive.params?.childrenResponse) {
|
||||
return extractDeepestInteractive(interactive.params.childrenResponse);
|
||||
}
|
||||
return interactive;
|
||||
};
|
||||
export const getMaxHistoryLimitFromNodes = (nodes: StoreNodeItemType[]): number => {
|
||||
let limit = 10;
|
||||
nodes.forEach((node) => {
|
||||
@@ -34,7 +46,9 @@ export const getMaxHistoryLimitFromNodes = (nodes: StoreNodeItemType[]): number
|
||||
1. Get the interactive data
|
||||
2. Check that the workflow starts at the interaction node
|
||||
*/
|
||||
export const getLastInteractiveValue = (histories: ChatItemType[]) => {
|
||||
export const getLastInteractiveValue = (
|
||||
histories: ChatItemType[]
|
||||
): WorkflowInteractiveResponseType | undefined => {
|
||||
const lastAIMessage = [...histories].reverse().find((item) => item.obj === ChatRoleEnum.AI);
|
||||
|
||||
if (lastAIMessage) {
|
||||
@@ -45,7 +59,11 @@ export const getLastInteractiveValue = (histories: ChatItemType[]) => {
|
||||
lastValue.type !== ChatItemValueTypeEnum.interactive ||
|
||||
!lastValue.interactive
|
||||
) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastValue.interactive.type === 'childrenInteractive') {
|
||||
return lastValue.interactive;
|
||||
}
|
||||
|
||||
// Check is user select
|
||||
@@ -62,38 +80,29 @@ export const getLastInteractiveValue = (histories: ChatItemType[]) => {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return;
|
||||
};
|
||||
|
||||
export const initWorkflowEdgeStatus = (
|
||||
edges: StoreEdgeItemType[] | RuntimeEdgeItemType[],
|
||||
histories?: ChatItemType[]
|
||||
edges: StoreEdgeItemType[],
|
||||
lastInteractive?: WorkflowInteractiveResponseType
|
||||
): RuntimeEdgeItemType[] => {
|
||||
// If there is a history, use the last interactive value
|
||||
if (histories && histories.length > 0) {
|
||||
const memoryEdges = getLastInteractiveValue(histories)?.memoryEdges;
|
||||
|
||||
if (lastInteractive) {
|
||||
const memoryEdges = lastInteractive.memoryEdges || [];
|
||||
if (memoryEdges && memoryEdges.length > 0) {
|
||||
return memoryEdges;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
edges?.map((edge) => ({
|
||||
...edge,
|
||||
status: 'waiting'
|
||||
})) || []
|
||||
);
|
||||
return edges?.map((edge) => ({ ...edge, status: 'waiting' })) || [];
|
||||
};
|
||||
|
||||
export const getWorkflowEntryNodeIds = (
|
||||
nodes: (StoreNodeItemType | RuntimeNodeItemType)[],
|
||||
histories?: ChatItemType[]
|
||||
lastInteractive?: WorkflowInteractiveResponseType
|
||||
) => {
|
||||
// If there is a history, use the last interactive entry node
|
||||
if (histories && histories.length > 0) {
|
||||
const entryNodeIds = getLastInteractiveValue(histories)?.entryNodeIds;
|
||||
|
||||
if (lastInteractive) {
|
||||
const entryNodeIds = lastInteractive.entryNodeIds || [];
|
||||
if (Array.isArray(entryNodeIds) && entryNodeIds.length > 0) {
|
||||
return entryNodeIds;
|
||||
}
|
||||
@@ -396,10 +405,10 @@ export const textAdaptGptResponse = ({
|
||||
|
||||
/* Update runtimeNode's outputs with interactive data from history */
|
||||
export function rewriteNodeOutputByHistories(
|
||||
histories: ChatItemType[],
|
||||
runtimeNodes: RuntimeNodeItemType[]
|
||||
runtimeNodes: RuntimeNodeItemType[],
|
||||
lastInteractive?: InteractiveNodeResponseType
|
||||
) {
|
||||
const interactive = getLastInteractiveValue(histories);
|
||||
const interactive = lastInteractive;
|
||||
if (!interactive?.nodeOutputs) {
|
||||
return runtimeNodes;
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import type { NodeOutputItemType } from '../../../../chat/type';
|
||||
import type { FlowNodeOutputItemType } from '../../../type/io';
|
||||
import type { RuntimeEdgeItemType } from '../../../runtime/type';
|
||||
import { FlowNodeInputTypeEnum } from 'core/workflow/node/constant';
|
||||
import { WorkflowIOValueTypeEnum } from 'core/workflow/constants';
|
||||
import type { ChatCompletionMessageParam } from '../../../../ai/type';
|
||||
@@ -9,7 +8,6 @@ type InteractiveBasicType = {
|
||||
entryNodeIds: string[];
|
||||
memoryEdges: RuntimeEdgeItemType[];
|
||||
nodeOutputs: NodeOutputItemType[];
|
||||
|
||||
toolParams?: {
|
||||
entryNodeIds: string[]; // 记录工具中,交互节点的 Id,而不是起始工作流的入口
|
||||
memoryMessages: ChatCompletionMessageParam[]; // 这轮工具中,产生的新的 messages
|
||||
@@ -23,6 +21,13 @@ type InteractiveNodeType = {
|
||||
nodeOutputs?: NodeOutputItemType[];
|
||||
};
|
||||
|
||||
type ChildrenInteractive = InteractiveNodeType & {
|
||||
type: 'childrenInteractive';
|
||||
params: {
|
||||
childrenResponse?: WorkflowInteractiveResponseType;
|
||||
};
|
||||
};
|
||||
|
||||
export type UserSelectOptionItemType = {
|
||||
key: string;
|
||||
value: string;
|
||||
@@ -62,5 +67,9 @@ type UserInputInteractive = InteractiveNodeType & {
|
||||
submitted?: boolean;
|
||||
};
|
||||
};
|
||||
export type InteractiveNodeResponseType = UserSelectInteractive | UserInputInteractive;
|
||||
|
||||
export type InteractiveNodeResponseType =
|
||||
| UserSelectInteractive
|
||||
| UserInputInteractive
|
||||
| ChildrenInteractive;
|
||||
export type WorkflowInteractiveResponseType = InteractiveBasicType & InteractiveNodeResponseType;
|
||||
|
14
packages/global/support/operationLog/constants.ts
Normal file
14
packages/global/support/operationLog/constants.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export enum OperationLogEventEnum {
|
||||
LOGIN = 'LOGIN',
|
||||
CREATE_INVITATION_LINK = 'CREATE_INVITATION_LINK',
|
||||
JOIN_TEAM = 'JOIN_TEAM',
|
||||
CHANGE_MEMBER_NAME = 'CHANGE_MEMBER_NAME',
|
||||
KICK_OUT_TEAM = 'KICK_OUT_TEAM',
|
||||
CREATE_DEPARTMENT = 'CREATE_DEPARTMENT',
|
||||
CHANGE_DEPARTMENT = 'CHANGE_DEPARTMENT',
|
||||
DELETE_DEPARTMENT = 'DELETE_DEPARTMENT',
|
||||
RELOCATE_DEPARTMENT = 'RELOCATE_DEPARTMENT',
|
||||
CREATE_GROUP = 'CREATE_GROUP',
|
||||
DELETE_GROUP = 'DELETE_GROUP',
|
||||
ASSIGN_PERMISSION = 'ASSIGN_PERMISSION'
|
||||
}
|
19
packages/global/support/operationLog/type.d.ts
vendored
Normal file
19
packages/global/support/operationLog/type.d.ts
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import { SourceMemberType } from '../user/type';
|
||||
import { OperationLogEventEnum } from './constants';
|
||||
|
||||
export type OperationLogSchema = {
|
||||
_id: string;
|
||||
tmbId: string;
|
||||
teamId: string;
|
||||
timestamp: Date;
|
||||
event: `${OperationLogEventEnum}`;
|
||||
metadata?: Record<string, string>;
|
||||
};
|
||||
|
||||
export type OperationListItemType = {
|
||||
_id: string;
|
||||
sourceMember: SourceMemberType;
|
||||
event: `${OperationLogEventEnum}`;
|
||||
timestamp: Date;
|
||||
metadata: Record<string, string>;
|
||||
};
|
@@ -1,6 +1,8 @@
|
||||
import { PerConstructPros, Permission } from '../controller';
|
||||
import {
|
||||
TeamApikeyCreatePermissionVal,
|
||||
TeamAppCreatePermissionVal,
|
||||
TeamDatasetCreatePermissionVal,
|
||||
TeamDefaultPermissionVal,
|
||||
TeamPermissionList
|
||||
} from './constant';
|
||||
@@ -23,8 +25,8 @@ export class TeamPermission extends Permission {
|
||||
|
||||
this.setUpdatePermissionCallback(() => {
|
||||
this.hasAppCreatePer = this.checkPer(TeamAppCreatePermissionVal);
|
||||
this.hasDatasetCreatePer = this.checkPer(TeamAppCreatePermissionVal);
|
||||
this.hasApikeyCreatePer = this.checkPer(TeamAppCreatePermissionVal);
|
||||
this.hasDatasetCreatePer = this.checkPer(TeamDatasetCreatePermissionVal);
|
||||
this.hasApikeyCreatePer = this.checkPer(TeamApikeyCreatePermissionVal);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user