refactor(behavior-tree)!: 迁移到 Runtime 执行器架构 (#196)

* refactor(behavior-tree)!: 迁移到 Runtime 执行器架构

* fix(behavior-tree): 修复LogAction中的ReDoS安全漏洞

* feat(behavior-tree): 完善行为树核心功能并修复类型错误
This commit is contained in:
YHH
2025-10-31 17:27:38 +08:00
committed by GitHub
parent c58e3411fd
commit 61813e67b6
113 changed files with 7795 additions and 10564 deletions

View File

@@ -0,0 +1,71 @@
import { TaskStatus, NodeType } from '../../Types/TaskStatus';
import { INodeExecutor, NodeExecutionContext, BindingHelper } from '../NodeExecutor';
import { NodeExecutorMetadata } from '../NodeMetadata';
/**
* 日志动作执行器
*
* 输出日志信息
*/
@NodeExecutorMetadata({
implementationType: 'Log',
nodeType: NodeType.Action,
displayName: '日志',
description: '输出日志信息',
category: 'Action',
configSchema: {
message: {
type: 'string',
default: '',
description: '日志消息,支持{key}占位符引用黑板变量',
supportBinding: true
},
logLevel: {
type: 'string',
default: 'info',
description: '日志级别',
options: ['info', 'warn', 'error']
}
}
})
export class LogAction implements INodeExecutor {
execute(context: NodeExecutionContext): TaskStatus {
const { runtime } = context;
const message = BindingHelper.getValue<string>(context, 'message', '');
const logLevel = BindingHelper.getValue<string>(context, 'logLevel', 'info');
const finalMessage = this.replaceBlackboardVariables(message, runtime);
this.log(finalMessage, logLevel);
return TaskStatus.Success;
}
private replaceBlackboardVariables(message: string, runtime: NodeExecutionContext['runtime']): string {
if (!message.includes('{') || !message.includes('}')) {
return message;
}
// 使用限制长度的正则表达式避免 ReDoS 攻击
// 限制占位符名称最多100个字符只允许字母、数字、下划线和点号
return message.replace(/\{([\w.]{1,100})\}/g, (_, key) => {
const value = runtime.getBlackboardValue(key.trim());
return value !== undefined ? String(value) : `{${key}}`;
});
}
private log(message: string, level: string): void {
switch (level) {
case 'error':
console.error(message);
break;
case 'warn':
console.warn(message);
break;
case 'info':
default:
console.log(message);
break;
}
}
}