tinyagent-ts
Version:
Modern TypeScript framework for building AI agents with pluggable tools and ReAct reasoning
115 lines • 5.02 kB
JavaScript
;
// prompt_engine.ts (cleaned — new branch wins)
// -----------------------------------------------------
// Lightweight prompt‑template engine with file‑based loading support.
// • Ships with default templates (markdown files + hard‑coded greeting)
// • Lets callers override / extend in code or via markdown files & folders
// • Designed for QA‑agent workflows, no external dependencies beyond Node fs/path
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PromptEngine = exports.defaultTemplates = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
// -----------------------------------------------------
// Helper: load every .md file in a directory as a template
// -----------------------------------------------------
function compileTemplate(content) {
return (data = {}) => content.replace(/{{\s*(\w+)\s*}}/g, (_, k) => k in data ? String(data[k]) : "");
}
function loadTemplatesFromDir(dir) {
const templates = {};
if (!fs_1.default.existsSync(dir))
return templates;
for (const fileName of fs_1.default.readdirSync(dir)) {
if (!fileName.endsWith(".md"))
continue;
const key = path_1.default.basename(fileName, ".md");
const content = fs_1.default.readFileSync(path_1.default.join(dir, fileName), "utf-8");
templates[key] = compileTemplate(content);
}
return templates;
}
// Core system prompt directory (relative to this file)
const systemPromptDir = path_1.default.join(__dirname, "core", "prompts", "system");
// -----------------------------------------------------
// Built‑in template registry (markdown + hardcoded)
// -----------------------------------------------------
exports.defaultTemplates = {
...loadTemplatesFromDir(systemPromptDir),
greeting: ({ user = "friend" } = {}) => `👋 Hey ${user}, how can I help?`,
};
// -----------------------------------------------------
// PromptEngine class
// -----------------------------------------------------
class PromptEngine {
constructor(overrides = {}, fileOverrides = {}) {
// User overrides win, but defaultTemplates stay untouched
this.templates = { ...exports.defaultTemplates };
// Apply any overrides that are defined
Object.entries(overrides).forEach(([key, value]) => {
if (value) {
this.templates[key] = value;
}
});
this.applyFileOverrides(fileOverrides);
}
/** Render a template by key */
render(name, data) {
const tpl = this.templates[name];
if (!tpl)
throw new Error(`Prompt template “${name}” not found`);
return tpl(data);
}
/** Register brand‑new template (fails if key exists) */
register(name, template) {
if (name in this.templates)
throw new Error("already exists — use overwrite()");
this.templates[name] = template;
}
/** Overwrite existing or create new template unconditionally */
overwrite(name, template) {
this.templates[name] = template;
}
// -------------------------------------------------
// File helpers (Markdown‑driven workflows)
// -------------------------------------------------
/** Register template from a markdown file (fails if key exists) */
registerFromFile(name, filePath) {
const content = fs_1.default.readFileSync(filePath, "utf-8");
this.register(name, compileTemplate(content));
}
/** Load every .md file in dir as new templates (fails on duplicates) */
loadDir(dir) {
const loaded = loadTemplatesFromDir(dir);
for (const [k, v] of Object.entries(loaded)) {
if (k in this.templates)
throw new Error(`Template ${k} already exists — use overwrite()`);
this.templates[k] = v;
}
}
/** Overwrite (or create) template from file */
overwriteFromFile(name, filePath) {
const content = fs_1.default.readFileSync(filePath, "utf-8");
this.overwrite(name, compileTemplate(content));
}
/** Apply multiple file overrides at once */
applyFileOverrides(map) {
for (const [name, file] of Object.entries(map)) {
const content = fs_1.default.readFileSync(file, "utf-8");
this.overwrite(name, compileTemplate(content));
}
}
}
exports.PromptEngine = PromptEngine;
// -----------------------------------------------------
// Usage example (delete or wrap in tests)
// -----------------------------------------------------
/*
const engine = new PromptEngine();
console.log(engine.render("greeting", { user: "Fabian" }));
engine.registerFromFile("intro", path.join(__dirname, "prompts", "intro.md"));
console.log(engine.render("intro"));
*/
//# sourceMappingURL=promptEngine.js.map