feat: 更新命令名称为dpml-prompt,保持PromptX品牌名称
This commit is contained in:
@ -1,26 +1,26 @@
|
||||
const BasePouchCommand = require('../BasePouchCommand');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const { COMMANDS, buildCommand } = require('../../../../constants');
|
||||
const BasePouchCommand = require('../BasePouchCommand')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const { COMMANDS, buildCommand } = require('../../../../constants')
|
||||
|
||||
/**
|
||||
* 角色激活锦囊命令
|
||||
* 负责分析角色文件,提取需要学习的thought、execution和knowledge
|
||||
*/
|
||||
class ActionCommand extends BasePouchCommand {
|
||||
constructor() {
|
||||
super();
|
||||
constructor () {
|
||||
super()
|
||||
// 获取HelloCommand的角色注册表
|
||||
this.helloCommand = null;
|
||||
this.helloCommand = null
|
||||
}
|
||||
|
||||
getPurpose() {
|
||||
return '激活特定AI角色,分析并生成具体的思维模式、行为模式和知识学习计划';
|
||||
getPurpose () {
|
||||
return '激活特定AI角色,分析并生成具体的思维模式、行为模式和知识学习计划'
|
||||
}
|
||||
|
||||
async getContent(args) {
|
||||
const [roleId] = args;
|
||||
|
||||
async getContent (args) {
|
||||
const [roleId] = args
|
||||
|
||||
if (!roleId) {
|
||||
return `❌ 请指定要激活的角色ID
|
||||
|
||||
@ -32,29 +32,28 @@ ${buildCommand.action('<角色ID>')}
|
||||
💡 查看可用角色:
|
||||
\`\`\`bash
|
||||
${COMMANDS.HELLO}
|
||||
\`\`\``;
|
||||
\`\`\``
|
||||
}
|
||||
|
||||
try {
|
||||
// 1. 获取角色信息
|
||||
const roleInfo = await this.getRoleInfo(roleId);
|
||||
const roleInfo = await this.getRoleInfo(roleId)
|
||||
if (!roleInfo) {
|
||||
return `❌ 角色 "${roleId}" 不存在!
|
||||
|
||||
🔍 请使用以下命令查看可用角色:
|
||||
\`\`\`bash
|
||||
${COMMANDS.HELLO}
|
||||
\`\`\``;
|
||||
\`\`\``
|
||||
}
|
||||
|
||||
// 2. 分析角色文件,提取依赖
|
||||
const dependencies = await this.analyzeRoleDependencies(roleInfo);
|
||||
|
||||
const dependencies = await this.analyzeRoleDependencies(roleInfo)
|
||||
|
||||
// 3. 生成学习计划 (新版本:以role://开头)
|
||||
return this.generateLearningPlan(roleInfo.id, dependencies);
|
||||
|
||||
return this.generateLearningPlan(roleInfo.id, dependencies)
|
||||
} catch (error) {
|
||||
console.error('Action command error:', error);
|
||||
console.error('Action command error:', error)
|
||||
return `❌ 激活角色 "${roleId}" 时发生错误。
|
||||
|
||||
🔍 可能的原因:
|
||||
@ -62,131 +61,130 @@ ${COMMANDS.HELLO}
|
||||
- 权限不足
|
||||
- 系统资源问题
|
||||
|
||||
💡 请使用 \`${COMMANDS.HELLO}\` 查看可用角色列表。`;
|
||||
💡 请使用 \`${COMMANDS.HELLO}\` 查看可用角色列表。`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色信息(从HelloCommand)
|
||||
*/
|
||||
async getRoleInfo(roleId) {
|
||||
async getRoleInfo (roleId) {
|
||||
// 懒加载HelloCommand实例
|
||||
if (!this.helloCommand) {
|
||||
const HelloCommand = require('./HelloCommand');
|
||||
this.helloCommand = new HelloCommand();
|
||||
const HelloCommand = require('./HelloCommand')
|
||||
this.helloCommand = new HelloCommand()
|
||||
}
|
||||
|
||||
return await this.helloCommand.getRoleInfo(roleId);
|
||||
|
||||
return await this.helloCommand.getRoleInfo(roleId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析角色文件,提取thought和execution依赖
|
||||
*/
|
||||
async analyzeRoleDependencies(roleInfo) {
|
||||
async analyzeRoleDependencies (roleInfo) {
|
||||
try {
|
||||
// 处理文件路径,将@package://前缀替换为实际路径
|
||||
let filePath = roleInfo.file;
|
||||
let filePath = roleInfo.file
|
||||
if (filePath.startsWith('@package://')) {
|
||||
filePath = filePath.replace('@package://', '');
|
||||
filePath = filePath.replace('@package://', '')
|
||||
}
|
||||
|
||||
|
||||
// 读取角色文件内容
|
||||
const roleContent = await fs.readFile(filePath, 'utf-8');
|
||||
|
||||
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 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;
|
||||
|
||||
const [fullMatch, priority, protocol, resource] = match
|
||||
|
||||
if (protocol === 'thought') {
|
||||
dependencies.thoughts.add(resource);
|
||||
dependencies.thoughts.add(resource)
|
||||
} else if (protocol === 'execution') {
|
||||
dependencies.executions.add(resource);
|
||||
dependencies.executions.add(resource)
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
return {
|
||||
thoughts: dependencies.thoughts,
|
||||
executions: dependencies.executions,
|
||||
knowledge: dependencies.knowledge
|
||||
};
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error analyzing role dependencies:', error);
|
||||
console.error('Error analyzing role dependencies:', error)
|
||||
// 如果分析失败,返回基础结构
|
||||
return {
|
||||
thoughts: [],
|
||||
executions: [],
|
||||
knowledge: [roleInfo.id]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成学习指引(基于分析出的依赖)
|
||||
*/
|
||||
generateLearningGuide(roleInfo, dependencies) {
|
||||
generateLearningGuide (roleInfo, dependencies) {
|
||||
let guide = `🎬 **角色激活计划:${roleInfo.name}**
|
||||
|
||||
📋 **角色概述**
|
||||
${roleInfo.description}
|
||||
|
||||
`;
|
||||
`
|
||||
|
||||
// 思维模式部分
|
||||
if (dependencies.thoughts.length > 0) {
|
||||
guide += `## 🧠 第一步:学习思维模式
|
||||
掌握角色所需的核心思考技能
|
||||
|
||||
`;
|
||||
`
|
||||
dependencies.thoughts.forEach((thought, index) => {
|
||||
guide += `### ${index + 1}. ${thought}
|
||||
\`\`\`bash
|
||||
promptx learn thought://${thought}
|
||||
\`\`\`
|
||||
|
||||
`;
|
||||
});
|
||||
`
|
||||
})
|
||||
}
|
||||
|
||||
// 行为模式部分
|
||||
// 行为模式部分
|
||||
if (dependencies.executions.length > 0) {
|
||||
guide += `## ⚖️ 第二步:学习行为模式
|
||||
掌握角色所需的核心执行技能
|
||||
|
||||
`;
|
||||
`
|
||||
dependencies.executions.forEach((execution, index) => {
|
||||
guide += `### ${index + 1}. ${execution}
|
||||
\`\`\`bash
|
||||
promptx learn execution://${execution}
|
||||
\`\`\`
|
||||
|
||||
`;
|
||||
});
|
||||
`
|
||||
})
|
||||
}
|
||||
|
||||
// 知识部分
|
||||
guide += `## 📚 第三步:学习专业知识
|
||||
获取角色的领域知识体系
|
||||
|
||||
`;
|
||||
`
|
||||
dependencies.knowledge.forEach((knowledge, index) => {
|
||||
guide += `### ${index + 1}. ${knowledge} 领域知识
|
||||
\`\`\`bash
|
||||
promptx learn knowledge://${knowledge}
|
||||
\`\`\`
|
||||
|
||||
`;
|
||||
});
|
||||
`
|
||||
})
|
||||
|
||||
// 编排学习
|
||||
guide += `## 🎪 第四步:学习编排方式
|
||||
@ -216,66 +214,66 @@ promptx learn principle://${roleInfo.id}
|
||||
- 🔍 **调用记忆** - 使用 \`promptx recall\` 检索相关经验
|
||||
- 🔄 **切换角色** - 使用 \`promptx hello\` 选择其他专业角色
|
||||
|
||||
💡 **设计理念**:基于 DPML 基础协议组合,通过thought和execution的灵活编排实现角色能力。`;
|
||||
💡 **设计理念**:基于 DPML 基础协议组合,通过thought和execution的灵活编排实现角色能力。`
|
||||
|
||||
return guide;
|
||||
return guide
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成学习计划
|
||||
*/
|
||||
generateLearningPlan(roleId, dependencies) {
|
||||
const { thoughts, executions } = dependencies;
|
||||
|
||||
let plan = `🎭 **准备激活角色:${roleId}**\n\n`;
|
||||
|
||||
generateLearningPlan (roleId, dependencies) {
|
||||
const { thoughts, executions } = dependencies
|
||||
|
||||
let plan = `🎭 **准备激活角色:${roleId}**\n\n`
|
||||
|
||||
// 第一步:学习完整角色
|
||||
plan += `## 🎯 第一步:掌握角色全貌\n`;
|
||||
plan += `理解角色的完整定义和核心特征\n\n`;
|
||||
plan += `\`\`\`bash\n`;
|
||||
plan += `${buildCommand.learn(`role://${roleId}`)}\n`;
|
||||
plan += `\`\`\`\n\n`;
|
||||
|
||||
plan += '## 🎯 第一步:掌握角色全貌\n'
|
||||
plan += '理解角色的完整定义和核心特征\n\n'
|
||||
plan += '```bash\n'
|
||||
plan += `${buildCommand.learn(`role://${roleId}`)}\n`
|
||||
plan += '```\n\n'
|
||||
|
||||
// 第二步:学习思维模式
|
||||
if (thoughts.size > 0) {
|
||||
plan += `## 🧠 第二步:掌握思维模式\n`;
|
||||
plan += `学习角色特定的思考方式和认知框架\n\n`;
|
||||
|
||||
plan += '## 🧠 第二步:掌握思维模式\n'
|
||||
plan += '学习角色特定的思考方式和认知框架\n\n'
|
||||
|
||||
Array.from(thoughts).forEach((thought, index) => {
|
||||
plan += `\`\`\`bash\n`;
|
||||
plan += `${buildCommand.learn(`thought://${thought}`)}\n`;
|
||||
plan += `\`\`\`\n\n`;
|
||||
});
|
||||
plan += '```bash\n'
|
||||
plan += `${buildCommand.learn(`thought://${thought}`)}\n`
|
||||
plan += '```\n\n'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 第三步:掌握执行技能
|
||||
if (executions.size > 0) {
|
||||
plan += `## ⚡ 第${thoughts.size > 0 ? '三' : '二'}步:掌握执行技能\n`;
|
||||
plan += `学习角色的行为模式和操作技能\n\n`;
|
||||
|
||||
plan += `## ⚡ 第${thoughts.size > 0 ? '三' : '二'}步:掌握执行技能\n`
|
||||
plan += '学习角色的行为模式和操作技能\n\n'
|
||||
|
||||
Array.from(executions).forEach((execution, index) => {
|
||||
plan += `\`\`\`bash\n`;
|
||||
plan += `${buildCommand.learn(`execution://${execution}`)}\n`;
|
||||
plan += `\`\`\`\n\n`;
|
||||
});
|
||||
plan += '```bash\n'
|
||||
plan += `${buildCommand.learn(`execution://${execution}`)}\n`
|
||||
plan += '```\n\n'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 激活确认
|
||||
const stepCount = thoughts.size > 0 ? (executions.size > 0 ? '四' : '三') : (executions.size > 0 ? '三' : '二');
|
||||
plan += `## 🎪 第${stepCount}步:完成角色激活\n`;
|
||||
plan += `确认角色能力已完全激活\n\n`;
|
||||
plan += `✅ **角色激活检查清单**:\n`;
|
||||
plan += `- [x] 已学习完整角色定义\n`;
|
||||
if (thoughts.size > 0) plan += `- [x] 已掌握 ${thoughts.size} 个思维模式\n`;
|
||||
if (executions.size > 0) plan += `- [x] 已掌握 ${executions.size} 个执行技能\n`;
|
||||
plan += `- [x] 可以开始以${roleId}身份工作\n\n`;
|
||||
|
||||
return plan;
|
||||
const stepCount = thoughts.size > 0 ? (executions.size > 0 ? '四' : '三') : (executions.size > 0 ? '三' : '二')
|
||||
plan += `## 🎪 第${stepCount}步:完成角色激活\n`
|
||||
plan += '确认角色能力已完全激活\n\n'
|
||||
plan += '✅ **角色激活检查清单**:\n'
|
||||
plan += '- [x] 已学习完整角色定义\n'
|
||||
if (thoughts.size > 0) plan += `- [x] 已掌握 ${thoughts.size} 个思维模式\n`
|
||||
if (executions.size > 0) plan += `- [x] 已掌握 ${executions.size} 个执行技能\n`
|
||||
plan += `- [x] 可以开始以${roleId}身份工作\n\n`
|
||||
|
||||
return plan
|
||||
}
|
||||
|
||||
getPATEOAS(args) {
|
||||
const [roleId] = args;
|
||||
|
||||
getPATEOAS (args) {
|
||||
const [roleId] = args
|
||||
|
||||
if (!roleId) {
|
||||
return {
|
||||
currentState: 'action_awaiting_role',
|
||||
@ -291,7 +289,7 @@ promptx learn principle://${roleInfo.id}
|
||||
metadata: {
|
||||
message: '需要指定角色ID'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
@ -319,8 +317,8 @@ promptx learn principle://${roleInfo.id}
|
||||
systemVersion: '锦囊串联状态机 v1.0',
|
||||
designPhilosophy: 'AI use CLI get prompt for AI'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ActionCommand;
|
||||
module.exports = ActionCommand
|
||||
|
||||
@ -1,87 +1,87 @@
|
||||
const BasePouchCommand = require('../BasePouchCommand');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const { buildCommand } = require('../../../../constants');
|
||||
const BasePouchCommand = require('../BasePouchCommand')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const { buildCommand } = require('../../../../constants')
|
||||
|
||||
/**
|
||||
* 角色发现锦囊命令
|
||||
* 负责展示可用的AI角色和领域专家
|
||||
*/
|
||||
class HelloCommand extends BasePouchCommand {
|
||||
constructor() {
|
||||
super();
|
||||
this.roleRegistry = null; // 角色注册表将从资源系统动态加载
|
||||
constructor () {
|
||||
super()
|
||||
this.roleRegistry = null // 角色注册表将从资源系统动态加载
|
||||
}
|
||||
|
||||
getPurpose() {
|
||||
return '为AI提供可用角色信息,以便AI向主人汇报专业服务选项';
|
||||
getPurpose () {
|
||||
return '为AI提供可用角色信息,以便AI向主人汇报专业服务选项'
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态加载角色注册表
|
||||
*/
|
||||
async loadRoleRegistry() {
|
||||
async loadRoleRegistry () {
|
||||
if (this.roleRegistry) {
|
||||
return this.roleRegistry;
|
||||
return this.roleRegistry
|
||||
}
|
||||
|
||||
try {
|
||||
// 从ResourceManager获取统一注册表
|
||||
const ResourceManager = require('../../resource/resourceManager');
|
||||
const resourceManager = new ResourceManager();
|
||||
await resourceManager.initialize(); // 确保初始化完成
|
||||
|
||||
const ResourceManager = require('../../resource/resourceManager')
|
||||
const resourceManager = new ResourceManager()
|
||||
await resourceManager.initialize() // 确保初始化完成
|
||||
|
||||
if (resourceManager.registry && resourceManager.registry.protocols && resourceManager.registry.protocols.role && resourceManager.registry.protocols.role.registry) {
|
||||
this.roleRegistry = resourceManager.registry.protocols.role.registry;
|
||||
this.roleRegistry = resourceManager.registry.protocols.role.registry
|
||||
} else {
|
||||
// 备用:如果资源系统不可用,使用基础角色
|
||||
this.roleRegistry = {
|
||||
'assistant': {
|
||||
"file": "@package://prompt/domain/assistant/assistant.role.md",
|
||||
"name": "🙋 智能助手",
|
||||
"description": "通用助理角色,提供基础的助理服务和记忆支持"
|
||||
assistant: {
|
||||
file: '@package://prompt/domain/assistant/assistant.role.md',
|
||||
name: '🙋 智能助手',
|
||||
description: '通用助理角色,提供基础的助理服务和记忆支持'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('角色注册表加载失败,使用基础角色:', error.message);
|
||||
console.warn('角色注册表加载失败,使用基础角色:', error.message)
|
||||
this.roleRegistry = {
|
||||
'assistant': {
|
||||
"file": "@package://prompt/domain/assistant/assistant.role.md",
|
||||
"name": "🙋 智能助手",
|
||||
"description": "通用助理角色,提供基础的助理服务和记忆支持"
|
||||
assistant: {
|
||||
file: '@package://prompt/domain/assistant/assistant.role.md',
|
||||
name: '🙋 智能助手',
|
||||
description: '通用助理角色,提供基础的助理服务和记忆支持'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return this.roleRegistry;
|
||||
return this.roleRegistry
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有角色列表(转换为数组格式)
|
||||
*/
|
||||
async getAllRoles() {
|
||||
const registry = await this.loadRoleRegistry();
|
||||
async getAllRoles () {
|
||||
const registry = await this.loadRoleRegistry()
|
||||
return Object.entries(registry).map(([id, roleInfo]) => ({
|
||||
id: id,
|
||||
id,
|
||||
name: roleInfo.name,
|
||||
description: roleInfo.description,
|
||||
file: roleInfo.file
|
||||
}));
|
||||
}))
|
||||
}
|
||||
|
||||
async getContent(args) {
|
||||
await this.loadRoleRegistry();
|
||||
const allRoles = await this.getAllRoles();
|
||||
const totalRoles = allRoles.length;
|
||||
|
||||
async getContent (args) {
|
||||
await this.loadRoleRegistry()
|
||||
const allRoles = await this.getAllRoles()
|
||||
const totalRoles = allRoles.length
|
||||
|
||||
let content = `🤖 **AI专业角色服务清单** (共 ${totalRoles} 个专业角色可供选择)
|
||||
|
||||
> 💡 **重要说明**:以下是可激活的AI专业角色。每个角色都有唯一的ID,使用action命令激活。
|
||||
|
||||
## 📋 可用角色列表
|
||||
|
||||
`;
|
||||
`
|
||||
|
||||
// 清楚显示角色ID和激活命令
|
||||
allRoles.forEach((role, index) => {
|
||||
@ -92,8 +92,8 @@ class HelloCommand extends BasePouchCommand {
|
||||
|
||||
---
|
||||
|
||||
`;
|
||||
});
|
||||
`
|
||||
})
|
||||
|
||||
content += `
|
||||
## 🎯 **角色激活指南**
|
||||
@ -120,19 +120,19 @@ npx promptx action ${allRoles[0]?.id || 'assistant'}
|
||||
📢 **向主人汇报角色选项,明确说明使用方法:"请选择角色ID,然后我将执行对应的action命令"**
|
||||
🎯 **等待主人指定具体的角色ID后,立即执行 \`npx promptx action <角色ID>\`**
|
||||
💡 **强调:action命令需要具体的角色ID,不是角色名称**
|
||||
`;
|
||||
`
|
||||
|
||||
return content;
|
||||
return content
|
||||
}
|
||||
|
||||
async getPATEOAS(args) {
|
||||
const allRoles = await this.getAllRoles();
|
||||
async getPATEOAS (args) {
|
||||
const allRoles = await this.getAllRoles()
|
||||
const availableRoles = allRoles.map(role => ({
|
||||
roleId: role.id,
|
||||
name: role.name,
|
||||
actionCommand: buildCommand.action(role.id)
|
||||
}));
|
||||
|
||||
}))
|
||||
|
||||
return {
|
||||
currentState: 'role_discovery',
|
||||
availableTransitions: ['action', 'learn', 'init', 'recall'],
|
||||
@ -147,44 +147,42 @@ npx promptx action ${allRoles[0]?.id || 'assistant'}
|
||||
],
|
||||
metadata: {
|
||||
totalRoles: allRoles.length,
|
||||
availableRoles: availableRoles,
|
||||
availableRoles,
|
||||
dataSource: 'resource.registry.json',
|
||||
systemVersion: '锦囊串联状态机 v1.0',
|
||||
designPhilosophy: 'AI use CLI get prompt for AI'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取角色信息(提供给其他命令使用)
|
||||
*/
|
||||
async getRoleInfo(roleId) {
|
||||
const registry = await this.loadRoleRegistry();
|
||||
const roleData = registry[roleId];
|
||||
|
||||
async getRoleInfo (roleId) {
|
||||
const registry = await this.loadRoleRegistry()
|
||||
const roleData = registry[roleId]
|
||||
|
||||
if (!roleData) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
id: roleId,
|
||||
name: roleData.name,
|
||||
description: roleData.description,
|
||||
file: roleData.file
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 未来扩展:动态角色发现
|
||||
* TODO: 实现真正的文件扫描和解析
|
||||
*/
|
||||
async discoverAvailableDomains() {
|
||||
async discoverAvailableDomains () {
|
||||
// 现在基于注册表返回角色ID列表
|
||||
const allRoles = await this.getAllRoles();
|
||||
return allRoles.map(role => role.id);
|
||||
const allRoles = await this.getAllRoles()
|
||||
return allRoles.map(role => role.id)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HelloCommand;
|
||||
module.exports = HelloCommand
|
||||
|
||||
@ -1,32 +1,32 @@
|
||||
const BasePouchCommand = require('../BasePouchCommand');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const { ResourceManager } = require('../../resource');
|
||||
const { COMMANDS } = require('../../../../constants');
|
||||
const BasePouchCommand = require('../BasePouchCommand')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const { ResourceManager } = require('../../resource')
|
||||
const { COMMANDS } = require('../../../../constants')
|
||||
|
||||
/**
|
||||
* 初始化锦囊命令
|
||||
* 负责准备工作环境和传达系统协议
|
||||
*/
|
||||
class InitCommand extends BasePouchCommand {
|
||||
constructor() {
|
||||
super();
|
||||
this.resourceManager = new ResourceManager();
|
||||
constructor () {
|
||||
super()
|
||||
this.resourceManager = new ResourceManager()
|
||||
}
|
||||
|
||||
getPurpose() {
|
||||
return '初始化PromptX工作环境,传达系统基本诺记(协议体系)';
|
||||
getPurpose () {
|
||||
return '初始化PromptX工作环境,传达系统基本诺记(协议体系)'
|
||||
}
|
||||
|
||||
async getContent(args) {
|
||||
const [workspacePath = '.'] = args;
|
||||
|
||||
async getContent (args) {
|
||||
const [workspacePath = '.'] = args
|
||||
|
||||
// 1. 技术初始化
|
||||
await this.initializeWorkspace(workspacePath);
|
||||
|
||||
await this.initializeWorkspace(workspacePath)
|
||||
|
||||
// 2. 加载协议体系
|
||||
const protocolContent = await this.loadProtocolSystem();
|
||||
|
||||
const protocolContent = await this.loadProtocolSystem()
|
||||
|
||||
return `🎯 PromptX 系统初始化完成!
|
||||
|
||||
## 🏗️ 技术环境准备
|
||||
@ -48,33 +48,33 @@ ${protocolContent}
|
||||
⚠️ **AI执行指令**:
|
||||
🚀 **立即执行下一个锦囊:${COMMANDS.HELLO}**
|
||||
📢 **不要等待确认,直接进入hello命令发现可用角色!**
|
||||
🎯 **记住:锦囊串联设计,init完成后必须自动进入hello!**`;
|
||||
🎯 **记住:锦囊串联设计,init完成后必须自动进入hello!**`
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载协议体系内容
|
||||
*/
|
||||
async loadProtocolSystem() {
|
||||
async loadProtocolSystem () {
|
||||
try {
|
||||
// 加载完整协议体系:PATEOAS + DPML + 所有标签协议
|
||||
const result = await this.resourceManager.resolve('@prompt://protocols');
|
||||
|
||||
const result = await this.resourceManager.resolve('@prompt://protocols')
|
||||
|
||||
if (result.success) {
|
||||
return result.content;
|
||||
return result.content
|
||||
} else {
|
||||
console.warn('⚠️ 协议加载失败:', result.error?.message);
|
||||
return this.getCoreProtocolSummary();
|
||||
console.warn('⚠️ 协议加载失败:', result.error?.message)
|
||||
return this.getCoreProtocolSummary()
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('⚠️ 无法加载完整协议体系,使用核心摘要:', error.message);
|
||||
return this.getCoreProtocolSummary();
|
||||
console.warn('⚠️ 无法加载完整协议体系,使用核心摘要:', error.message)
|
||||
return this.getCoreProtocolSummary()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取核心协议摘要(fallback)
|
||||
*/
|
||||
getCoreProtocolSummary() {
|
||||
getCoreProtocolSummary () {
|
||||
return `### 🎯 核心理念:AI use CLI get prompt for AI
|
||||
|
||||
**PATEOAS协议** - Prompt as the Engine of Application State
|
||||
@ -91,10 +91,10 @@ ${protocolContent}
|
||||
**三大解决方案**
|
||||
- **上下文遗忘** → 锦囊自包含,每个命令独立执行
|
||||
- **注意力分散** → 分阶段专注,每锦囊专注单一任务
|
||||
- **能力局限** → 即时专家化,通过提示词获得专业能力`;
|
||||
- **能力局限** → 即时专家化,通过提示词获得专业能力`
|
||||
}
|
||||
|
||||
getPATEOAS(args) {
|
||||
getPATEOAS (args) {
|
||||
return {
|
||||
currentState: 'initialized',
|
||||
availableTransitions: ['hello', 'action', 'learn'],
|
||||
@ -117,10 +117,10 @@ ${protocolContent}
|
||||
version: '0.0.1',
|
||||
philosophy: 'AI use CLI get prompt for AI - 锦囊串联无缝衔接'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async initializeWorkspace(workspacePath) {
|
||||
async initializeWorkspace (workspacePath) {
|
||||
// 创建基础目录结构
|
||||
const dirs = [
|
||||
'prompt/core',
|
||||
@ -128,23 +128,23 @@ ${protocolContent}
|
||||
'prompt/protocol',
|
||||
'prompt/resource',
|
||||
'.promptx'
|
||||
];
|
||||
]
|
||||
|
||||
for (const dir of dirs) {
|
||||
await fs.ensureDir(path.join(workspacePath, dir));
|
||||
await fs.ensureDir(path.join(workspacePath, dir))
|
||||
}
|
||||
|
||||
// 创建锦囊状态配置文件
|
||||
const configPath = path.join(workspacePath, '.promptx', 'pouch.json');
|
||||
const configPath = path.join(workspacePath, '.promptx', 'pouch.json')
|
||||
if (!await fs.pathExists(configPath)) {
|
||||
await fs.writeJson(configPath, {
|
||||
version: '0.0.1',
|
||||
initialized: new Date().toISOString(),
|
||||
defaultFormat: 'human',
|
||||
stateHistory: []
|
||||
}, { spaces: 2 });
|
||||
}, { spaces: 2 })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = InitCommand;
|
||||
module.exports = InitCommand
|
||||
|
||||
@ -1,47 +1,46 @@
|
||||
const BasePouchCommand = require('../BasePouchCommand');
|
||||
const ResourceManager = require('../../resource/resourceManager');
|
||||
const { COMMANDS, buildCommand } = require('../../../../constants');
|
||||
const BasePouchCommand = require('../BasePouchCommand')
|
||||
const ResourceManager = require('../../resource/resourceManager')
|
||||
const { COMMANDS, buildCommand } = require('../../../../constants')
|
||||
|
||||
/**
|
||||
* 智能学习锦囊命令
|
||||
* 支持加载thought、execution、memory等协议资源,以及角色的personality、principle、knowledge
|
||||
*/
|
||||
class LearnCommand extends BasePouchCommand {
|
||||
constructor() {
|
||||
super();
|
||||
this.resourceManager = new ResourceManager();
|
||||
constructor () {
|
||||
super()
|
||||
this.resourceManager = new ResourceManager()
|
||||
}
|
||||
|
||||
getPurpose() {
|
||||
return '智能学习指定协议的资源内容,支持thought、execution、memory等DPML协议以及角色组件';
|
||||
getPurpose () {
|
||||
return '智能学习指定协议的资源内容,支持thought、execution、memory等DPML协议以及角色组件'
|
||||
}
|
||||
|
||||
async getContent(args) {
|
||||
const [resourceUrl] = args;
|
||||
|
||||
async getContent (args) {
|
||||
const [resourceUrl] = args
|
||||
|
||||
if (!resourceUrl) {
|
||||
return this.getUsageHelp();
|
||||
return this.getUsageHelp()
|
||||
}
|
||||
|
||||
try {
|
||||
// 直接使用ResourceManager解析资源
|
||||
const content = await this.resourceManager.resolve(resourceUrl);
|
||||
|
||||
const content = await this.resourceManager.resolve(resourceUrl)
|
||||
|
||||
// 解析协议信息
|
||||
const urlMatch = resourceUrl.match(/^([a-zA-Z]+):\/\/(.+)$/);
|
||||
const [, protocol, resourceId] = urlMatch;
|
||||
|
||||
return this.formatSuccessResponse(protocol, resourceId, content);
|
||||
|
||||
const urlMatch = resourceUrl.match(/^([a-zA-Z]+):\/\/(.+)$/)
|
||||
const [, protocol, resourceId] = urlMatch
|
||||
|
||||
return this.formatSuccessResponse(protocol, resourceId, content)
|
||||
} catch (error) {
|
||||
return this.formatErrorResponse(resourceUrl, error.message);
|
||||
return this.formatErrorResponse(resourceUrl, error.message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化成功响应
|
||||
*/
|
||||
formatSuccessResponse(protocol, resourceId, content) {
|
||||
formatSuccessResponse (protocol, resourceId, content) {
|
||||
const protocolLabels = {
|
||||
thought: '🧠 思维模式',
|
||||
execution: '⚡ 执行模式',
|
||||
@ -49,10 +48,10 @@ class LearnCommand extends BasePouchCommand {
|
||||
personality: '👤 角色人格',
|
||||
principle: '⚖️ 行为原则',
|
||||
knowledge: '📚 专业知识'
|
||||
};
|
||||
}
|
||||
|
||||
const label = protocolLabels[protocol] || `📄 ${protocol}`
|
||||
|
||||
const label = protocolLabels[protocol] || `📄 ${protocol}`;
|
||||
|
||||
return `✅ **成功学习${label}:${resourceId}**
|
||||
|
||||
## 📋 学习内容
|
||||
@ -72,13 +71,13 @@ ${content}
|
||||
- 激活角色: 激活完整角色能力
|
||||
命令: \`${buildCommand.action('<role-id>')}\`
|
||||
|
||||
📍 当前状态:learned_${protocol}`;
|
||||
📍 当前状态:learned_${protocol}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化错误响应
|
||||
*/
|
||||
formatErrorResponse(resourceUrl, errorMessage) {
|
||||
formatErrorResponse (resourceUrl, errorMessage) {
|
||||
return `❌ 学习资源失败:${resourceUrl}
|
||||
|
||||
🔍 错误详情:
|
||||
@ -105,13 +104,13 @@ ${buildCommand.action('<role-id>')} # 查看角色的所有依赖
|
||||
- 激活角色: 激活完整角色能力
|
||||
命令: ${buildCommand.action('<role-id>')}
|
||||
- 查看角色列表: 选择其他角色
|
||||
命令: ${COMMANDS.HELLO}`;
|
||||
命令: ${COMMANDS.HELLO}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取使用帮助
|
||||
*/
|
||||
getUsageHelp() {
|
||||
getUsageHelp () {
|
||||
return `🎓 **Learn锦囊 - 智能学习系统**
|
||||
|
||||
## 📖 基本用法
|
||||
@ -153,15 +152,15 @@ ${COMMANDS.HELLO} # 查看可用角色列表
|
||||
- 激活角色: 分析角色依赖
|
||||
命令: ${buildCommand.action('<role-id>')}
|
||||
- 查看角色: 选择感兴趣的角色
|
||||
命令: ${COMMANDS.HELLO}`;
|
||||
命令: ${COMMANDS.HELLO}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取PATEOAS导航信息
|
||||
*/
|
||||
getPATEOAS(args) {
|
||||
const [resourceUrl] = args;
|
||||
|
||||
getPATEOAS (args) {
|
||||
const [resourceUrl] = args
|
||||
|
||||
if (!resourceUrl) {
|
||||
return {
|
||||
currentState: 'learn_awaiting_resource',
|
||||
@ -180,27 +179,27 @@ ${COMMANDS.HELLO} # 查看可用角色列表
|
||||
priority: 'high'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const urlMatch = resourceUrl.match(/^([a-zA-Z]+):\/\/(.+)$/);
|
||||
const urlMatch = resourceUrl.match(/^([a-zA-Z]+):\/\/(.+)$/)
|
||||
if (!urlMatch) {
|
||||
return {
|
||||
currentState: 'learn_error',
|
||||
availableTransitions: ['hello', 'action'],
|
||||
nextActions: [
|
||||
{
|
||||
name: '查看使用帮助',
|
||||
description: '重新学习命令使用方法',
|
||||
command: COMMANDS.LEARN,
|
||||
name: '查看使用帮助',
|
||||
description: '重新学习命令使用方法',
|
||||
command: COMMANDS.LEARN,
|
||||
priority: 'high'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const [, protocol, resourceId] = urlMatch;
|
||||
|
||||
const [, protocol, resourceId] = urlMatch
|
||||
|
||||
return {
|
||||
currentState: `learned_${protocol}`,
|
||||
availableTransitions: ['learn', 'recall', 'hello', 'action'],
|
||||
@ -232,12 +231,12 @@ ${COMMANDS.HELLO} # 查看可用角色列表
|
||||
],
|
||||
metadata: {
|
||||
learnedResource: resourceUrl,
|
||||
protocol: protocol,
|
||||
resourceId: resourceId,
|
||||
protocol,
|
||||
resourceId,
|
||||
systemVersion: '锦囊串联状态机 v1.0'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LearnCommand;
|
||||
module.exports = LearnCommand
|
||||
|
||||
@ -1,38 +1,38 @@
|
||||
const BasePouchCommand = require('../BasePouchCommand');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const { COMMANDS, buildCommand } = require('../../../../constants');
|
||||
const BasePouchCommand = require('../BasePouchCommand')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const { COMMANDS, buildCommand } = require('../../../../constants')
|
||||
|
||||
/**
|
||||
* 记忆检索锦囊命令
|
||||
* 负责从记忆库中检索相关知识和经验
|
||||
*/
|
||||
class RecallCommand extends BasePouchCommand {
|
||||
constructor() {
|
||||
super();
|
||||
constructor () {
|
||||
super()
|
||||
}
|
||||
|
||||
getPurpose() {
|
||||
return 'AI主动检索记忆中的专业知识、最佳实践和历史经验';
|
||||
getPurpose () {
|
||||
return 'AI主动检索记忆中的专业知识、最佳实践和历史经验'
|
||||
}
|
||||
|
||||
async getContent(args) {
|
||||
const [query] = args;
|
||||
async getContent (args) {
|
||||
const [query] = args
|
||||
|
||||
try {
|
||||
const memories = await this.getAllMemories(query);
|
||||
|
||||
const memories = await this.getAllMemories(query)
|
||||
|
||||
if (memories.length === 0) {
|
||||
return `🧠 AI记忆体系中暂无内容。
|
||||
|
||||
💡 建议:
|
||||
1. 使用 ${COMMANDS.REMEMBER} 内化新知识
|
||||
2. 使用 ${COMMANDS.LEARN} 学习后再内化
|
||||
3. 开始构建AI的专业知识体系`;
|
||||
3. 开始构建AI的专业知识体系`
|
||||
}
|
||||
|
||||
const formattedMemories = this.formatRetrievedKnowledge(memories, query);
|
||||
|
||||
const formattedMemories = this.formatRetrievedKnowledge(memories, query)
|
||||
|
||||
return `🧠 AI记忆体系 ${query ? `检索"${query}"` : '全部记忆'} (${memories.length}条):
|
||||
|
||||
${formattedMemories}
|
||||
@ -40,31 +40,31 @@ ${formattedMemories}
|
||||
💡 记忆运用建议:
|
||||
1. 结合当前任务场景灵活运用
|
||||
2. 根据实际情况调整和变通
|
||||
3. 持续学习和增强记忆能力`;
|
||||
3. 持续学习和增强记忆能力`
|
||||
} catch (error) {
|
||||
return `❌ 检索记忆时出错:${error.message}`;
|
||||
return `❌ 检索记忆时出错:${error.message}`
|
||||
}
|
||||
}
|
||||
|
||||
getPATEOAS(args) {
|
||||
const [query] = args;
|
||||
|
||||
getPATEOAS (args) {
|
||||
const [query] = args
|
||||
|
||||
if (!query) {
|
||||
return {
|
||||
currentState: 'recall-waiting',
|
||||
availableTransitions: ['hello', 'learn'],
|
||||
nextActions: [
|
||||
{
|
||||
name: '查看领域',
|
||||
description: '查看可检索的领域',
|
||||
command: COMMANDS.HELLO
|
||||
}
|
||||
{
|
||||
name: '查看领域',
|
||||
description: '查看可检索的领域',
|
||||
command: COMMANDS.HELLO
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const domain = this.extractDomain(query);
|
||||
|
||||
const domain = this.extractDomain(query)
|
||||
|
||||
return {
|
||||
currentState: `recalled-${query}`,
|
||||
availableTransitions: ['action', 'learn', 'remember'],
|
||||
@ -91,128 +91,128 @@ ${formattedMemories}
|
||||
}
|
||||
],
|
||||
metadata: {
|
||||
query: query,
|
||||
query,
|
||||
resultCount: this.lastSearchCount || 0,
|
||||
searchTime: new Date().toISOString()
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有记忆(紧凑格式)
|
||||
*/
|
||||
async getAllMemories(query) {
|
||||
this.lastSearchCount = 0;
|
||||
const memories = [];
|
||||
|
||||
async getAllMemories (query) {
|
||||
this.lastSearchCount = 0
|
||||
const memories = []
|
||||
|
||||
// 读取单一记忆文件
|
||||
const memoryFile = path.join(process.cwd(), '.promptx/memory/declarative.md');
|
||||
|
||||
const memoryFile = path.join(process.cwd(), '.promptx/memory/declarative.md')
|
||||
|
||||
try {
|
||||
if (await fs.pathExists(memoryFile)) {
|
||||
const content = await fs.readFile(memoryFile, 'utf-8');
|
||||
const lines = content.split('\n');
|
||||
|
||||
const content = await fs.readFile(memoryFile, 'utf-8')
|
||||
const lines = content.split('\n')
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('- ')) {
|
||||
// 解析记忆行
|
||||
const memory = this.parseMemoryLine(line);
|
||||
const memory = this.parseMemoryLine(line)
|
||||
if (memory && (!query || this.matchesMemory(memory, query))) {
|
||||
memories.push(memory);
|
||||
memories.push(memory)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error reading memories:', error);
|
||||
console.error('Error reading memories:', error)
|
||||
}
|
||||
|
||||
this.lastSearchCount = memories.length;
|
||||
return memories;
|
||||
this.lastSearchCount = memories.length
|
||||
return memories
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析记忆行(紧凑格式)
|
||||
*/
|
||||
parseMemoryLine(line) {
|
||||
parseMemoryLine (line) {
|
||||
// 格式:- 2025/05/31 14:30 内容 #key #tag1 #tag2 #评分:8 #有效期:长期
|
||||
const match = line.match(/^- (\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}) (.*?) (#\w+.*?)$/);
|
||||
if (!match) return null;
|
||||
|
||||
const [, timestamp, content, tagsStr] = match;
|
||||
const tags = tagsStr.split(' ').filter(t => t.startsWith('#'));
|
||||
const keyTag = tags.find(t => !t.includes(':') && !['#敏捷开发', '#测试', '#部署', '#前端开发', '#后端开发', '#AI', '#最佳实践', '#流程管理', '#工具使用', '#其他'].includes(t));
|
||||
|
||||
const match = line.match(/^- (\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}) (.*?) (#\w+.*?)$/)
|
||||
if (!match) return null
|
||||
|
||||
const [, timestamp, content, tagsStr] = match
|
||||
const tags = tagsStr.split(' ').filter(t => t.startsWith('#'))
|
||||
const keyTag = tags.find(t => !t.includes(':') && !['#敏捷开发', '#测试', '#部署', '#前端开发', '#后端开发', '#AI', '#最佳实践', '#流程管理', '#工具使用', '#其他'].includes(t))
|
||||
|
||||
return {
|
||||
timestamp,
|
||||
content,
|
||||
key: keyTag ? keyTag.substring(1) : 'unknown',
|
||||
tags,
|
||||
source: keyTag ? keyTag.substring(1) : 'unknown'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查记忆是否匹配查询
|
||||
*/
|
||||
matchesMemory(memory, query) {
|
||||
const lowerQuery = query.toLowerCase();
|
||||
matchesMemory (memory, query) {
|
||||
const lowerQuery = query.toLowerCase()
|
||||
return memory.content.toLowerCase().includes(lowerQuery) ||
|
||||
memory.key.toLowerCase().includes(lowerQuery) ||
|
||||
memory.tags.some(tag => tag.toLowerCase().includes(lowerQuery));
|
||||
memory.tags.some(tag => tag.toLowerCase().includes(lowerQuery))
|
||||
}
|
||||
|
||||
matchesQuery(content, query) {
|
||||
const lowerContent = content.toLowerCase();
|
||||
const lowerQuery = query.toLowerCase();
|
||||
const keywords = lowerQuery.split(/\s+/);
|
||||
|
||||
return keywords.some(keyword => lowerContent.includes(keyword));
|
||||
matchesQuery (content, query) {
|
||||
const lowerContent = content.toLowerCase()
|
||||
const lowerQuery = query.toLowerCase()
|
||||
const keywords = lowerQuery.split(/\s+/)
|
||||
|
||||
return keywords.some(keyword => lowerContent.includes(keyword))
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化检索到的记忆(紧凑格式)
|
||||
*/
|
||||
formatRetrievedKnowledge(memories, query) {
|
||||
formatRetrievedKnowledge (memories, query) {
|
||||
return memories.map((memory, index) => {
|
||||
const content = memory.content.length > 120 ?
|
||||
memory.content.substring(0, 120) + '...' :
|
||||
memory.content;
|
||||
|
||||
const content = memory.content.length > 120
|
||||
? memory.content.substring(0, 120) + '...'
|
||||
: memory.content
|
||||
|
||||
return `📝 ${index + 1}. **${memory.key}** (${memory.timestamp})
|
||||
|
||||
${content}
|
||||
|
||||
${memory.tags.slice(0, 5).join(' ')}
|
||||
|
||||
---`;
|
||||
}).join('\n\n');
|
||||
---`
|
||||
}).join('\n\n')
|
||||
}
|
||||
|
||||
extractDomain(query) {
|
||||
const domains = ['copywriter', 'scrum', 'developer', 'test', 'prompt'];
|
||||
const lowerQuery = query.toLowerCase();
|
||||
|
||||
return domains.find(domain => lowerQuery.includes(domain)) || null;
|
||||
extractDomain (query) {
|
||||
const domains = ['copywriter', 'scrum', 'developer', 'test', 'prompt']
|
||||
const lowerQuery = query.toLowerCase()
|
||||
|
||||
return domains.find(domain => lowerQuery.includes(domain)) || null
|
||||
}
|
||||
|
||||
getRelatedQuery(query) {
|
||||
getRelatedQuery (query) {
|
||||
const relatedMap = {
|
||||
'copywriter': 'marketing',
|
||||
'scrum': 'agile',
|
||||
'frontend': 'ui',
|
||||
'backend': 'api',
|
||||
'test': 'qa'
|
||||
};
|
||||
|
||||
copywriter: 'marketing',
|
||||
scrum: 'agile',
|
||||
frontend: 'ui',
|
||||
backend: 'api',
|
||||
test: 'qa'
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(relatedMap)) {
|
||||
if (query.toLowerCase().includes(key)) {
|
||||
return value;
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
return query + '-advanced';
|
||||
|
||||
return query + '-advanced'
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RecallCommand;
|
||||
module.exports = RecallCommand
|
||||
|
||||
@ -1,27 +1,27 @@
|
||||
const BasePouchCommand = require('../BasePouchCommand');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const { COMMANDS, buildCommand } = require('../../../../constants');
|
||||
const BasePouchCommand = require('../BasePouchCommand')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const { COMMANDS, buildCommand } = require('../../../../constants')
|
||||
|
||||
/**
|
||||
* 记忆保存锦囊命令
|
||||
* 负责将知识、经验和最佳实践保存到记忆库中
|
||||
*/
|
||||
class RememberCommand extends BasePouchCommand {
|
||||
constructor() {
|
||||
super();
|
||||
constructor () {
|
||||
super()
|
||||
}
|
||||
|
||||
getPurpose() {
|
||||
return '增强AI长期记忆能力,主动内化专业知识、最佳实践和项目经验';
|
||||
getPurpose () {
|
||||
return '增强AI长期记忆能力,主动内化专业知识、最佳实践和项目经验'
|
||||
}
|
||||
|
||||
async getContent(args) {
|
||||
const [key, ...valueParts] = args;
|
||||
const value = valueParts.join(' ');
|
||||
|
||||
async getContent (args) {
|
||||
const [key, ...valueParts] = args
|
||||
const value = valueParts.join(' ')
|
||||
|
||||
if (!key) {
|
||||
return this.getUsageHelp();
|
||||
return this.getUsageHelp()
|
||||
}
|
||||
|
||||
if (!value) {
|
||||
@ -36,15 +36,14 @@ ${buildCommand.remember('<记忆标识>', '<知识内容>')}
|
||||
\`\`\`bash
|
||||
${buildCommand.remember('copywriter-tips', '"视频文案要有强烈的画面感和节奏感"')}
|
||||
${buildCommand.remember('scrum-daily', '"每日站会应该控制在15分钟内,关注昨天、今天、阻碍"')}
|
||||
\`\`\``;
|
||||
\`\`\``
|
||||
}
|
||||
|
||||
try {
|
||||
const memoryEntry = await this.saveMemory(key, value);
|
||||
|
||||
return this.formatSaveResponse(key, value, memoryEntry);
|
||||
|
||||
} catch (error) {
|
||||
const memoryEntry = await this.saveMemory(key, value)
|
||||
|
||||
return this.formatSaveResponse(key, value, memoryEntry)
|
||||
} catch (error) {
|
||||
return `❌ 记忆内化失败:${error.message}
|
||||
|
||||
💡 可能的原因:
|
||||
@ -55,88 +54,88 @@ ${buildCommand.remember('scrum-daily', '"每日站会应该控制在15分钟内
|
||||
🔧 解决方案:
|
||||
1. 检查 .promptx 目录权限
|
||||
2. 确保磁盘空间充足
|
||||
3. 使用简洁的记忆标识(字母、数字、连字符)`;
|
||||
3. 使用简洁的记忆标识(字母、数字、连字符)`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将知识内化到AI记忆体系(紧凑格式)
|
||||
*/
|
||||
async saveMemory(key, value) {
|
||||
async saveMemory (key, value) {
|
||||
// 1. 确保AI记忆体系目录存在
|
||||
const memoryDir = await this.ensureMemoryDirectory();
|
||||
|
||||
const memoryDir = await this.ensureMemoryDirectory()
|
||||
|
||||
// 2. 使用单一记忆文件
|
||||
const memoryFile = path.join(memoryDir, 'declarative.md');
|
||||
|
||||
const memoryFile = path.join(memoryDir, 'declarative.md')
|
||||
|
||||
// 3. 格式化为一行记忆
|
||||
const memoryLine = this.formatMemoryLine(key, value);
|
||||
|
||||
const memoryLine = this.formatMemoryLine(key, value)
|
||||
|
||||
// 4. 追加到记忆文件
|
||||
const action = await this.appendToMemoryFile(memoryFile, key, memoryLine);
|
||||
|
||||
const action = await this.appendToMemoryFile(memoryFile, key, memoryLine)
|
||||
|
||||
return {
|
||||
key,
|
||||
value,
|
||||
filePath: memoryFile,
|
||||
action,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保AI记忆体系目录存在
|
||||
*/
|
||||
async ensureMemoryDirectory() {
|
||||
const promptxDir = path.join(process.cwd(), '.promptx');
|
||||
const memoryDir = path.join(promptxDir, 'memory');
|
||||
|
||||
await fs.ensureDir(memoryDir);
|
||||
|
||||
return memoryDir;
|
||||
async ensureMemoryDirectory () {
|
||||
const promptxDir = path.join(process.cwd(), '.promptx')
|
||||
const memoryDir = path.join(promptxDir, 'memory')
|
||||
|
||||
await fs.ensureDir(memoryDir)
|
||||
|
||||
return memoryDir
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化为一行记忆(紧凑格式)
|
||||
*/
|
||||
formatMemoryLine(key, value) {
|
||||
const now = new Date();
|
||||
const timestamp = `${now.getFullYear()}/${String(now.getMonth() + 1).padStart(2, '0')}/${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
|
||||
|
||||
formatMemoryLine (key, value) {
|
||||
const now = new Date()
|
||||
const timestamp = `${now.getFullYear()}/${String(now.getMonth() + 1).padStart(2, '0')}/${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`
|
||||
|
||||
// 自动生成标签
|
||||
const tags = this.generateTags(key, value);
|
||||
|
||||
return `- ${timestamp} ${value} #${key} ${tags} #评分:8 #有效期:长期`;
|
||||
const tags = this.generateTags(key, value)
|
||||
|
||||
return `- ${timestamp} ${value} #${key} ${tags} #评分:8 #有效期:长期`
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动生成标签
|
||||
*/
|
||||
generateTags(key, value) {
|
||||
const tags = [];
|
||||
const lowerKey = key.toLowerCase();
|
||||
const lowerValue = value.toLowerCase();
|
||||
|
||||
generateTags (key, value) {
|
||||
const tags = []
|
||||
const lowerKey = key.toLowerCase()
|
||||
const lowerValue = value.toLowerCase()
|
||||
|
||||
// 基于key生成标签
|
||||
if (lowerKey.includes('scrum') || lowerKey.includes('agile')) tags.push('#敏捷开发');
|
||||
if (lowerKey.includes('test') || lowerKey.includes('qa')) tags.push('#测试');
|
||||
if (lowerKey.includes('deploy') || lowerKey.includes('发布')) tags.push('#部署');
|
||||
if (lowerKey.includes('react') || lowerKey.includes('前端')) tags.push('#前端开发');
|
||||
if (lowerKey.includes('api') || lowerKey.includes('后端')) tags.push('#后端开发');
|
||||
if (lowerKey.includes('prompt') || lowerKey.includes('ai')) tags.push('#AI');
|
||||
|
||||
if (lowerKey.includes('scrum') || lowerKey.includes('agile')) tags.push('#敏捷开发')
|
||||
if (lowerKey.includes('test') || lowerKey.includes('qa')) tags.push('#测试')
|
||||
if (lowerKey.includes('deploy') || lowerKey.includes('发布')) tags.push('#部署')
|
||||
if (lowerKey.includes('react') || lowerKey.includes('前端')) tags.push('#前端开发')
|
||||
if (lowerKey.includes('api') || lowerKey.includes('后端')) tags.push('#后端开发')
|
||||
if (lowerKey.includes('prompt') || lowerKey.includes('ai')) tags.push('#AI')
|
||||
|
||||
// 基于value生成标签
|
||||
if (lowerValue.includes('最佳实践') || lowerValue.includes('规则')) tags.push('#最佳实践');
|
||||
if (lowerValue.includes('流程') || lowerValue.includes('步骤')) tags.push('#流程管理');
|
||||
if (lowerValue.includes('命令') || lowerValue.includes('工具')) tags.push('#工具使用');
|
||||
|
||||
return tags.join(' ') || '#其他';
|
||||
if (lowerValue.includes('最佳实践') || lowerValue.includes('规则')) tags.push('#最佳实践')
|
||||
if (lowerValue.includes('流程') || lowerValue.includes('步骤')) tags.push('#流程管理')
|
||||
if (lowerValue.includes('命令') || lowerValue.includes('工具')) tags.push('#工具使用')
|
||||
|
||||
return tags.join(' ') || '#其他'
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加到记忆文件
|
||||
*/
|
||||
async appendToMemoryFile(memoryFile, key, memoryLine) {
|
||||
async appendToMemoryFile (memoryFile, key, memoryLine) {
|
||||
// 初始化文件(如果不存在)
|
||||
if (!await fs.pathExists(memoryFile)) {
|
||||
await fs.writeFile(memoryFile, `# 陈述性记忆
|
||||
@ -145,42 +144,40 @@ ${buildCommand.remember('scrum-daily', '"每日站会应该控制在15分钟内
|
||||
|
||||
${memoryLine}
|
||||
|
||||
`);
|
||||
return 'created';
|
||||
`)
|
||||
return 'created'
|
||||
}
|
||||
|
||||
|
||||
// 读取现有内容
|
||||
const content = await fs.readFile(memoryFile, 'utf-8');
|
||||
|
||||
const content = await fs.readFile(memoryFile, 'utf-8')
|
||||
|
||||
// 检查是否已存在相同key的记忆
|
||||
const keyPattern = new RegExp(`^- .*#${key}\\b`, 'm');
|
||||
const keyPattern = new RegExp(`^- .*#${key}\\b`, 'm')
|
||||
if (keyPattern.test(content)) {
|
||||
// 替换现有记忆
|
||||
const updatedContent = content.replace(keyPattern, memoryLine);
|
||||
await fs.writeFile(memoryFile, updatedContent);
|
||||
return 'updated';
|
||||
const updatedContent = content.replace(keyPattern, memoryLine)
|
||||
await fs.writeFile(memoryFile, updatedContent)
|
||||
return 'updated'
|
||||
} else {
|
||||
// 追加新记忆(在高价值记忆部分)
|
||||
const insertPosition = content.indexOf('\n\n') + 2;
|
||||
const updatedContent = content.slice(0, insertPosition) + memoryLine + '\n\n' + content.slice(insertPosition);
|
||||
await fs.writeFile(memoryFile, updatedContent);
|
||||
return 'created';
|
||||
const insertPosition = content.indexOf('\n\n') + 2
|
||||
const updatedContent = content.slice(0, insertPosition) + memoryLine + '\n\n' + content.slice(insertPosition)
|
||||
await fs.writeFile(memoryFile, updatedContent)
|
||||
return 'created'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 格式化保存响应(简化版本)
|
||||
*/
|
||||
formatSaveResponse(key, value, memoryEntry) {
|
||||
const { action, timestamp } = memoryEntry;
|
||||
|
||||
formatSaveResponse (key, value, memoryEntry) {
|
||||
const { action, timestamp } = memoryEntry
|
||||
|
||||
const actionLabels = {
|
||||
created: '✅ AI已内化新记忆',
|
||||
updated: '🔄 AI已更新记忆'
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return `${actionLabels[action]}:${key}
|
||||
|
||||
## 📋 记忆详情
|
||||
@ -201,13 +198,13 @@ ${memoryLine}
|
||||
- 应用实践: 在实际场景中运用记忆
|
||||
命令: \`${buildCommand.action('<role-id>')}\`
|
||||
|
||||
📍 当前状态:memory_saved`;
|
||||
📍 当前状态:memory_saved`
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取使用帮助
|
||||
*/
|
||||
getUsageHelp() {
|
||||
getUsageHelp () {
|
||||
return `🧠 **Remember锦囊 - AI记忆增强系统**
|
||||
|
||||
## 📖 基本用法
|
||||
@ -241,16 +238,16 @@ ${buildCommand.action('<role-id>')} # AI运用记忆激活角色
|
||||
- 开始记忆: 内化第一条知识
|
||||
命令: ${buildCommand.remember('<key>', '<content>')}
|
||||
- 学习资源: 学习新知识再内化
|
||||
命令: ${buildCommand.learn('<protocol>://<resource>')}`;
|
||||
命令: ${buildCommand.learn('<protocol>://<resource>')}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取PATEOAS导航信息
|
||||
*/
|
||||
getPATEOAS(args) {
|
||||
const [key, ...valueParts] = args;
|
||||
const value = valueParts.join(' ');
|
||||
|
||||
getPATEOAS (args) {
|
||||
const [key, ...valueParts] = args
|
||||
const value = valueParts.join(' ')
|
||||
|
||||
if (!key) {
|
||||
return {
|
||||
currentState: 'remember_awaiting_input',
|
||||
@ -269,7 +266,7 @@ ${buildCommand.action('<role-id>')} # AI运用记忆激活角色
|
||||
priority: 'high'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!value) {
|
||||
@ -284,7 +281,7 @@ ${buildCommand.action('<role-id>')} # AI运用记忆激活角色
|
||||
priority: 'high'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
@ -322,8 +319,8 @@ ${buildCommand.action('<role-id>')} # AI运用记忆激活角色
|
||||
timestamp: new Date().toISOString(),
|
||||
systemVersion: '锦囊串联状态机 v1.0'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RememberCommand;
|
||||
module.exports = RememberCommand
|
||||
|
||||
@ -2,12 +2,12 @@
|
||||
* 锦囊命令导出
|
||||
*/
|
||||
|
||||
const InitCommand = require('./InitCommand');
|
||||
const HelloCommand = require('./HelloCommand');
|
||||
const ActionCommand = require('./ActionCommand');
|
||||
const LearnCommand = require('./LearnCommand');
|
||||
const RecallCommand = require('./RecallCommand');
|
||||
const RememberCommand = require('./RememberCommand');
|
||||
const InitCommand = require('./InitCommand')
|
||||
const HelloCommand = require('./HelloCommand')
|
||||
const ActionCommand = require('./ActionCommand')
|
||||
const LearnCommand = require('./LearnCommand')
|
||||
const RecallCommand = require('./RecallCommand')
|
||||
const RememberCommand = require('./RememberCommand')
|
||||
|
||||
module.exports = {
|
||||
InitCommand,
|
||||
@ -16,4 +16,4 @@ module.exports = {
|
||||
LearnCommand,
|
||||
RecallCommand,
|
||||
RememberCommand
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user