pi-st-ejs
v0.1.0
Published
SillyTavern EJS template engine for pi — ported from ST-Prompt-Template
Readme
pi-st-ejs
SillyTavern EJS template engine for pi. Ported from ST-Prompt-Template — provides the full variable API, worldbook functions, and synchronous EJS template evaluation that SillyTavern worldbooks expect.
Install
npm install pi-st-ejsRequires Node.js >= 22.19.0.
Quick start
import {
objectStore, createVariableState, precacheVariables,
createWorldInfoStore, parseDecorators,
prepareContext, evalTemplate,
} from "pi-st-ejs";
// 1. Create a variable store backed by your runtime state
const state = objectStore(runtimeState);
const vars = createVariableState(state);
precacheVariables(vars);
// 2. Load worldbook entries from ST JSON
const entries = worldbookEntries.map(e => {
const [decorators, cleanContent] = parseDecorators(e.content);
return { ...e, content: cleanContent };
});
const worldInfo = createWorldInfoStore(entries);
// 3. Build the EJS execution context
const ctx = prepareContext(vars, {
messages: chatHistory,
worldInfoStore: worldInfo,
activated: new Set(),
customVars: {},
messageText: lastMessage,
ctxText: fullContext,
renderFn: (content, extraData) =>
evalTemplate(content, { ...ctx, ...extraData }),
});
// 4. Render templates (synchronous)
const result = evalTemplate(templateString, ctx);API
Variable store
| Function | ST equivalent |
|----------|---------------|
| objectStore(root) | Creates a StateStore from a plain object |
| createVariableState(store) | Initializes the variable system |
| precacheVariables(vs) | Merges global + initial + local + cache scopes |
Variable API (EJS context)
| Function | Description |
|----------|-------------|
| getvar(path, opts?) | Read a variable; default scope = cache |
| setvar(path, value, opts?) | Write a variable; supports nx (no-overwrite) |
| incvar(path, amount?, opts?) | Increment a numeric variable |
| decvar(path, amount?, opts?) | Decrement a numeric variable |
| delvar(path, opts?) | Delete a variable |
| insvar(path, value, position?) | Insert into an array variable |
| variables | Accessor for the merged cache tree |
Worldbook API
| Function | Description |
|----------|-------------|
| getwi(title, data?) | Get entry content by title; data passed as extra EJS context |
| activewi(title) | Check if entry is activated |
| getEnabledWorldInfoEntries() | List all enabled entries |
| parseDecorators(content) | Strip @@preprocessing / @@activate / @@dont_activate decorators |
| createWorldInfoStore(entries) | Build a worldbook store from entry array |
Chat API (EJS context)
| Function | Description |
|----------|-------------|
| getChatMessages() | All messages as string[] |
| getChatMessages(n) | Last n messages |
| getChatMessages(start, end) | Slice by index (negative = from end) |
| getChatMessages(start, end, role) | Slice filtered by role |
| getChatMessage(idx) | Single message; negative index from end |
| matchChatMessages(pattern, and?) | Regex or substring match |
EJS context extras
| Name | Description |
|------|-------------|
| _ | Lodash shim: _.get, _.set, _.has, _.merge, _.cloneDeep, _.isArray, _.toArray, _.concat |
| define(name, value, merge?) | Define a persistent variable (SharedDefines) |
| getAllVariables() | Returns { stat_data: cacheVars } |
| getVariables(opts?) | Same as getAllVariables |
| findVariables(query) | Returns [] (pi has no per-message variable tracking) |
| messageText | Current message text |
| ctxText | Full context text |
Template evaluation
| Function | Description |
|----------|-------------|
| evalTemplate(template, ctx) | Synchronous EJS render |
| hasEjsSyntax(text) | Check if string contains EJS tags |
EJS syntax
Standard EJS with ST conventions:
<%/<%_/<%=/<%-— code, trim-start, escaped output, raw outputawait getwi(...)—awaitis stripped before evaluation (ST convention)print(...)— available asoutputFunctionName(not in context to avoid shadowing)
ST decorators
Worldbook entries in ST JSON may have decorators in their content:
| Decorator | Behavior |
|-----------|----------|
| @@preprocessing | Stripped; EJS runs before keyword matching in ST |
| @@activate | Emitted by preprocessing to force-activate entry |
| @@dont_activate | Emitted by preprocessing to suppress entry |
parseDecorators(content) returns [decorators, cleanContent].
License
MIT
