feat: 更新命令名称为dpml-prompt,保持PromptX品牌名称
This commit is contained in:
@ -3,15 +3,15 @@
|
||||
* 所有锦囊命令都需要继承此类
|
||||
*/
|
||||
class BasePouchCommand {
|
||||
constructor() {
|
||||
constructor () {
|
||||
this.context = {
|
||||
currentPouch: '',
|
||||
history: [],
|
||||
userProfile: {},
|
||||
sessionData: {},
|
||||
domainContext: {}
|
||||
};
|
||||
this.outputFormat = 'human';
|
||||
}
|
||||
this.outputFormat = 'human'
|
||||
}
|
||||
|
||||
/**
|
||||
@ -19,36 +19,36 @@ class BasePouchCommand {
|
||||
* @param {Array} args - 命令参数
|
||||
* @returns {Promise<PouchOutput>} 锦囊输出
|
||||
*/
|
||||
async execute(args = []) {
|
||||
const purpose = this.getPurpose();
|
||||
const content = await this.getContent(args);
|
||||
const pateoas = await this.getPATEOAS(args);
|
||||
|
||||
return this.formatOutput(purpose, content, pateoas);
|
||||
async execute (args = []) {
|
||||
const purpose = this.getPurpose()
|
||||
const content = await this.getContent(args)
|
||||
const pateoas = await this.getPATEOAS(args)
|
||||
|
||||
return this.formatOutput(purpose, content, pateoas)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态上下文
|
||||
* @param {StateContext} context - 状态上下文
|
||||
*/
|
||||
setContext(context) {
|
||||
this.context = { ...this.context, ...context };
|
||||
setContext (context) {
|
||||
this.context = { ...this.context, ...context }
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置输出格式
|
||||
* @param {'human'|'json'} format - 输出格式
|
||||
*/
|
||||
setOutputFormat(format) {
|
||||
this.outputFormat = format;
|
||||
setOutputFormat (format) {
|
||||
this.outputFormat = format
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取锦囊目的说明(子类必须实现)
|
||||
* @returns {string} 目的说明
|
||||
*/
|
||||
getPurpose() {
|
||||
throw new Error('子类必须实现 getPurpose 方法');
|
||||
getPurpose () {
|
||||
throw new Error('子类必须实现 getPurpose 方法')
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,8 +56,8 @@ class BasePouchCommand {
|
||||
* @param {Array} args - 命令参数
|
||||
* @returns {Promise<string>} 锦囊内容
|
||||
*/
|
||||
async getContent(args) {
|
||||
throw new Error('子类必须实现 getContent 方法');
|
||||
async getContent (args) {
|
||||
throw new Error('子类必须实现 getContent 方法')
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,8 +65,8 @@ class BasePouchCommand {
|
||||
* @param {Array} args - 命令参数
|
||||
* @returns {PATEOASNavigation} PATEOAS导航
|
||||
*/
|
||||
getPATEOAS(args) {
|
||||
throw new Error('子类必须实现 getPATEOAS 方法');
|
||||
getPATEOAS (args) {
|
||||
throw new Error('子类必须实现 getPATEOAS 方法')
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,27 +76,27 @@ class BasePouchCommand {
|
||||
* @param {PATEOASNavigation} pateoas - PATEOAS导航
|
||||
* @returns {PouchOutput} 格式化的输出
|
||||
*/
|
||||
formatOutput(purpose, content, pateoas) {
|
||||
formatOutput (purpose, content, pateoas) {
|
||||
const output = {
|
||||
purpose,
|
||||
content,
|
||||
pateoas,
|
||||
context: this.context,
|
||||
format: this.outputFormat
|
||||
};
|
||||
}
|
||||
|
||||
if (this.outputFormat === 'json') {
|
||||
return output;
|
||||
return output
|
||||
}
|
||||
|
||||
// 人类可读格式
|
||||
return {
|
||||
...output,
|
||||
toString() {
|
||||
const divider = '='.repeat(60);
|
||||
toString () {
|
||||
const divider = '='.repeat(60)
|
||||
const nextSteps = (pateoas.nextActions || [])
|
||||
.map(action => ` - ${action.name}: ${action.description}\n 命令: ${action.command}`)
|
||||
.join('\n');
|
||||
.join('\n')
|
||||
|
||||
return `
|
||||
${divider}
|
||||
@ -111,10 +111,10 @@ ${nextSteps}
|
||||
|
||||
📍 当前状态:${pateoas.currentState}
|
||||
${divider}
|
||||
`;
|
||||
`
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BasePouchCommand;
|
||||
module.exports = BasePouchCommand
|
||||
|
||||
@ -1,24 +1,24 @@
|
||||
const PouchStateMachine = require('./state/PouchStateMachine');
|
||||
const PouchRegistry = require('./PouchRegistry');
|
||||
const commands = require('./commands');
|
||||
const PouchStateMachine = require('./state/PouchStateMachine')
|
||||
const PouchRegistry = require('./PouchRegistry')
|
||||
const commands = require('./commands')
|
||||
|
||||
/**
|
||||
* 锦囊CLI主入口
|
||||
* 提供命令行接口和统一的执行入口
|
||||
*/
|
||||
class PouchCLI {
|
||||
constructor() {
|
||||
this.stateMachine = new PouchStateMachine();
|
||||
this.registry = new PouchRegistry();
|
||||
this.initialized = false;
|
||||
constructor () {
|
||||
this.stateMachine = new PouchStateMachine()
|
||||
this.registry = new PouchRegistry()
|
||||
this.initialized = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化CLI
|
||||
*/
|
||||
async initialize() {
|
||||
async initialize () {
|
||||
if (this.initialized) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// 批量注册所有命令
|
||||
@ -29,18 +29,18 @@ class PouchCLI {
|
||||
learn: commands.LearnCommand,
|
||||
recall: commands.RecallCommand,
|
||||
remember: commands.RememberCommand
|
||||
});
|
||||
})
|
||||
|
||||
// 将命令注册到状态机
|
||||
for (const name of this.registry.list()) {
|
||||
const command = this.registry.get(name);
|
||||
this.stateMachine.registerCommand(name, command);
|
||||
const command = this.registry.get(name)
|
||||
this.stateMachine.registerCommand(name, command)
|
||||
}
|
||||
|
||||
// 加载历史状态
|
||||
await this.stateMachine.loadState();
|
||||
await this.stateMachine.loadState()
|
||||
|
||||
this.initialized = true;
|
||||
this.initialized = true
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,32 +49,32 @@ class PouchCLI {
|
||||
* @param {Array} args - 命令参数
|
||||
* @returns {Promise<PouchOutput>} 执行结果
|
||||
*/
|
||||
async execute(commandName, args = []) {
|
||||
async execute (commandName, args = []) {
|
||||
// 确保已初始化
|
||||
if (!this.initialized) {
|
||||
await this.initialize();
|
||||
await this.initialize()
|
||||
}
|
||||
|
||||
// 验证命令是否存在
|
||||
if (!this.registry.validate(commandName)) {
|
||||
throw new Error(`未知命令: ${commandName}\n使用 'npx promptx help' 查看可用命令`);
|
||||
throw new Error(`未知命令: ${commandName}\n使用 'npx promptx help' 查看可用命令`)
|
||||
}
|
||||
|
||||
try {
|
||||
// 通过状态机执行命令
|
||||
const result = await this.stateMachine.transition(commandName, args);
|
||||
|
||||
const result = await this.stateMachine.transition(commandName, args)
|
||||
|
||||
// 如果结果有 toString 方法,打印人类可读格式
|
||||
if (result && result.toString && typeof result.toString === 'function') {
|
||||
console.log(result.toString());
|
||||
console.log(result.toString())
|
||||
} else {
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
console.log(JSON.stringify(result, null, 2))
|
||||
}
|
||||
|
||||
return result;
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error(`执行命令出错: ${error.message}`);
|
||||
throw error;
|
||||
console.error(`执行命令出错: ${error.message}`)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,10 +82,10 @@ class PouchCLI {
|
||||
* 获取帮助信息
|
||||
* @returns {string} 帮助文本
|
||||
*/
|
||||
getHelp() {
|
||||
const commands = this.registry.getCommandDetails();
|
||||
const currentState = this.stateMachine.getCurrentState();
|
||||
const availableTransitions = this.stateMachine.getAvailableTransitions();
|
||||
getHelp () {
|
||||
const commands = this.registry.getCommandDetails()
|
||||
const currentState = this.stateMachine.getCurrentState()
|
||||
const availableTransitions = this.stateMachine.getAvailableTransitions()
|
||||
|
||||
let help = `
|
||||
🎯 PromptX 锦囊系统帮助
|
||||
@ -95,10 +95,10 @@ class PouchCLI {
|
||||
可用转换: ${availableTransitions.join(', ')}
|
||||
|
||||
📋 可用命令:
|
||||
`;
|
||||
`
|
||||
|
||||
for (const cmd of commands) {
|
||||
help += `\n ${cmd.name.padEnd(12)} - ${cmd.purpose}`;
|
||||
help += `\n ${cmd.name.padEnd(12)} - ${cmd.purpose}`
|
||||
}
|
||||
|
||||
help += `
|
||||
@ -115,23 +115,23 @@ class PouchCLI {
|
||||
按照提示即可完成完整的工作流程。
|
||||
|
||||
📚 更多信息请访问: https://github.com/yourusername/promptx
|
||||
`;
|
||||
`
|
||||
|
||||
return help;
|
||||
return help
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前状态信息
|
||||
* @returns {StateContext} 状态上下文
|
||||
*/
|
||||
getStatus() {
|
||||
getStatus () {
|
||||
return {
|
||||
currentState: this.stateMachine.getCurrentState(),
|
||||
availableCommands: this.registry.list(),
|
||||
availableTransitions: this.stateMachine.getAvailableTransitions(),
|
||||
context: this.stateMachine.context,
|
||||
initialized: this.initialized
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,62 +139,62 @@ class PouchCLI {
|
||||
* @param {string} input - 用户输入
|
||||
* @returns {Object} 解析结果
|
||||
*/
|
||||
parseCommand(input) {
|
||||
const parts = input.trim().split(/\s+/);
|
||||
const command = parts[0];
|
||||
const args = parts.slice(1);
|
||||
parseCommand (input) {
|
||||
const parts = input.trim().split(/\s+/)
|
||||
const command = parts[0]
|
||||
const args = parts.slice(1)
|
||||
|
||||
return {
|
||||
command: command,
|
||||
args: args
|
||||
};
|
||||
command,
|
||||
args
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行交互式CLI
|
||||
*/
|
||||
async runInteractive() {
|
||||
console.log('🎯 欢迎使用 PromptX 锦囊系统!');
|
||||
console.log('输入 "help" 查看帮助,"exit" 退出\n');
|
||||
async runInteractive () {
|
||||
console.log('🎯 欢迎使用 PromptX 锦囊系统!')
|
||||
console.log('输入 "help" 查看帮助,"exit" 退出\n')
|
||||
|
||||
const readline = require('readline');
|
||||
const readline = require('readline')
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
prompt: 'promptx> '
|
||||
});
|
||||
})
|
||||
|
||||
rl.prompt();
|
||||
rl.prompt()
|
||||
|
||||
rl.on('line', async (line) => {
|
||||
const input = line.trim();
|
||||
|
||||
const input = line.trim()
|
||||
|
||||
if (input === 'exit' || input === 'quit') {
|
||||
console.log('再见!');
|
||||
rl.close();
|
||||
return;
|
||||
console.log('再见!')
|
||||
rl.close()
|
||||
return
|
||||
}
|
||||
|
||||
if (input === 'help') {
|
||||
console.log(this.getHelp());
|
||||
console.log(this.getHelp())
|
||||
} else if (input === 'status') {
|
||||
console.log(JSON.stringify(this.getStatus(), null, 2));
|
||||
console.log(JSON.stringify(this.getStatus(), null, 2))
|
||||
} else if (input) {
|
||||
const { command, args } = this.parseCommand(input);
|
||||
const { command, args } = this.parseCommand(input)
|
||||
try {
|
||||
await this.execute(command, args);
|
||||
await this.execute(command, args)
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
console.error(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
rl.prompt();
|
||||
});
|
||||
rl.prompt()
|
||||
})
|
||||
|
||||
rl.on('close', () => {
|
||||
process.exit(0);
|
||||
});
|
||||
process.exit(0)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PouchCLI;
|
||||
module.exports = PouchCLI
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
* 负责管理和注册所有锦囊命令
|
||||
*/
|
||||
class PouchRegistry {
|
||||
constructor() {
|
||||
this.commands = new Map();
|
||||
constructor () {
|
||||
this.commands = new Map()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -12,16 +12,16 @@ class PouchRegistry {
|
||||
* @param {string} name - 命令名称
|
||||
* @param {BasePouchCommand} command - 命令实例
|
||||
*/
|
||||
register(name, command) {
|
||||
register (name, command) {
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('命令名称必须是非空字符串');
|
||||
throw new Error('命令名称必须是非空字符串')
|
||||
}
|
||||
|
||||
if (!command || typeof command.execute !== 'function') {
|
||||
throw new Error('命令必须实现 execute 方法');
|
||||
throw new Error('命令必须实现 execute 方法')
|
||||
}
|
||||
|
||||
this.commands.set(name.toLowerCase(), command);
|
||||
this.commands.set(name.toLowerCase(), command)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -29,16 +29,16 @@ class PouchRegistry {
|
||||
* @param {string} name - 命令名称
|
||||
* @returns {BasePouchCommand} 命令实例
|
||||
*/
|
||||
get(name) {
|
||||
return this.commands.get(name.toLowerCase());
|
||||
get (name) {
|
||||
return this.commands.get(name.toLowerCase())
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出所有已注册的命令
|
||||
* @returns {string[]} 命令名称列表
|
||||
*/
|
||||
list() {
|
||||
return Array.from(this.commands.keys());
|
||||
list () {
|
||||
return Array.from(this.commands.keys())
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,46 +46,46 @@ class PouchRegistry {
|
||||
* @param {string} name - 命令名称
|
||||
* @returns {boolean} 是否存在
|
||||
*/
|
||||
validate(name) {
|
||||
return this.commands.has(name.toLowerCase());
|
||||
validate (name) {
|
||||
return this.commands.has(name.toLowerCase())
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取命令详情
|
||||
* @returns {Object[]} 命令详情列表
|
||||
*/
|
||||
getCommandDetails() {
|
||||
const details = [];
|
||||
|
||||
getCommandDetails () {
|
||||
const details = []
|
||||
|
||||
for (const [name, command] of this.commands) {
|
||||
details.push({
|
||||
name: name,
|
||||
name,
|
||||
purpose: command.getPurpose ? command.getPurpose() : '未定义',
|
||||
className: command.constructor.name
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return details;
|
||||
|
||||
return details
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空注册器
|
||||
*/
|
||||
clear() {
|
||||
this.commands.clear();
|
||||
clear () {
|
||||
this.commands.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量注册命令
|
||||
* @param {Object} commandMap - 命令映射对象
|
||||
*/
|
||||
registerBatch(commandMap) {
|
||||
registerBatch (commandMap) {
|
||||
for (const [name, CommandClass] of Object.entries(commandMap)) {
|
||||
if (typeof CommandClass === 'function') {
|
||||
this.register(name.toLowerCase(), new CommandClass());
|
||||
this.register(name.toLowerCase(), new CommandClass())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PouchRegistry;
|
||||
module.exports = PouchRegistry
|
||||
|
||||
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,43 +1,43 @@
|
||||
/**
|
||||
* 锦囊框架 (PATEOAS Framework)
|
||||
* Prompt as the Engine of Application State
|
||||
*
|
||||
*
|
||||
* 这是一个革命性的AI-First CLI框架,通过锦囊串联实现AI的状态管理。
|
||||
* 每个锦囊都是独立的专家知识单元,通过PATEOAS导航实现状态转换。
|
||||
*/
|
||||
|
||||
const PouchCLI = require('./PouchCLI');
|
||||
const PouchRegistry = require('./PouchRegistry');
|
||||
const PouchStateMachine = require('./state/PouchStateMachine');
|
||||
const BasePouchCommand = require('./BasePouchCommand');
|
||||
const commands = require('./commands');
|
||||
const PouchCLI = require('./PouchCLI')
|
||||
const PouchRegistry = require('./PouchRegistry')
|
||||
const PouchStateMachine = require('./state/PouchStateMachine')
|
||||
const BasePouchCommand = require('./BasePouchCommand')
|
||||
const commands = require('./commands')
|
||||
|
||||
// 创建全局CLI实例
|
||||
const cli = new PouchCLI();
|
||||
const cli = new PouchCLI()
|
||||
|
||||
module.exports = {
|
||||
// 主要导出
|
||||
PouchCLI,
|
||||
cli,
|
||||
|
||||
|
||||
// 框架组件
|
||||
PouchRegistry,
|
||||
PouchStateMachine,
|
||||
BasePouchCommand,
|
||||
|
||||
|
||||
// 内置命令
|
||||
commands,
|
||||
|
||||
|
||||
// 便捷方法
|
||||
execute: async (commandName, args) => {
|
||||
return await cli.execute(commandName, args);
|
||||
return await cli.execute(commandName, args)
|
||||
},
|
||||
|
||||
|
||||
help: () => {
|
||||
return cli.getHelp();
|
||||
return cli.getHelp()
|
||||
},
|
||||
|
||||
|
||||
status: () => {
|
||||
return cli.getStatus();
|
||||
return cli.getStatus()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -44,4 +44,4 @@
|
||||
|
||||
module.exports = {
|
||||
// 这些是类型定义,JavaScript中不需要导出
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,22 +1,22 @@
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
|
||||
/**
|
||||
* 锦囊状态机管理器
|
||||
* 负责管理锦囊之间的状态转换
|
||||
*/
|
||||
class PouchStateMachine {
|
||||
constructor() {
|
||||
this.currentState = 'initial';
|
||||
this.stateHistory = [];
|
||||
constructor () {
|
||||
this.currentState = 'initial'
|
||||
this.stateHistory = []
|
||||
this.context = {
|
||||
currentPouch: '',
|
||||
history: [],
|
||||
userProfile: {},
|
||||
sessionData: {},
|
||||
domainContext: {}
|
||||
};
|
||||
this.commands = new Map();
|
||||
}
|
||||
this.commands = new Map()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -24,8 +24,8 @@ class PouchStateMachine {
|
||||
* @param {string} name - 命令名称
|
||||
* @param {BasePouchCommand} command - 命令实例
|
||||
*/
|
||||
registerCommand(name, command) {
|
||||
this.commands.set(name, command);
|
||||
registerCommand (name, command) {
|
||||
this.commands.set(name, command)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -34,11 +34,11 @@ class PouchStateMachine {
|
||||
* @param {Array} args - 命令参数
|
||||
* @returns {Promise<PouchOutput>} 执行结果
|
||||
*/
|
||||
async transition(commandName, args = []) {
|
||||
async transition (commandName, args = []) {
|
||||
// 获取命令对应的锦囊
|
||||
const command = this.commands.get(commandName);
|
||||
const command = this.commands.get(commandName)
|
||||
if (!command) {
|
||||
throw new Error(`未找到命令: ${commandName}`);
|
||||
throw new Error(`未找到命令: ${commandName}`)
|
||||
}
|
||||
|
||||
// 记录历史
|
||||
@ -46,128 +46,126 @@ class PouchStateMachine {
|
||||
from: this.currentState,
|
||||
command: commandName,
|
||||
timestamp: new Date().toISOString(),
|
||||
args: args
|
||||
});
|
||||
args
|
||||
})
|
||||
|
||||
// 更新上下文
|
||||
this.context.currentPouch = commandName;
|
||||
this.context.history = this.stateHistory.map(h => h.command || h.to);
|
||||
this.context.currentPouch = commandName
|
||||
this.context.history = this.stateHistory.map(h => h.command || h.to)
|
||||
|
||||
// 设置命令上下文
|
||||
command.setContext(this.context);
|
||||
command.setContext(this.context)
|
||||
|
||||
// 执行命令
|
||||
const result = await command.execute(args);
|
||||
const result = await command.execute(args)
|
||||
|
||||
// 根据PATEOAS导航更新状态
|
||||
if (result && result.pateoas && result.pateoas.currentState) {
|
||||
this.currentState = result.pateoas.currentState;
|
||||
this.currentState = result.pateoas.currentState
|
||||
}
|
||||
|
||||
// 保存状态
|
||||
await this.saveState();
|
||||
await this.saveState()
|
||||
|
||||
return result;
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前状态
|
||||
* @returns {string} 当前状态
|
||||
*/
|
||||
getCurrentState() {
|
||||
return this.currentState;
|
||||
getCurrentState () {
|
||||
return this.currentState
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可用的状态转换
|
||||
* @returns {string[]} 可转换的状态列表
|
||||
*/
|
||||
getAvailableTransitions() {
|
||||
getAvailableTransitions () {
|
||||
const transitions = {
|
||||
'initial': ['init', 'hello'],
|
||||
'initialized': ['hello', 'action', 'learn'],
|
||||
'discovering': ['action', 'learn', 'init'],
|
||||
'activated': ['learn', 'recall', 'hello'],
|
||||
'learned': ['action', 'recall', 'hello'],
|
||||
'recalled': ['action', 'learn', 'remember']
|
||||
};
|
||||
initial: ['init', 'hello'],
|
||||
initialized: ['hello', 'action', 'learn'],
|
||||
discovering: ['action', 'learn', 'init'],
|
||||
activated: ['learn', 'recall', 'hello'],
|
||||
learned: ['action', 'recall', 'hello'],
|
||||
recalled: ['action', 'learn', 'remember']
|
||||
}
|
||||
|
||||
// 根据当前状态的前缀匹配
|
||||
for (const [statePrefix, availableStates] of Object.entries(transitions)) {
|
||||
if (this.currentState.startsWith(statePrefix)) {
|
||||
return availableStates;
|
||||
return availableStates
|
||||
}
|
||||
}
|
||||
|
||||
// 默认可转换状态
|
||||
return ['hello', 'init'];
|
||||
return ['hello', 'init']
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 保存状态到文件
|
||||
*/
|
||||
async saveState() {
|
||||
const promptxDir = path.join(process.cwd(), '.promptx');
|
||||
const configPath = path.join(promptxDir, 'pouch.json');
|
||||
|
||||
async saveState () {
|
||||
const promptxDir = path.join(process.cwd(), '.promptx')
|
||||
const configPath = path.join(promptxDir, 'pouch.json')
|
||||
|
||||
try {
|
||||
// 确保 .promptx 目录存在
|
||||
await fs.ensureDir(promptxDir);
|
||||
|
||||
let config = {};
|
||||
await fs.ensureDir(promptxDir)
|
||||
|
||||
let config = {}
|
||||
if (await fs.pathExists(configPath)) {
|
||||
config = await fs.readJson(configPath);
|
||||
config = await fs.readJson(configPath)
|
||||
}
|
||||
|
||||
config.currentState = this.currentState;
|
||||
config.stateHistory = this.stateHistory.slice(-50); // 只保留最近50条记录
|
||||
config.lastUpdated = new Date().toISOString();
|
||||
config.currentState = this.currentState
|
||||
config.stateHistory = this.stateHistory.slice(-50) // 只保留最近50条记录
|
||||
config.lastUpdated = new Date().toISOString()
|
||||
|
||||
await fs.writeJson(configPath, config, { spaces: 2 });
|
||||
await fs.writeJson(configPath, config, { spaces: 2 })
|
||||
} catch (error) {
|
||||
console.error('保存状态失败:', error);
|
||||
console.error('保存状态失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件加载状态
|
||||
*/
|
||||
async loadState() {
|
||||
const configPath = path.join(process.cwd(), '.promptx', 'pouch.json');
|
||||
|
||||
async loadState () {
|
||||
const configPath = path.join(process.cwd(), '.promptx', 'pouch.json')
|
||||
|
||||
try {
|
||||
if (await fs.pathExists(configPath)) {
|
||||
const config = await fs.readJson(configPath);
|
||||
|
||||
const config = await fs.readJson(configPath)
|
||||
|
||||
if (config.currentState) {
|
||||
this.currentState = config.currentState;
|
||||
this.currentState = config.currentState
|
||||
}
|
||||
|
||||
|
||||
if (config.stateHistory) {
|
||||
this.stateHistory = config.stateHistory;
|
||||
this.stateHistory = config.stateHistory
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载状态失败:', error);
|
||||
console.error('加载状态失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置状态机
|
||||
*/
|
||||
reset() {
|
||||
this.currentState = 'initial';
|
||||
this.stateHistory = [];
|
||||
reset () {
|
||||
this.currentState = 'initial'
|
||||
this.stateHistory = []
|
||||
this.context = {
|
||||
currentPouch: '',
|
||||
history: [],
|
||||
userProfile: {},
|
||||
sessionData: {},
|
||||
domainContext: {}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PouchStateMachine;
|
||||
module.exports = PouchStateMachine
|
||||
|
||||
Reference in New Issue
Block a user