Fix: The variables in the message node are not displaying correctly. #11839 (#11841)

### What problem does this PR solve?

Fix: The variables in the message node are not displaying correctly.
#11839

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
balibabu
2025-12-09 17:59:49 +08:00
committed by GitHub
parent 07dca37ef0
commit 30377319d8
3 changed files with 95 additions and 2 deletions

View File

@ -1059,7 +1059,7 @@ General实体和关系提取提示来自 GitHub - microsoft/graphrag基于
exceptionMethod: '异常处理方法',
maxRounds: '最大反思轮数',
delayEfterError: '错误后延迟',
maxRetries: '最大反思轮数',
maxRetries: '最大重试轮数',
advancedSettings: '高级设置',
addTools: '添加工具',
sysPromptDefultValue: `

View File

@ -1,6 +1,7 @@
import { NodeCollapsible } from '@/components/collapse';
import { IMessageNode } from '@/interfaces/database/flow';
import { cn } from '@/lib/utils';
import { useGetVariableLabelOrTypeByValue } from '@/pages/agent/hooks/use-get-begin-query';
import { NodeProps } from '@xyflow/react';
import classNames from 'classnames';
import { get } from 'lodash';
@ -11,9 +12,12 @@ import styles from './index.less';
import NodeHeader from './node-header';
import { NodeWrapper } from './node-wrapper';
import { ToolBar } from './toolbar';
import { VariableDisplay } from './variable-display';
function InnerMessageNode({ id, data, selected }: NodeProps<IMessageNode>) {
const messages: string[] = get(data, 'form.content', []);
const { getLabel } = useGetVariableLabelOrTypeByValue({ nodeId: id });
return (
<ToolBar selected={selected} id={id} label={data.label}>
<NodeWrapper selected={selected} id={id}>
@ -32,7 +36,7 @@ function InnerMessageNode({ id, data, selected }: NodeProps<IMessageNode>) {
<NodeCollapsible items={messages}>
{(x, idx) => (
<LabelCard key={idx} className="truncate">
{x}
<VariableDisplay content={x} getLabel={getLabel} />
</LabelCard>
)}
</NodeCollapsible>

View File

@ -0,0 +1,89 @@
import i18n from '@/locales/config';
import { BeginId } from '@/pages/agent/constant';
import { ReactNode } from 'react';
const prefix = BeginId + '@';
interface VariableDisplayProps {
content: string;
getLabel?: (value?: string) => string | ReactNode;
}
// This component mimics the VariableNode's decorate function from PromptEditor
function VariableNodeDisplay({
value,
label,
}: {
value: string;
label: ReactNode;
}) {
let content: ReactNode = <span className="text-accent-primary">{label}</span>;
if (value.startsWith(prefix)) {
content = (
<div>
<span>{i18n.t(`flow.begin`)}</span> / {content}
</div>
);
}
return <div className="inline-flex items-center mr-1">{content}</div>;
}
export function VariableDisplay({ content, getLabel }: VariableDisplayProps) {
if (!content) return null;
// Regular expression to match content within {}
const regex = /{([^}]*)}/g;
let match;
let lastIndex = 0;
const elements: ReactNode[] = [];
const findLabelByValue = (value: string) => {
if (getLabel) {
const label = getLabel(value);
return label;
}
return null;
};
while ((match = regex.exec(content)) !== null) {
const { 1: variableValue, index, 0: template } = match;
// Add the previous text part (if any)
if (index > lastIndex) {
elements.push(
<span key={`text-${index}`}>{content.slice(lastIndex, index)}</span>,
);
}
// Try to find the label
const label = findLabelByValue(variableValue);
if (label && label !== variableValue) {
// If we found a valid label, render as variable node
elements.push(
<VariableNodeDisplay
key={`variable-${index}`}
value={variableValue}
label={label}
/>,
);
} else {
// If no label found, keep as original text
elements.push(<span key={`text-${index}-template`}>{template}</span>);
}
// Update index
lastIndex = regex.lastIndex;
}
// Add the last part of text (if any)
if (lastIndex < content.length) {
elements.push(
<span key={`text-${lastIndex}`}>{content.slice(lastIndex)}</span>,
);
}
return <>{elements.length > 0 ? elements : content}</>;
}