优化角色注册,发现,nuwa 角色的提示词等
This commit is contained in:
@ -3,6 +3,9 @@ const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const { COMMANDS, buildCommand } = require('../../../../constants')
|
||||
const ResourceManager = require('../../resource/resourceManager')
|
||||
const DPMLContentParser = require('../../resource/DPMLContentParser')
|
||||
const SemanticRenderer = require('../../resource/SemanticRenderer')
|
||||
const logger = require('../../../utils/logger')
|
||||
|
||||
/**
|
||||
* 角色激活锦囊命令
|
||||
@ -14,6 +17,8 @@ class ActionCommand extends BasePouchCommand {
|
||||
// 获取HelloCommand的角色注册表
|
||||
this.helloCommand = null
|
||||
this.resourceManager = new ResourceManager()
|
||||
this.dpmlParser = new DPMLContentParser()
|
||||
this.semanticRenderer = new SemanticRenderer()
|
||||
}
|
||||
|
||||
getPurpose () {
|
||||
@ -38,9 +43,14 @@ ${COMMANDS.HELLO}
|
||||
}
|
||||
|
||||
try {
|
||||
logger.debug(`[ActionCommand] 开始激活角色: ${roleId}`)
|
||||
|
||||
// 1. 获取角色信息
|
||||
const roleInfo = await this.getRoleInfo(roleId)
|
||||
logger.debug(`[ActionCommand] getRoleInfo结果:`, roleInfo)
|
||||
|
||||
if (!roleInfo) {
|
||||
logger.warn(`[ActionCommand] 角色 "${roleId}" 不存在!`)
|
||||
return `❌ 角色 "${roleId}" 不存在!
|
||||
|
||||
🔍 请使用以下命令查看可用角色:
|
||||
@ -71,17 +81,24 @@ ${COMMANDS.HELLO}
|
||||
* 获取角色信息(从HelloCommand)
|
||||
*/
|
||||
async getRoleInfo (roleId) {
|
||||
logger.debug(`[ActionCommand] getRoleInfo调用,角色ID: ${roleId}`)
|
||||
|
||||
// 懒加载HelloCommand实例
|
||||
if (!this.helloCommand) {
|
||||
logger.debug(`[ActionCommand] 创建新的HelloCommand实例`)
|
||||
const HelloCommand = require('./HelloCommand')
|
||||
this.helloCommand = new HelloCommand()
|
||||
} else {
|
||||
logger.debug(`[ActionCommand] 复用现有HelloCommand实例`)
|
||||
}
|
||||
|
||||
return await this.helloCommand.getRoleInfo(roleId)
|
||||
const result = await this.helloCommand.getRoleInfo(roleId)
|
||||
logger.debug(`[ActionCommand] HelloCommand.getRoleInfo返回:`, result)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析角色文件,提取thought和execution依赖
|
||||
* 分析角色文件,提取完整的角色语义(@引用 + 直接内容)
|
||||
*/
|
||||
async analyzeRoleDependencies (roleInfo) {
|
||||
try {
|
||||
@ -99,32 +116,47 @@ ${COMMANDS.HELLO}
|
||||
|
||||
// 读取角色文件内容
|
||||
const roleContent = await fs.readFile(filePath, 'utf-8')
|
||||
|
||||
// 提取所有资源引用
|
||||
const resourceRegex = /@([!?]?)([a-zA-Z][a-zA-Z0-9_-]*):\/\/([a-zA-Z0-9_\/.,-]+?)(?=[\s\)\],]|$)/g
|
||||
const matches = Array.from(roleContent.matchAll(resourceRegex))
|
||||
|
||||
const dependencies = {
|
||||
thoughts: new Set(),
|
||||
executions: new Set(),
|
||||
knowledge: [roleInfo.id] // 角色自身的knowledge
|
||||
}
|
||||
|
||||
// 分类依赖
|
||||
matches.forEach(match => {
|
||||
const [fullMatch, priority, protocol, resource] = match
|
||||
|
||||
if (protocol === 'thought') {
|
||||
dependencies.thoughts.add(resource)
|
||||
} else if (protocol === 'execution') {
|
||||
dependencies.executions.add(resource)
|
||||
|
||||
// 使用DPMLContentParser解析完整的角色语义
|
||||
const roleSemantics = this.dpmlParser.parseRoleDocument(roleContent)
|
||||
|
||||
// 提取@引用依赖(保持兼容性)
|
||||
// 注意:对于包含语义内容的角色,引用已在语义渲染中处理,无需重复加载
|
||||
const thoughts = new Set()
|
||||
const executions = new Set()
|
||||
|
||||
// 从所有标签中提取thought和execution引用
|
||||
// 但排除已在语义内容中处理的引用
|
||||
Object.values(roleSemantics).forEach(tagSemantics => {
|
||||
if (tagSemantics && tagSemantics.references) {
|
||||
tagSemantics.references.forEach(ref => {
|
||||
// 跳过已在语义内容中处理的引用
|
||||
if (tagSemantics.fullSemantics) {
|
||||
// 如果标签有完整语义内容,其引用将在语义渲染中处理,无需独立加载
|
||||
return
|
||||
}
|
||||
|
||||
if (ref.protocol === 'thought') {
|
||||
thoughts.add(ref.resource)
|
||||
} else if (ref.protocol === 'execution') {
|
||||
executions.add(ref.resource)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
thoughts: dependencies.thoughts,
|
||||
executions: dependencies.executions,
|
||||
knowledge: dependencies.knowledge
|
||||
// 保持原有结构(兼容性)
|
||||
thoughts,
|
||||
executions,
|
||||
knowledge: [roleInfo.id],
|
||||
|
||||
// 新增:完整的角色语义结构
|
||||
roleSemantics: {
|
||||
personality: roleSemantics.personality || null,
|
||||
principle: roleSemantics.principle || null,
|
||||
knowledge: roleSemantics.knowledge || null
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error analyzing role dependencies:', error)
|
||||
@ -132,7 +164,12 @@ ${COMMANDS.HELLO}
|
||||
return {
|
||||
thoughts: [],
|
||||
executions: [],
|
||||
knowledge: [roleInfo.id]
|
||||
knowledge: [roleInfo.id],
|
||||
roleSemantics: {
|
||||
personality: null,
|
||||
principle: null,
|
||||
knowledge: null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -267,37 +304,85 @@ ${result.content}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成学习计划并直接加载所有内容
|
||||
* 生成学习计划并直接加载所有内容(包含完整的角色语义)
|
||||
*/
|
||||
async generateLearningPlan (roleId, dependencies) {
|
||||
const { thoughts, executions } = dependencies
|
||||
const { thoughts, executions, roleSemantics } = dependencies
|
||||
|
||||
let content = `🎭 **角色激活完成:${roleId}** - 所有技能已自动加载\n`
|
||||
|
||||
// 加载思维模式
|
||||
// 加载思维模式技能(仅包含独立的thought引用)
|
||||
if (thoughts.size > 0) {
|
||||
content += `# 🧠 思维模式技能 (${thoughts.size}个)\n`
|
||||
|
||||
// 加载引用的思维资源
|
||||
for (const thought of Array.from(thoughts)) {
|
||||
content += await this.loadLearnContent(`thought://${thought}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载执行技能
|
||||
// 添加角色人格特征(支持@引用占位符语义渲染)
|
||||
if (roleSemantics.personality && roleSemantics.personality.fullSemantics) {
|
||||
content += `# 👤 角色人格特征\n`
|
||||
content += `## ✅ 👤 人格特征:${roleId}\n`
|
||||
const personalityContent = await this.semanticRenderer.renderSemanticContent(
|
||||
roleSemantics.personality,
|
||||
this.resourceManager
|
||||
)
|
||||
content += `${personalityContent}\n`
|
||||
content += `---\n`
|
||||
}
|
||||
|
||||
// 加载执行技能(仅包含独立的execution引用)
|
||||
if (executions.size > 0) {
|
||||
content += `# ⚡ 执行技能 (${executions.size}个)\n`
|
||||
|
||||
// 加载引用的执行资源
|
||||
for (const execution of Array.from(executions)) {
|
||||
content += await this.loadLearnContent(`execution://${execution}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 添加角色行为原则(支持@引用占位符语义渲染)
|
||||
if (roleSemantics.principle && roleSemantics.principle.fullSemantics) {
|
||||
content += `# ⚖️ 角色行为原则\n`
|
||||
content += `## ✅ ⚖️ 行为原则:${roleId}\n`
|
||||
const principleContent = await this.semanticRenderer.renderSemanticContent(
|
||||
roleSemantics.principle,
|
||||
this.resourceManager
|
||||
)
|
||||
content += `${principleContent}\n`
|
||||
content += `---\n`
|
||||
}
|
||||
|
||||
// 添加语义渲染的知识体系(支持@引用占位符)
|
||||
if (roleSemantics.knowledge && roleSemantics.knowledge.fullSemantics) {
|
||||
content += `# 📚 专业知识体系\n`
|
||||
content += `## ✅ 📚 知识体系:${roleId}-knowledge\n`
|
||||
const knowledgeContent = await this.semanticRenderer.renderSemanticContent(
|
||||
roleSemantics.knowledge,
|
||||
this.resourceManager
|
||||
)
|
||||
content += `${knowledgeContent}\n`
|
||||
content += `---\n`
|
||||
}
|
||||
|
||||
// 激活总结
|
||||
content += `# 🎯 角色激活总结\n`
|
||||
content += `✅ **${roleId} 角色已完全激活!**\n`
|
||||
content += `📋 **已获得能力**:\n`
|
||||
if (thoughts.size > 0) content += `- 🧠 思维模式:${Array.from(thoughts).join(', ')}\n`
|
||||
if (executions.size > 0) content += `- ⚡ 执行技能:${Array.from(executions).join(', ')}\n`
|
||||
|
||||
// 显示角色核心组件
|
||||
const roleComponents = []
|
||||
if (roleSemantics.personality?.fullSemantics) roleComponents.push('👤 人格特征')
|
||||
if (roleSemantics.principle?.fullSemantics) roleComponents.push('⚖️ 行为原则')
|
||||
if (roleSemantics.knowledge?.fullSemantics) roleComponents.push('📚 专业知识')
|
||||
if (roleComponents.length > 0) {
|
||||
content += `- 🎭 角色组件:${roleComponents.join(', ')}\n`
|
||||
}
|
||||
|
||||
content += `💡 **现在可以立即开始以 ${roleId} 身份提供专业服务!**\n`
|
||||
|
||||
// 自动执行 recall 命令
|
||||
|
||||
@ -2,6 +2,8 @@ const BasePouchCommand = require('../BasePouchCommand')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const { buildCommand } = require('../../../../constants')
|
||||
const SimplifiedRoleDiscovery = require('../../resource/SimplifiedRoleDiscovery')
|
||||
const logger = require('../../../utils/logger')
|
||||
|
||||
/**
|
||||
* 角色发现锦囊命令
|
||||
@ -10,7 +12,8 @@ const { buildCommand } = require('../../../../constants')
|
||||
class HelloCommand extends BasePouchCommand {
|
||||
constructor () {
|
||||
super()
|
||||
this.roleRegistry = null // 角色注册表将从资源系统动态加载
|
||||
// 移除roleRegistry缓存,改为每次实时扫描
|
||||
this.discovery = new SimplifiedRoleDiscovery()
|
||||
}
|
||||
|
||||
getPurpose () {
|
||||
@ -18,28 +21,21 @@ class HelloCommand extends BasePouchCommand {
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态加载角色注册表
|
||||
* 动态加载角色注册表 - 使用SimplifiedRoleDiscovery
|
||||
* 移除缓存机制,每次都实时扫描,确保角色发现的一致性
|
||||
*/
|
||||
async loadRoleRegistry () {
|
||||
if (this.roleRegistry) {
|
||||
return this.roleRegistry
|
||||
}
|
||||
|
||||
// 移除缓存检查,每次都实时扫描
|
||||
// 原因:1) 客户端应用,action频次不高 2) 避免新角色创建后的状态不一致问题
|
||||
|
||||
try {
|
||||
// 使用新的ResourceManager架构
|
||||
const ResourceManager = require('../../resource/resourceManager')
|
||||
const resourceManager = new ResourceManager()
|
||||
// 使用新的SimplifiedRoleDiscovery算法
|
||||
const allRoles = await this.discovery.discoverAllRoles()
|
||||
|
||||
// 加载统一注册表(包含系统+用户资源)
|
||||
const unifiedRegistry = await resourceManager.loadUnifiedRegistry()
|
||||
|
||||
// 提取角色数据
|
||||
const roleData = unifiedRegistry.role || {}
|
||||
|
||||
// 转换为HelloCommand期望的格式
|
||||
this.roleRegistry = {}
|
||||
for (const [roleId, roleInfo] of Object.entries(roleData)) {
|
||||
this.roleRegistry[roleId] = {
|
||||
// 转换为HelloCommand期望的格式,不缓存
|
||||
const roleRegistry = {}
|
||||
for (const [roleId, roleInfo] of Object.entries(allRoles)) {
|
||||
roleRegistry[roleId] = {
|
||||
file: roleInfo.file,
|
||||
name: roleInfo.name || roleId,
|
||||
description: this.extractDescription(roleInfo) || `${roleInfo.name || roleId}专业角色`,
|
||||
@ -48,21 +44,21 @@ class HelloCommand extends BasePouchCommand {
|
||||
}
|
||||
|
||||
// 如果没有任何角色,使用基础角色
|
||||
if (Object.keys(this.roleRegistry).length === 0) {
|
||||
this.roleRegistry = {
|
||||
assistant: {
|
||||
file: '@package://prompt/domain/assistant/assistant.role.md',
|
||||
name: '🙋 智能助手',
|
||||
description: '通用助理角色,提供基础的助理服务和记忆支持',
|
||||
source: 'fallback'
|
||||
}
|
||||
if (Object.keys(roleRegistry).length === 0) {
|
||||
roleRegistry.assistant = {
|
||||
file: '@package://prompt/domain/assistant/assistant.role.md',
|
||||
name: '🙋 智能助手',
|
||||
description: '通用助理角色,提供基础的助理服务和记忆支持',
|
||||
source: 'fallback'
|
||||
}
|
||||
}
|
||||
|
||||
return roleRegistry
|
||||
} catch (error) {
|
||||
console.warn('角色注册表加载失败,使用基础角色:', error.message)
|
||||
logger.warn('角色注册表加载失败,使用基础角色:', error.message)
|
||||
|
||||
// 使用基础角色作为fallback
|
||||
this.roleRegistry = {
|
||||
return {
|
||||
assistant: {
|
||||
file: '@package://prompt/domain/assistant/assistant.role.md',
|
||||
name: '🙋 智能助手',
|
||||
@ -71,8 +67,6 @@ class HelloCommand extends BasePouchCommand {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.roleRegistry
|
||||
}
|
||||
|
||||
/**
|
||||
@ -212,19 +206,28 @@ ${buildCommand.action(allRoles[0]?.id || 'assistant')}
|
||||
* 获取角色信息(提供给其他命令使用)
|
||||
*/
|
||||
async getRoleInfo (roleId) {
|
||||
logger.debug(`[HelloCommand] getRoleInfo调用,角色ID: ${roleId}`)
|
||||
|
||||
const registry = await this.loadRoleRegistry()
|
||||
logger.debug(`[HelloCommand] 注册表加载完成,包含角色:`, Object.keys(registry))
|
||||
|
||||
const roleData = registry[roleId]
|
||||
logger.debug(`[HelloCommand] 查找角色${roleId}结果:`, roleData ? '找到' : '未找到')
|
||||
|
||||
if (!roleData) {
|
||||
logger.debug(`[HelloCommand] 角色${roleId}在注册表中不存在`)
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
const result = {
|
||||
id: roleId,
|
||||
name: roleData.name,
|
||||
description: roleData.description,
|
||||
file: roleData.file
|
||||
}
|
||||
|
||||
logger.debug(`[HelloCommand] 返回角色信息:`, result)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,62 +241,10 @@ ${buildCommand.action(allRoles[0]?.id || 'assistant')}
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态发现本地角色文件
|
||||
* 注意:原来的discoverLocalRoles方法已被移除
|
||||
* 现在使用SimplifiedRoleDiscovery.discoverAllRoles()替代
|
||||
* 这避免了glob依赖和跨平台兼容性问题
|
||||
*/
|
||||
async discoverLocalRoles () {
|
||||
const PackageProtocol = require('../../resource/protocols/PackageProtocol')
|
||||
const packageProtocol = new PackageProtocol()
|
||||
const glob = require('glob')
|
||||
const path = require('path')
|
||||
|
||||
try {
|
||||
const packageRoot = await packageProtocol.getPackageRoot()
|
||||
const domainPath = path.join(packageRoot, 'prompt', 'domain')
|
||||
|
||||
// 扫描所有角色目录
|
||||
const rolePattern = path.join(domainPath, '*', '*.role.md')
|
||||
const roleFiles = glob.sync(rolePattern)
|
||||
|
||||
const discoveredRoles = {}
|
||||
|
||||
for (const roleFile of roleFiles) {
|
||||
try {
|
||||
const content = await fs.readFile(roleFile, 'utf-8')
|
||||
const relativePath = path.relative(packageRoot, roleFile)
|
||||
const roleName = path.basename(roleFile, '.role.md')
|
||||
|
||||
// 尝试从文件内容中提取角色信息
|
||||
let description = '本地发现的角色'
|
||||
let name = `🎭 ${roleName}`
|
||||
|
||||
// 简单的元数据提取(支持多行)
|
||||
const descMatch = content.match(/description:\s*(.+?)(?:\n|$)/i)
|
||||
if (descMatch) {
|
||||
description = descMatch[1].trim()
|
||||
}
|
||||
|
||||
const nameMatch = content.match(/name:\s*(.+?)(?:\n|$)/i)
|
||||
if (nameMatch) {
|
||||
name = nameMatch[1].trim()
|
||||
}
|
||||
|
||||
discoveredRoles[roleName] = {
|
||||
file: `@package://${relativePath}`,
|
||||
name,
|
||||
description,
|
||||
source: 'local-discovery'
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`跳过无效的角色文件: ${roleFile}`, error.message)
|
||||
}
|
||||
}
|
||||
|
||||
return discoveredRoles
|
||||
} catch (error) {
|
||||
console.warn('动态角色发现失败:', error.message)
|
||||
return {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HelloCommand
|
||||
|
||||
Reference in New Issue
Block a user