sensai
Version:
Because even AI needs a master
160 lines (159 loc) • 6.71 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, /**
* Add extension hooks to transpile file everytime it is imported.
*/ "default", {
enumerable: true,
get: function() {
return _default;
}
});
const _nodemodule = /*#__PURE__*/ _interop_require_default(require("node:module"));
const _nodepath = require("node:path");
const _nodefs = require("node:fs");
const _core = require("@swc/core");
const _options = /*#__PURE__*/ _interop_require_wildcard(require("./options"));
const _markdown = require("./markdown");
const _enums = require("./enums");
const _constants = require("../../constants");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
const _default = (// compiler is routes-context aware
routes, options)=>{
const { cwdPath, apiDir } = options;
const aliases = (0, _options.getCompilerOptions)(cwdPath);
const apiPath = (0, _nodepath.join)(cwdPath, apiDir);
for (const extension of Object.values(_enums.JSExtensionE)){
// @ts-ignore
_nodemodule.default._extensions[extension] = typescriptCompiler(aliases, apiPath);
}
// @ts-ignore
_nodemodule.default._extensions[_enums.MDExtensionE.MARKDOWN] = markdownCompiler(routes, apiPath, aliases);
};
/**
* Creates a module extension to compile file into JavaScript code.
* This method is mainly used to transpile TypeScript files but is also
* used for JavaScript files to insure consistency.
*/ const typescriptCompiler = (aliases, apiPath)=>{
return decorator((filename, content)=>{
return getJsCode(content, (0, _options.default)(filename, aliases));
});
};
/**
* Creates a module extension to compile supported markdown files into JavaScript code.
*/ const markdownCompiler = (routes, apiPath, aliases)=>{
return decorator((filename, content)=>{
if (filename.substring(0, apiPath.length) === apiPath) {
const [prefix] = (0, _nodepath.basename)(filename, _enums.MDExtensionE.MARKDOWN).split(".");
switch(prefix){
case _constants.FILE_TYPE.PROMPT:
{
const { dir, name } = (0, _nodepath.parse)(filename);
return getJsCode((0, _markdown.getPromptTypescript)(content, routes.getTools(dir).map((tool)=>({
...tool,
path: (0, _nodepath.join)((0, _nodepath.dirname)(apiPath), tool.path)
}))), (0, _options.default)((0, _nodepath.join)(dir, name + ".ts"), aliases));
}
case _constants.FILE_TYPE.ORCHESTRATOR:
{
const { dir, name } = (0, _nodepath.parse)(filename);
const rootPath = (0, _nodepath.dirname)(apiPath);
const tools = routes.getTools(dir).map((tool)=>({
...tool,
path: (0, _nodepath.join)(rootPath, tool.path)
}));
const agents = Object.entries(routes.getAgents(dir.substring(rootPath.length))).map(([name, path])=>{
return {
name,
path: (0, _nodepath.join)(rootPath, path)
};
});
return getJsCode((0, _markdown.getPromptTypescript)(content, [
...tools,
...agents
]), (0, _options.default)((0, _nodepath.join)(dir, name + ".ts"), aliases));
}
case _constants.FILE_TYPE.MOCK:
case _constants.FILE_TYPE.ROUTE:
{
const { dir, name } = (0, _nodepath.parse)(filename);
return getJsCode((0, _markdown.getMarkdownTypescript)(content), (0, _options.default)((0, _nodepath.join)(dir, name + ".ts"), aliases));
}
}
}
// TODO or should we return content?
throw new Error("temporary error");
});
};
/**
* This is a native module extension decorator.
* @notes Native extensions need to be synchronous.
*/ const decorator = (cb)=>{
// TODO based on the extension and type, behavior might change
return (mod, filename)=>{
// TODO prevent files in node_modules and outside of project
const content = (0, _nodefs.readFileSync)(filename, "utf-8");
try {
mod._compile(filename.includes(`${_nodepath.sep}node_modules${_nodepath.sep}`) ? content : cb(filename, content), filename);
} catch (error) {
// prevent exit 1
throw error;
}
};
};
/**
* Transform file content into JavaScript code.
*/ const getJsCode = (content, options)=>{
const { code } = (0, _core.transformSync)(content, options);
if (//avoid circular dependencies when linking sensai locally
options.filename === require.resolve("sensai/dist/src/lib/guard")) {
return content;
}
return `const { default: guard } = require('sensai/dist/src/lib/guard');(function(exports, guard) {${code}})(exports, guard);`;
};