@genkit-ai/dotprompt
Version:
Genkit AI framework `.prompt` file format and management library.
134 lines • 4.29 kB
JavaScript
import {
__spreadProps,
__spreadValues
} from "./chunk-DFMI36TU.mjs";
import Handlebars from "handlebars";
const Promptbars = global["dotprompt.handlebars"] || Handlebars.create();
global["dotprompt.handlebars"] = Promptbars;
function jsonHelper(serializable, options) {
return new Promptbars.SafeString(
JSON.stringify(serializable, null, options.hash.indent || 0)
);
}
Promptbars.registerHelper("json", jsonHelper);
function roleHelper(role) {
return new Promptbars.SafeString(`<<<dotprompt:role:${role}>>>`);
}
Promptbars.registerHelper("role", roleHelper);
function historyHelper() {
return new Promptbars.SafeString("<<<dotprompt:history>>>");
}
Promptbars.registerHelper("history", historyHelper);
function sectionHelper(name) {
return new Promptbars.SafeString(`<<<dotprompt:section ${name}>>>`);
}
Promptbars.registerHelper("section", sectionHelper);
function mediaHelper(options) {
return new Promptbars.SafeString(
`<<<dotprompt:media:url ${options.hash.url}${options.hash.contentType ? ` ${options.hash.contentType}` : ""}>>>`
);
}
Promptbars.registerHelper("media", mediaHelper);
const ROLE_REGEX = /(<<<dotprompt:(?:role:[a-z]+|history))>>>/g;
function toMessages(renderedString, options) {
var _a;
let currentMessage = {
role: "user",
source: ""
};
const messageSources = [currentMessage];
for (const piece of renderedString.split(ROLE_REGEX).filter((s) => s.trim() !== "")) {
if (piece.startsWith("<<<dotprompt:role:")) {
const role = piece.substring(18);
if (currentMessage.source.trim()) {
currentMessage = { role, source: "" };
messageSources.push(currentMessage);
} else {
currentMessage.role = role;
}
} else if (piece.startsWith("<<<dotprompt:history")) {
messageSources.push(
...((_a = options == null ? void 0 : options.history) == null ? void 0 : _a.map((m) => {
return __spreadProps(__spreadValues({}, m), {
metadata: __spreadProps(__spreadValues({}, m.metadata || {}), { purpose: "history" })
});
})) || []
);
currentMessage = { role: "model", source: "" };
messageSources.push(currentMessage);
} else {
currentMessage.source += piece;
}
}
const messages = messageSources.filter((ms) => ms.content || ms.source).map((m) => {
const out = {
role: m.role,
content: m.content || toParts(m.source)
};
if (m.metadata)
out.metadata = m.metadata;
return out;
});
if (!(options == null ? void 0 : options.history) || messages.find((m) => {
var _a2;
return ((_a2 = m.metadata) == null ? void 0 : _a2.purpose) === "history";
}))
return messages;
return [
...messages.slice(0, -1),
...options.history,
messages.at(-1)
];
}
const PART_REGEX = /(<<<dotprompt:(?:media:url|section).*?)>>>/g;
function toParts(source) {
const parts = [];
const pieces = source.split(PART_REGEX).filter((s) => s.trim() !== "");
for (let i = 0; i < pieces.length; i++) {
const piece = pieces[i];
if (piece.startsWith("<<<dotprompt:media:")) {
const [_, url, contentType] = piece.split(" ");
const part = { media: { url } };
if (contentType)
part.media.contentType = contentType;
parts.push(part);
} else if (piece.startsWith("<<<dotprompt:section")) {
const [_, sectionType] = piece.split(" ");
parts.push({ metadata: { purpose: sectionType, pending: true } });
} else {
parts.push({ text: piece });
}
}
return parts;
}
function compile(source, metadata) {
const renderString = Promptbars.compile(source, {
knownHelpers: {
json: true,
section: true,
media: true,
role: true,
history: true
}
});
return (input, options) => {
const renderedString = renderString(input, {
data: {
metadata: { prompt: metadata, context: (options == null ? void 0 : options.context) || null }
}
});
return toMessages(renderedString, options);
};
}
function defineHelper(name, fn) {
Promptbars.registerHelper(name, fn);
}
function definePartial(name, source) {
Promptbars.registerPartial(name, source);
}
export {
compile,
defineHelper,
definePartial
};
//# sourceMappingURL=template.mjs.map