dpml-prompt
Version:
DPML-powered AI prompt framework - Revolutionary AI-First CLI system based on Deepractice Prompt Markup Language. Build sophisticated AI agents with structured prompts, memory systems, and execution frameworks.
249 lines (217 loc) • 7.64 kB
JavaScript
const path = require('path')
const { ProtocolInfo } = require('./types')
/**
* 资源注册表管理器
* 管理资源协议和ID到路径的映射
*/
class ResourceRegistry {
constructor () {
this.builtinRegistry = new Map()
this.customRegistry = new Map()
this.loadBuiltinRegistry()
}
/**
* 加载内置注册表
*/
loadBuiltinRegistry () {
// PromptX 内置资源协议
const promptProtocol = new ProtocolInfo()
promptProtocol.name = 'prompt'
promptProtocol.description = 'PromptX内置提示词资源协议'
promptProtocol.location = 'prompt://{resource_id}'
promptProtocol.registry = new Map([
['protocols', '@package://prompt/protocol/**/*.md'],
['core', '@package://prompt/core/**/*.md'],
['domain', '@package://prompt/domain/**/*.md'],
['resource', '@package://prompt/resource/**/*.md'],
['bootstrap', '@package://bootstrap.md']
])
this.builtinRegistry.set('prompt', promptProtocol)
// File 协议(标准协议,无需注册表)
const fileProtocol = new ProtocolInfo()
fileProtocol.name = 'file'
fileProtocol.description = '文件系统资源协议'
fileProtocol.location = 'file://{absolute_or_relative_path}'
fileProtocol.params = {
line: 'string - 行范围,如 "1-10"',
encoding: 'string - 文件编码,默认 utf8'
}
this.builtinRegistry.set('file', fileProtocol)
// Memory 协议(项目记忆系统)
const memoryProtocol = new ProtocolInfo()
memoryProtocol.name = 'memory'
memoryProtocol.description = '项目记忆系统协议'
memoryProtocol.location = 'memory://{resource_id}'
memoryProtocol.registry = new Map([
['declarative', '@project://.promptx/memory/declarative.md'],
['procedural', '@project://.promptx/memory/procedural.md'],
['episodic', '@project://.promptx/memory/episodic.md'],
['semantic', '@project://.promptx/memory/semantic.md']
])
this.builtinRegistry.set('memory', memoryProtocol)
// HTTP/HTTPS 协议(标准协议)
const httpProtocol = new ProtocolInfo()
httpProtocol.name = 'http'
httpProtocol.description = 'HTTP网络资源协议'
httpProtocol.location = 'http://{url}'
httpProtocol.params = {
format: 'string - 响应格式,如 json, text',
timeout: 'number - 超时时间(毫秒)',
cache: 'boolean - 是否缓存响应'
}
this.builtinRegistry.set('http', httpProtocol)
this.builtinRegistry.set('https', httpProtocol)
}
/**
* 解析资源ID到具体路径
* @param {string} protocol - 协议名
* @param {string} resourceId - 资源ID
* @returns {string} 解析后的路径
*/
resolve (protocol, resourceId) {
const protocolInfo = this.getProtocolInfo(protocol)
if (!protocolInfo) {
throw new Error(`Unknown protocol: ${protocol}`)
}
// 如果协议有注册表,尝试解析ID
if (protocolInfo.registry && protocolInfo.registry.size > 0) {
const resolvedPath = protocolInfo.registry.get(resourceId)
if (resolvedPath) {
return resolvedPath
}
// 如果在注册表中找不到,但这是一个有注册表的协议,抛出错误
throw new Error(`Resource ID '${resourceId}' not found in ${protocol} protocol registry`)
}
// 对于没有注册表的协议(如file, http),直接返回资源ID作为路径
return resourceId
}
/**
* 注册新的协议或更新现有协议
* @param {string} protocolName - 协议名
* @param {object} protocolDefinition - 协议定义
*/
register (protocolName, protocolDefinition) {
const protocolInfo = new ProtocolInfo()
protocolInfo.name = protocolName
protocolInfo.description = protocolDefinition.description || ''
protocolInfo.location = protocolDefinition.location || ''
protocolInfo.params = protocolDefinition.params || {}
// 设置注册表映射
if (protocolDefinition.registry) {
protocolInfo.registry = new Map()
for (const [id, path] of Object.entries(protocolDefinition.registry)) {
protocolInfo.registry.set(id, path)
}
}
this.customRegistry.set(protocolName, protocolInfo)
}
/**
* 获取协议信息
* @param {string} protocolName - 协议名
* @returns {ProtocolInfo|null} 协议信息
*/
getProtocolInfo (protocolName) {
return this.customRegistry.get(protocolName) ||
this.builtinRegistry.get(protocolName) ||
null
}
/**
* 列出所有可用协议
* @returns {string[]} 协议名列表
*/
listProtocols () {
const protocols = new Set()
for (const protocol of this.builtinRegistry.keys()) {
protocols.add(protocol)
}
for (const protocol of this.customRegistry.keys()) {
protocols.add(protocol)
}
return Array.from(protocols).sort()
}
/**
* 检查协议是否存在
* @param {string} protocolName - 协议名
* @returns {boolean} 是否存在
*/
hasProtocol (protocolName) {
return this.builtinRegistry.has(protocolName) ||
this.customRegistry.has(protocolName)
}
/**
* 获取协议的注册表内容
* @param {string} protocolName - 协议名
* @returns {Map|null} 注册表映射
*/
getProtocolRegistry (protocolName) {
const protocolInfo = this.getProtocolInfo(protocolName)
return protocolInfo ? protocolInfo.registry : null
}
/**
* 列出协议的所有可用资源ID
* @param {string} protocolName - 协议名
* @returns {string[]} 资源ID列表
*/
listProtocolResources (protocolName) {
const registry = this.getProtocolRegistry(protocolName)
return registry ? Array.from(registry.keys()) : []
}
/**
* 展开通配符模式
* @param {string} pattern - 通配符模式
* @returns {string[]} 展开后的路径列表
*/
expandWildcards (pattern) {
// 这里暂时返回原样,实际实现需要结合文件系统
// 在ResourceLocator中会有更详细的实现
return [pattern]
}
/**
* 验证资源引用
* @param {string} protocol - 协议名
* @param {string} resourceId - 资源ID
* @returns {boolean} 是否有效
*/
validateReference (protocol, resourceId) {
if (!this.hasProtocol(protocol)) {
return false
}
const protocolInfo = this.getProtocolInfo(protocol)
// 如果有注册表,检查ID是否存在
if (protocolInfo.registry && protocolInfo.registry.size > 0) {
return protocolInfo.registry.has(resourceId)
}
// 对于没有注册表的协议,只要协议存在就认为有效
return true
}
/**
* 获取所有注册表信息(用于调试)
* @returns {object} 注册表信息
*/
getRegistryInfo () {
const info = {
builtin: {},
custom: {}
}
for (const [name, protocol] of this.builtinRegistry) {
info.builtin[name] = {
description: protocol.description,
location: protocol.location,
params: protocol.params,
registrySize: protocol.registry ? protocol.registry.size : 0,
resources: protocol.registry ? Array.from(protocol.registry.keys()) : []
}
}
for (const [name, protocol] of this.customRegistry) {
info.custom[name] = {
description: protocol.description,
location: protocol.location,
params: protocol.params,
registrySize: protocol.registry ? protocol.registry.size : 0,
resources: protocol.registry ? Array.from(protocol.registry.keys()) : []
}
}
return info
}
}
module.exports = ResourceRegistry