Files
PromptX/src/lib/core/pouch/commands/LearnCommand.js
2025-06-19 15:59:04 +08:00

351 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const BasePouchCommand = require('../BasePouchCommand')
const { getGlobalResourceManager } = require('../../resource')
const DPMLContentParser = require('../../dpml/DPMLContentParser')
const SemanticRenderer = require('../../dpml/SemanticRenderer')
const CurrentProjectManager = require('../../../utils/CurrentProjectManager')
const { COMMANDS } = require('../../../../constants')
/**
* 智能学习锦囊命令
* 支持加载thought、execution、memory等协议资源以及角色的personality、principle、knowledge
* 支持语义占位符渲染,将@引用展开为完整的语义内容
*/
class LearnCommand extends BasePouchCommand {
constructor () {
super()
// 使用全局单例 ResourceManager
this.resourceManager = getGlobalResourceManager()
this.dpmlParser = new DPMLContentParser()
this.semanticRenderer = new SemanticRenderer()
this.currentProjectManager = new CurrentProjectManager()
}
getPurpose () {
return '智能学习指定协议的资源内容支持thought、execution、memory等DPML协议以及角色组件支持@引用的语义渲染'
}
/**
* 学习指定资源并返回结果
*/
async getContent (args) {
const [resourceUrl] = args
if (!resourceUrl) {
return this.getUsageHelp()
}
// 复用ActionCommand的成功资源加载逻辑
return await this.loadLearnContentUsingActionLogic(resourceUrl)
}
/**
* 使用ActionCommand的成功逻辑加载学习内容
* 这个方法复用了ActionCommand.loadLearnContent的逻辑
*/
async loadLearnContentUsingActionLogic(resourceUrl) {
try {
const result = await this.resourceManager.resolve(resourceUrl)
if (!result.success) {
return this.formatErrorResponse(resourceUrl, result.error.message)
}
// 解析协议信息
const urlMatch = resourceUrl.match(/^(@[!?]?)?([a-zA-Z][a-zA-Z0-9_-]*):\/\/(.+)$/)
if (!urlMatch) {
return this.formatErrorResponse(resourceUrl, "无效的资源URL格式")
}
const [, loadingSemantic, protocol, resourceId] = urlMatch
// 检查内容是否包含@引用,如果包含则进行语义渲染
let finalContent = result.content
if (this.containsReferences(result.content)) {
// 对于完整的DPML标签如<execution>...</execution>),提取标签内容进行渲染
const innerContent = this.extractTagInnerContent(result.content, protocol)
if (innerContent) {
// 解析标签内的混合内容(@引用 + 直接内容)
const tagSemantics = this.dpmlParser.parseTagContent(innerContent, protocol)
// 使用SemanticRenderer进行语义占位符渲染
const renderedInnerContent = await this.semanticRenderer.renderSemanticContent(tagSemantics, this.resourceManager)
// 如果渲染成功重新包装为完整的DPML标签
if (renderedInnerContent && renderedInnerContent.trim()) {
finalContent = `<${protocol}>\n${renderedInnerContent}\n</${protocol}>`
}
}
}
return await this.formatSuccessResponse(protocol, resourceId, finalContent)
} catch (error) {
return this.formatErrorResponse(resourceUrl, error.message)
}
}
/**
* 检查内容是否包含@引用
* @param {string} content - 要检查的内容
* @returns {boolean} 是否包含@引用
*/
containsReferences(content) {
const resourceRegex = /@([!?]?)([a-zA-Z][a-zA-Z0-9_-]*):\/\/([a-zA-Z0-9_\/.,-]+)/g
return resourceRegex.test(content)
}
/**
* 提取完整的DPML标签内容
* @param {string} content - 要提取的内容
* @param {string} protocol - 协议
* @returns {string} 提取的完整DPML标签内容
*/
extractTagInnerContent(content, protocol) {
const tagRegex = new RegExp(`<${protocol}>([\\s\\S]*?)<\\/${protocol}>`, 'i')
const match = content.match(tagRegex)
return match ? match[1].trim() : null
}
/**
* 格式化成功响应
*/
async formatSuccessResponse (protocol, resourceId, content) {
const protocolLabels = {
thought: '🧠 思维模式',
execution: '⚡ 执行模式',
memory: '💾 记忆模式',
personality: '👤 角色人格',
principle: '⚖️ 行为原则',
knowledge: '📚 专业知识'
}
const label = protocolLabels[protocol] || `📄 ${protocol}`
return `✅ **成功学习${label}${resourceId}**
## 📋 学习内容
${content}
## 🎯 学习效果
- ✅ **已激活${label}能力**
- ✅ **相关知识已整合到AI认知体系**
- ✅ **可立即应用于实际场景**
## 🔄 下一步行动:
- 继续学习: 使用 MCP PromptX learn 工具学习其他相关资源
- 应用记忆: 使用 MCP PromptX recall 工具检索相关经验
- 激活角色: 使用 MCP PromptX action 工具激活完整角色能力
📍 当前状态learned_${protocol}`
}
/**
* 格式化错误响应
*/
formatErrorResponse (resourceUrl, errorMessage) {
return `❌ 学习资源失败:${resourceUrl}
🔍 错误详情:
${errorMessage}
💡 支持的协议:
- \`thought://resource-id\` - 学习思维模式
- \`execution://resource-id\` - 学习执行模式
- \`memory://resource-id\` - 学习记忆模式
- \`personality://role-id\` - 学习角色思维
- \`principle://role-id\` - 学习角色原则
- \`knowledge://role-id\` - 学习角色知识
🔍 查看可用资源:
使用 MCP PromptX action 工具查看角色的所有依赖
🔄 下一步行动:
- 继续学习: 使用 MCP PromptX learn 工具学习其他资源
- 应用记忆: 使用 MCP PromptX recall 工具检索相关经验
- 激活角色: 使用 MCP PromptX action 工具激活完整角色能力
- 查看角色列表: 使用 MCP PromptX welcome 工具选择其他角色`
}
/**
* 获取使用帮助
*/
getUsageHelp () {
return `🎓 **Learn锦囊 - 智能学习系统**
## 📖 基本用法
通过 MCP PromptX learn 工具学习资源:
\`<protocol>://<resource-id>\`
## 🎯 支持的协议
### 🔧 DPML核心协议
- **\`thought://\`** - 思维模式资源
- **\`execution://\`** - 执行模式资源
- **\`memory://\`** - 记忆系统资源
### 👤 角色组件协议
- **\`personality://\`** - 角色人格特征
- **\`principle://\`** - 行为原则
- **\`knowledge://\`** - 专业知识
## 📝 使用示例
通过 MCP PromptX learn 工具学习各种资源:
- 学习执行技能: \`execution://deal-at-reference\`
- 学习思维模式: \`thought://prompt-developer\`
- 学习角色人格: \`personality://video-copywriter\`
## 🔍 发现可学习资源
- 使用 MCP PromptX action 工具查看角色需要的所有资源
- 使用 MCP PromptX welcome 工具查看可用角色列表
🔄 下一步行动:
- 激活角色: 使用 MCP PromptX action 工具分析角色依赖
- 查看角色: 使用 MCP PromptX welcome 工具选择感兴趣的角色`
}
/**
* 获取PATEOAS导航信息
*/
getPATEOAS (args) {
const [resourceUrl] = args
if (!resourceUrl) {
return {
currentState: 'learn_awaiting_resource',
availableTransitions: ['welcome', 'action'],
nextActions: [
{
name: '查看可用角色',
description: '返回角色选择页面',
method: 'MCP PromptX welcome 工具',
priority: 'high'
},
{
name: '生成学习计划',
description: '为特定角色生成学习计划',
method: 'MCP PromptX action 工具',
priority: 'high'
}
]
}
}
const urlMatch = resourceUrl.match(/^([a-zA-Z]+):\/\/(.+)$/)
if (!urlMatch) {
return {
currentState: 'learn_error',
availableTransitions: ['welcome', 'action'],
nextActions: [
{
name: '查看使用帮助',
description: '重新学习命令使用方法',
method: 'MCP PromptX learn 工具',
priority: 'high'
}
]
}
}
const [, protocol, resourceId] = urlMatch
return {
currentState: `learned_${protocol}`,
availableTransitions: ['learn', 'recall', 'welcome', 'action'],
nextActions: [
{
name: '继续学习',
description: '学习其他资源',
method: 'MCP PromptX learn 工具',
priority: 'medium'
},
{
name: '应用记忆',
description: '检索相关经验',
method: 'MCP PromptX recall 工具',
priority: 'medium'
},
{
name: '激活角色',
description: '激活完整角色能力',
method: 'MCP PromptX action 工具',
priority: 'high'
},
{
name: '查看角色列表',
description: '选择其他角色',
method: 'MCP PromptX welcome 工具',
priority: 'low'
}
],
metadata: {
learnedResource: resourceUrl,
protocol,
resourceId,
systemVersion: '锦囊串联状态机 v1.0'
}
}
}
/**
* 重写execute方法以添加项目状态检查
*/
async execute (args = []) {
// 获取项目状态提示
const projectPrompt = await this.currentProjectManager.generateTopLevelProjectPrompt('learn')
const purpose = this.getPurpose()
const content = await this.getContent(args)
const pateoas = await this.getPATEOAS(args)
return this.formatOutputWithProjectCheck(purpose, content, pateoas, projectPrompt)
}
/**
* 格式化带有项目检查的输出
*/
formatOutputWithProjectCheck(purpose, content, pateoas, projectPrompt) {
const output = {
purpose,
content,
pateoas,
context: this.context,
format: this.outputFormat,
projectPrompt
}
if (this.outputFormat === 'json') {
return output
}
// 人类可读格式
return {
...output,
toString () {
const divider = '='.repeat(60)
const nextSteps = (pateoas.nextActions || [])
.map(action => ` - ${action.name}: ${action.description}\n 方式: ${action.method || action.command || '通过MCP工具'}`)
.join('\n')
return `${projectPrompt}
${divider}
🎯 锦囊目的:${purpose}
${divider}
📜 锦囊内容:
${content}
🔄 下一步行动:
${nextSteps}
📍 当前状态:${pateoas.currentState}
${divider}
`
}
}
}
}
module.exports = LearnCommand