Files
PromptX/src/constants.js

229 lines
5.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

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

/**
* PromptX 系统常量配置
* 统一管理命令格式、路径等配置信息
*/
const PromptXConfig = require('./lib/utils/promptxConfig')
// 缓存配置实例和命令前缀
let _config = null
let _cachedPrefix = null
/**
* 获取配置实例
*/
function getConfig() {
if (!_config) {
_config = new PromptXConfig()
}
return _config
}
/**
* 动态检测命令前缀
* 优先级:环境变量 > npm环境变量检测 > 配置文件 > 默认值
*/
function detectCommandPrefix() {
// 在 init 过程中,优先使用实时检测而不是缓存
const isInitProcess = process.argv.includes('init')
// 如果不是 init 过程且有缓存,返回缓存结果
if (!isInitProcess && _cachedPrefix) {
return _cachedPrefix
}
// 1. 环境变量优先(用于测试和自定义)
if (process.env.DPML_COMMAND_PREFIX) {
_cachedPrefix = process.env.DPML_COMMAND_PREFIX
return _cachedPrefix
}
// 2. npm环境变量检测实时检测优先级提高
if (process.env.npm_execpath?.includes('npx') ||
process.env.npm_config_user_agent?.includes('npx')) {
_cachedPrefix = 'npx -y dpml-prompt'
return _cachedPrefix
}
// 3. 如果不是 init 过程,尝试读取配置文件
if (!isInitProcess) {
try {
const config = getConfig()
const configPath = config.getPath('command-prefix')
const fs = require('fs')
if (fs.existsSync(configPath)) {
const savedPrefix = fs.readFileSync(configPath, 'utf8').trim()
if (savedPrefix) {
_cachedPrefix = savedPrefix
return _cachedPrefix
}
}
} catch (error) {
// 忽略读取错误,继续下一步检测
}
}
// 4. 默认值
_cachedPrefix = 'npx -y dpml-prompt'
return _cachedPrefix
}
/**
* 智能推测用户使用的命令前缀
* 从 process.argv 中提取 init 之前的所有部分作为命令前缀
*/
function reconstructCommandPrefix() {
try {
// 优先检查环境变量,因为通过 npx 执行时环境变量是最可靠的
if (process.env.npm_execpath?.includes('npx') ||
process.env.npm_config_user_agent?.includes('npx')) {
return 'npx -y dpml-prompt'
}
// 从 process.argv 中找到 init 命令的位置
const initIndex = process.argv.findIndex(arg => arg === 'init')
if (initIndex > 0) {
// 提取 init 之前的所有参数,跳过 node 可执行文件路径
const prefixParts = process.argv.slice(1, initIndex)
if (prefixParts.length > 0) {
// 检查脚本路径是否包含典型的开发模式特征
const firstPart = prefixParts[0]
if (firstPart.includes('promptx.js') ||
firstPart.includes('cli.js') ||
firstPart.includes('bin/') ||
firstPart.includes('src/bin/')) {
// 开发模式,使用包名
return 'dpml-prompt'
}
// 直接使用检测到的前缀
return prefixParts.join(' ')
}
}
// 如果找不到 init 或解析失败,使用环境变量判断
if (process.env.npm_execpath && process.env.npm_execpath.includes('npx')) {
return 'npx -y dpml-prompt'
}
return 'dpml-prompt'
} catch (error) {
// 解析失败时的回退逻辑
return 'dpml-prompt'
}
}
/**
* 保存命令前缀到配置文件
* 在init命令中调用
*/
async function saveCommandPrefix() {
try {
// 先清除缓存,确保使用最新的检测结果
_cachedPrefix = null
// 直接使用检测到的前缀,不再通过 reconstructCommandPrefix
const actualPrefix = detectCommandPrefix()
const config = getConfig()
await config.writeText('command-prefix', actualPrefix)
// 保存后更新缓存
_cachedPrefix = actualPrefix
return actualPrefix
} catch (error) {
console.warn('保存命令前缀失败:', error.message)
return null
}
}
// 动态生成命令常量(函数式)
function getCommands() {
const prefix = detectCommandPrefix()
return {
INIT: `${prefix} init`,
HELLO: `${prefix} hello`,
ACTION: `${prefix} action`,
LEARN: `${prefix} learn`,
RECALL: `${prefix} recall`,
REMEMBER: `${prefix} remember`,
HELP: `${prefix} help`
}
}
// 带参数的命令构建函数
function getBuildCommand() {
const prefix = detectCommandPrefix()
return {
action: (roleId) => `${prefix} action ${roleId}`,
learn: (resource) => `${prefix} learn ${resource}`,
recall: (query = '') => `${prefix} recall${query ? ' ' + query : ''}`,
remember: (content = '<content>') => `${prefix} remember${content !== '<content>' ? ' "' + content + '"' : ' <content>'}`
}
}
// 为了向后兼容,保留原有的静态导出方式
// 但实际上是动态计算的
const COMMANDS = new Proxy({}, {
get(target, prop) {
return getCommands()[prop]
}
})
const buildCommand = new Proxy({}, {
get(target, prop) {
return getBuildCommand()[prop]
}
})
// 系统路径配置(静态)
const PATHS = {
POUCH_DIR: '.promptx',
MEMORY_DIR: '.promptx/memory',
STATE_FILE: '.promptx/pouch.json',
MEMORY_FILE: '.promptx/memory/declarative.md'
}
// 版本信息
const VERSION = '0.0.1'
// 系统状态
const STATES = {
INITIALIZED: 'initialized',
ROLE_DISCOVERY: 'role_discovery',
ACTION_PLAN_GENERATED: 'action_plan_generated',
LEARNED_ROLE: 'learned_role',
MEMORY_SAVED: 'memory_saved',
RECALL_WAITING: 'recall-waiting'
}
/**
* 清除缓存(主要用于测试)
*/
function clearCache() {
_cachedPrefix = null
_config = null
}
// 导出
module.exports = {
// 新的函数式API推荐
getCommands,
getBuildCommand,
detectCommandPrefix,
reconstructCommandPrefix,
saveCommandPrefix,
clearCache,
// 向后兼容的静态API
COMMANDS,
buildCommand,
// 其他静态常量
PATHS,
VERSION,
STATES
}