@sesamecare-oss/ai-templating 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,254 @@
1
+ # ai-templating
2
+
3
+ `@sesamecare-oss/ai-templating` loads prompts and skills for Sesame services from:
4
+
5
+ - local files under `private/prompts` and `private/skills`
6
+ - Langfuse prompts, partials, and skills
7
+
8
+ It compiles prompts with Handlebars, registers a shared helper set, supports Langfuse production variants, and exposes a small `TemplateManager` API for service code.
9
+
10
+ ## Common Use Case
11
+
12
+ The normal pattern is:
13
+
14
+ 1. Create a Langfuse client
15
+ 2. Construct a `TemplateManager`
16
+ 3. Load templates during service startup
17
+ 4. Render prompts by name inside request or workflow code
18
+
19
+ ```ts
20
+ import path from 'node:path';
21
+
22
+ import { TemplateManager } from '@sesamecare-oss/ai-templating';
23
+
24
+ export async function start(app: AgentApp) {
25
+ const templates = new TemplateManager(app, {
26
+ langfuse: app.locals.langfuse,
27
+ rootDir: path.join(process.cwd(), 'private'),
28
+ });
29
+
30
+ await templates.loadTemplates();
31
+ app.locals.templates = templates;
32
+ }
33
+ ```
34
+
35
+ Later, render a prompt:
36
+
37
+ ```ts
38
+ const { messages, config, metadata } = await app.locals.templates.render(
39
+ 'patient/base-prompt',
40
+ {
41
+ patientName: 'Ada Lovelace',
42
+ appointmentDate: '2026-03-21T14:00:00.000Z',
43
+ },
44
+ {
45
+ conversation: priorMessages,
46
+ },
47
+ {
48
+ conversationUuid: '7d1a227d-bf49-4fcb-9db0-04f7c767d0b0',
49
+ },
50
+ );
51
+ ```
52
+
53
+ `render()` returns:
54
+
55
+ - `messages`: the final AI SDK `ModelMessage[]`
56
+ - `config`: model config attached to the prompt when present
57
+ - `metadata.langfusePrompt`: the serialized Langfuse prompt tag for tracing
58
+
59
+ ## Requirements
60
+
61
+ `TemplateManager` expects a service-style app object whose `locals` include:
62
+
63
+ - `logger` from `@openapi-typescript-infra/service`
64
+
65
+ The Langfuse client is passed explicitly in `TemplateManagerOptions.langfuse`.
66
+
67
+ Missing templates or skills throw `ServiceError` with status `400`.
68
+
69
+ ## Directory Layout
70
+
71
+ `rootDir` is the directory that contains `prompts/` and `skills/`.
72
+
73
+ By default the package looks for:
74
+
75
+ - `<rootDir>/prompts`
76
+ - `<rootDir>/skills`
77
+
78
+ Example:
79
+
80
+ ```ts
81
+ const templates = new TemplateManager(app, {
82
+ langfuse,
83
+ rootDir: '/srv/service/private',
84
+ });
85
+ ```
86
+
87
+ Typical local layout:
88
+
89
+ ```text
90
+ private/
91
+ prompts/
92
+ patient/
93
+ base-prompt.yaml
94
+ base-prompt.hbs
95
+ shared/
96
+ header.partial.hbs
97
+ skills/
98
+ patient/
99
+ triage.yaml
100
+ ```
101
+
102
+ Prompt and skill names are derived from paths relative to the configured `rootDir`:
103
+
104
+ - `private/prompts/patient/base-prompt.yaml` -> `patient/base-prompt`
105
+ - `private/prompts/shared/header.partial.hbs` -> partial `shared/header`
106
+ - `private/skills/patient/triage.yaml` -> skill `patient_triage`
107
+
108
+ ## Local Prompt Example
109
+
110
+ `private/prompts/patient/base-prompt.yaml`
111
+
112
+ ```yaml
113
+ messages:
114
+ - role: system
115
+ content:
116
+ $ref: ./base-prompt.hbs
117
+ config:
118
+ model: gpt-4.1
119
+ temperature: 0
120
+ topK: 0
121
+ topP: 1
122
+ ```
123
+
124
+ `private/prompts/patient/base-prompt.hbs`
125
+
126
+ ```hbs
127
+ {{> shared/header}}
128
+
129
+ You are helping {{patientName}}.
130
+ The appointment is scheduled for {{formatDate appointmentDate}}.
131
+ ```
132
+
133
+ `private/prompts/shared/header.partial.hbs`
134
+
135
+ ```hbs
136
+ Be direct, accurate, and concise.
137
+ ```
138
+
139
+ ## Local Skill Example
140
+
141
+ `private/skills/patient/triage.yaml`
142
+
143
+ ```yaml
144
+ description: Decide which patient support workflow should be used.
145
+ detail: |
146
+ Use this skill when the user is asking to schedule, reschedule, cancel,
147
+ or clarify an appointment-related request.
148
+ tools:
149
+ - appointments_search
150
+ - appointments_reschedule
151
+ ```
152
+
153
+ Load skills by name:
154
+
155
+ ```ts
156
+ const [triageSkill] = app.locals.templates.getSkills(['patient_triage']);
157
+ ```
158
+
159
+ ## Langfuse Conventions
160
+
161
+ The package treats certain Langfuse prompt names specially.
162
+
163
+ ### Standard prompts
164
+
165
+ Use the prompt name directly, for example:
166
+
167
+ - `patient/base-prompt`
168
+
169
+ Production labels control which Langfuse version is loaded:
170
+
171
+ - `production`
172
+ - `production-canary`
173
+ - `production-whatever`
174
+
175
+ If multiple production labels exist for the same prompt name, they are grouped and selected deterministically per `conversationUuid`. Variant weights come from `config.promptWeight`.
176
+
177
+ ### Partials
178
+
179
+ Name partial prompts with either:
180
+
181
+ - `partial:shared/header`
182
+ - `partial/shared/header`
183
+
184
+ These become Handlebars partials named `shared/header`.
185
+
186
+ ### Skills
187
+
188
+ Name skill prompts with either:
189
+
190
+ - `skill:patient/triage`
191
+ - `skill/patient/triage`
192
+
193
+ For Langfuse skills:
194
+
195
+ - prompt text becomes `detail`
196
+ - `config.description` is required
197
+ - `config.tools` is optional and must be an array of strings
198
+
199
+ ## Public API
200
+
201
+ The main API surface is intentionally small:
202
+
203
+ ### `new TemplateManager(app, options)`
204
+
205
+ Construct the manager. `options` supports:
206
+
207
+ - `langfuse`
208
+ - `rootDir`
209
+
210
+ ### `await templates.loadTemplates()`
211
+
212
+ Loads local templates, local skills, Langfuse inventory, partials, and production prompts into memory.
213
+
214
+ ### `await templates.render(name, data, placeholders?, options?)`
215
+
216
+ Renders a template by name.
217
+
218
+ Options:
219
+
220
+ - `promptVersion`: force a specific Langfuse version
221
+ - `conversationUuid`: stable seed for weighted variant selection
222
+
223
+ ### `templates.getSkills(names)`
224
+
225
+ Returns skill specs in the requested order.
226
+
227
+ ### `await templates.getAndCacheTemplate(name, version?, label?)`
228
+
229
+ Fetches a Langfuse template directly and stores it in the in-memory cache.
230
+
231
+ ### `await templates.reloadFromLangfuse(update?)`
232
+
233
+ Refreshes templates, skills, or partials from Langfuse.
234
+
235
+ - with `promptName`, it reloads only the affected prompt when possible
236
+ - without `promptName`, it falls back to a full reload
237
+
238
+ ## Built-in Helpers
239
+
240
+ The package registers:
241
+
242
+ - the helper set from `handlebars-helpers`
243
+ - `howLongAgo(date)`
244
+ - `formatDate(date, format?)`
245
+ - `formatCents(cents)`
246
+ - `eq(a, b)`
247
+
248
+ These are available to both filesystem prompts and Langfuse prompts.
249
+
250
+ ## Notes
251
+
252
+ - Node `>=22` is required.
253
+ - The package is designed for service environments built on `@openapi-typescript-infra/service`.
254
+ - `TemplateManager.iterateAllPrompts(langfuse)` is exported if you need raw Langfuse prompt inventory iteration.
@@ -0,0 +1,32 @@
1
+ import type { ModelMessage } from 'ai';
2
+ import type { TemplateDelegate } from 'handlebars';
3
+ import type { LangfuseClient } from '@langfuse/client';
4
+ import type { LangfuseReloadRequest, LangfuseHandlebarsTemplate, SkillSpec, TemplateApp, TemplateManagerOptions, TemplateStore, WeightedPromptGroup } from './types.js';
5
+ export declare class TemplateManager implements TemplateStore {
6
+ private readonly app;
7
+ private readonly options;
8
+ readonly templates: Record<string, LangfuseHandlebarsTemplate<unknown>>;
9
+ readonly promptGroups: Record<string, WeightedPromptGroup<unknown>>;
10
+ readonly skills: Record<string, SkillSpec>;
11
+ constructor(app: TemplateApp, options: TemplateManagerOptions);
12
+ static iterateAllPrompts(langfuse: LangfuseClient): AsyncGenerator<import("node_modules/@langfuse/core/dist/index.js").PromptMeta, void, unknown>;
13
+ loadTemplates(): Promise<void>;
14
+ getSkills(skillNames: string[]): SkillSpec[];
15
+ getAndCacheTemplate(templateName: string, version?: number, label?: string): Promise<LangfuseHandlebarsTemplate<unknown>>;
16
+ reloadFromLangfuse(update?: LangfuseReloadRequest): Promise<void>;
17
+ render<T>(template: string | TemplateDelegate<T>, data: T, placeholders: Record<string, ModelMessage[]> | undefined, options?: {
18
+ promptVersion?: number;
19
+ conversationUuid?: string;
20
+ }): Promise<{
21
+ messages: ModelMessage[];
22
+ config?: LangfuseHandlebarsTemplate['config'];
23
+ metadata?: Record<string, string>;
24
+ }>;
25
+ private resolveTemplate;
26
+ private clearStore;
27
+ private reloadPartialFromLangfuse;
28
+ private reloadSkillFromLangfuse;
29
+ private reloadPromptFromLangfuse;
30
+ private clearTemplateEntries;
31
+ }
32
+ export { selectPromptVariant } from './template-store.js';
@@ -0,0 +1,189 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import handlebars from 'handlebars';
3
+ import { ServiceError } from '@openapi-typescript-infra/service';
4
+ import { resolveTemplateDirectories } from './template-files.js';
5
+ import { loadTemplateStore } from './template-loader.js';
6
+ import { getPromptMetaByName, isPartialPromptName, isSkillPromptName, iterateAllPrompts, loadLangfusePartialByName, loadLangfuseSkillByName, loadProductionTemplates, } from './sources/langfuse.js';
7
+ import { loadFilesystemPartialByName, loadFilesystemSkillByName, loadFilesystemTemplateByName, } from './sources/filesystem.js';
8
+ import { cacheTemplateVersion, createLangfuseTemplate, getProductionLabel, mergeProductionTemplateIntoStore, selectPromptVariant, } from './template-store.js';
9
+ export class TemplateManager {
10
+ app;
11
+ options;
12
+ templates = {};
13
+ promptGroups = {};
14
+ skills = {};
15
+ constructor(app, options) {
16
+ this.app = app;
17
+ this.options = options;
18
+ }
19
+ static iterateAllPrompts(langfuse) {
20
+ return iterateAllPrompts(langfuse);
21
+ }
22
+ async loadTemplates() {
23
+ await loadTemplateStore(this.app, this.options.langfuse, this, resolveTemplateDirectories(this.options));
24
+ }
25
+ getSkills(skillNames) {
26
+ return skillNames.map((name) => {
27
+ const skill = this.skills[name];
28
+ if (!skill) {
29
+ throw new ServiceError(this.app, `Skill ${name} not found`, { status: 400 });
30
+ }
31
+ return skill;
32
+ });
33
+ }
34
+ async getAndCacheTemplate(templateName, version, label) {
35
+ const templateDetail = await this.options.langfuse.prompt.get(templateName, version ? { version, cacheTtlSeconds: 0 } : label ? { label, cacheTtlSeconds: 0 } : undefined);
36
+ if (!templateDetail) {
37
+ throw new ServiceError(this.app, `Template ${templateName}${version ? ` (v${version})` : ''}${label ? ` (${label})` : ''} not found`, { status: 400 });
38
+ }
39
+ const template = createLangfuseTemplate(templateName, templateDetail, label);
40
+ if (getProductionLabel(templateDetail.labels)) {
41
+ mergeProductionTemplateIntoStore(this, templateName, template, templateDetail.labels);
42
+ }
43
+ else {
44
+ const current = this.templates[templateName];
45
+ if (!current || (current.version !== -1 && current.version < template.version)) {
46
+ this.templates[templateName] = template;
47
+ }
48
+ }
49
+ cacheTemplateVersion(this, templateName, template);
50
+ return template;
51
+ }
52
+ async reloadFromLangfuse(update = {}) {
53
+ if (!update.promptName) {
54
+ this.clearStore();
55
+ await this.loadTemplates();
56
+ return;
57
+ }
58
+ const directories = resolveTemplateDirectories(this.options);
59
+ if (isPartialPromptName(update.promptName)) {
60
+ await this.reloadPartialFromLangfuse(update.promptName, directories);
61
+ return;
62
+ }
63
+ if (isSkillPromptName(update.promptName)) {
64
+ await this.reloadSkillFromLangfuse(update.promptName, directories);
65
+ return;
66
+ }
67
+ await this.reloadPromptFromLangfuse({ ...update, promptName: update.promptName }, directories);
68
+ }
69
+ async render(template, data, placeholders, options) {
70
+ if (typeof template === 'string') {
71
+ const templateInfo = await this.resolveTemplate(template, options);
72
+ const messages = templateInfo
73
+ .delegate(data, placeholders)
74
+ .filter((message) => message.content);
75
+ return {
76
+ messages,
77
+ config: templateInfo.config,
78
+ metadata: {
79
+ langfusePrompt: templateInfo.tag,
80
+ },
81
+ };
82
+ }
83
+ const raw = template(data);
84
+ const messages = raw.split('---').map((message) => {
85
+ const [role, ...content] = message
86
+ .trim()
87
+ .split('\n')
88
+ .map((line) => line.trim());
89
+ if (role.startsWith('role:')) {
90
+ return {
91
+ role: role.replace('role:', '').trim(),
92
+ content: content.join('\n'),
93
+ };
94
+ }
95
+ return { role: 'user', content: message.trim() };
96
+ });
97
+ return { messages };
98
+ }
99
+ async resolveTemplate(templateName, options) {
100
+ if (options?.promptVersion && this.templates[templateName]?.version !== options.promptVersion) {
101
+ return this.getAndCacheTemplate(templateName, options.promptVersion);
102
+ }
103
+ if (!this.templates[templateName] && !this.promptGroups[templateName]) {
104
+ await this.getAndCacheTemplate(templateName);
105
+ }
106
+ const templateInfo = this.templates[templateName];
107
+ if (templateInfo) {
108
+ return templateInfo;
109
+ }
110
+ const group = this.promptGroups[templateName];
111
+ if (group) {
112
+ return selectPromptVariant(options?.conversationUuid || randomUUID(), group);
113
+ }
114
+ throw new ServiceError(this.app, `Template ${templateName} not found`, { status: 400 });
115
+ }
116
+ clearStore() {
117
+ clearRecord(this.templates);
118
+ clearRecord(this.promptGroups);
119
+ clearRecord(this.skills);
120
+ }
121
+ async reloadPartialFromLangfuse(promptName, directories) {
122
+ const partialName = promptName.replace(/partial[:/]/, '');
123
+ const localPartial = loadFilesystemPartialByName(directories.promptsDir, partialName);
124
+ if (localPartial) {
125
+ handlebars.registerPartial(partialName, localPartial.code);
126
+ return;
127
+ }
128
+ const langfusePartial = await loadLangfusePartialByName(this.app, this.options.langfuse, promptName);
129
+ if (langfusePartial) {
130
+ handlebars.registerPartial(partialName, langfusePartial.code);
131
+ return;
132
+ }
133
+ handlebars.unregisterPartial(partialName);
134
+ }
135
+ async reloadSkillFromLangfuse(promptName, directories) {
136
+ const skillPath = promptName.replace(/skill[:/]/, '');
137
+ const skillName = skillPath.replace(/\//g, '_');
138
+ delete this.skills[skillName];
139
+ const hasLocalSkill = await loadFilesystemSkillByName(this.app, this, directories.skillsDir, skillPath);
140
+ if (hasLocalSkill) {
141
+ return;
142
+ }
143
+ const langfuseSkill = await loadLangfuseSkillByName(this.app, this.options.langfuse, promptName);
144
+ if (langfuseSkill) {
145
+ this.skills[skillName] = langfuseSkill;
146
+ }
147
+ }
148
+ async reloadPromptFromLangfuse(update, directories) {
149
+ const templateName = update.promptName;
150
+ this.clearTemplateEntries(templateName);
151
+ await loadFilesystemTemplateByName(this.app, this, directories.promptsDir, templateName);
152
+ const promptMeta = await getPromptMetaByName(this.options.langfuse, templateName);
153
+ const productionLabels = promptMeta?.labels.filter((label) => label.startsWith('production')) ?? [];
154
+ if (productionLabels.length > 0) {
155
+ await loadProductionTemplates(this.app, this.options.langfuse, this, new Map([[templateName, productionLabels]]));
156
+ return;
157
+ }
158
+ if (this.templates[templateName]?.version === -1) {
159
+ return;
160
+ }
161
+ const promptDetail = await this.options.langfuse.prompt.get(templateName, update.version
162
+ ? { version: update.version, cacheTtlSeconds: 0 }
163
+ : update.label
164
+ ? { label: update.label, cacheTtlSeconds: 0 }
165
+ : undefined);
166
+ if (!promptDetail) {
167
+ return;
168
+ }
169
+ const template = createLangfuseTemplate(templateName, promptDetail, update.label);
170
+ this.templates[templateName] = template;
171
+ cacheTemplateVersion(this, templateName, template);
172
+ }
173
+ clearTemplateEntries(templateName) {
174
+ delete this.templates[templateName];
175
+ delete this.promptGroups[templateName];
176
+ for (const key of Object.keys(this.templates)) {
177
+ if (key.startsWith(`${templateName}::`) || key.startsWith(`${templateName}#`)) {
178
+ delete this.templates[key];
179
+ }
180
+ }
181
+ }
182
+ }
183
+ export { selectPromptVariant } from './template-store.js';
184
+ function clearRecord(record) {
185
+ for (const key of Object.keys(record)) {
186
+ delete record[key];
187
+ }
188
+ }
189
+ //# sourceMappingURL=TemplateManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateManager.js","sourceRoot":"","sources":["../src/TemplateManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ChatPromptClient, TextPromptClient } from '@langfuse/client';
2
+ import type { LangfuseTemplateDelegate } from './types.js';
3
+ export declare function compileLangfusePrompt<T>(promptDetail: Pick<TextPromptClient, 'type' | 'prompt'> | Pick<ChatPromptClient, 'prompt' | 'type'>): LangfuseTemplateDelegate<T>;
@@ -0,0 +1,42 @@
1
+ import handlebars from 'handlebars';
2
+ import { ChatMessageType } from '@langfuse/client';
3
+ export function compileLangfusePrompt(promptDetail) {
4
+ if (promptDetail.type === 'chat') {
5
+ const promptMessages = promptDetail.prompt;
6
+ const compiledHandlebars = promptMessages.map((message) => {
7
+ if (message.type === ChatMessageType.Placeholder) {
8
+ return message.name;
9
+ }
10
+ const chatMessage = message;
11
+ return {
12
+ role: chatMessage.role,
13
+ template: handlebars.compile(chatMessage.content),
14
+ };
15
+ });
16
+ return function renderChatPrompt(context, placeholders, options) {
17
+ const messages = [];
18
+ for (const entry of compiledHandlebars) {
19
+ if (typeof entry === 'string') {
20
+ messages.push(...(placeholders?.[entry] ?? []));
21
+ continue;
22
+ }
23
+ messages.push({
24
+ role: entry.role,
25
+ content: entry.template(context, options),
26
+ });
27
+ }
28
+ return messages;
29
+ };
30
+ }
31
+ const template = handlebars.compile(promptDetail.prompt);
32
+ return (context, placeholders, options) => {
33
+ void placeholders;
34
+ return [
35
+ {
36
+ role: 'user',
37
+ content: template(context, options),
38
+ },
39
+ ];
40
+ };
41
+ }
42
+ //# sourceMappingURL=compile-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-prompt.js","sourceRoot":"","sources":["../src/compile-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMnD,MAAM,UAAU,qBAAqB,CACnC,YAE6C;IAE7C,IAAI,YAAY,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACjC,MAAM,cAAc,GAAG,YAAY,CAAC,MAAoC,CAAC;QACzE,MAAM,kBAAkB,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YACxD,IAAI,OAAO,CAAC,IAAI,KAAK,eAAe,CAAC,WAAW,EAAE,CAAC;gBACjD,OAAO,OAAO,CAAC,IAAI,CAAC;YACtB,CAAC;YAED,MAAM,WAAW,GAAG,OAA0D,CAAC;YAE/E,OAAO;gBACL,IAAI,EAAE,WAAW,CAAC,IAA4B;gBAC9C,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC;aAClD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO,SAAS,gBAAgB,CAC9B,OAAU,EACV,YAAwD,EACxD,OAAwB;YAExB,MAAM,QAAQ,GAAmB,EAAE,CAAC;YACpC,KAAK,MAAM,KAAK,IAAI,kBAAkB,EAAE,CAAC;gBACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC9B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;oBAChD,SAAS;gBACX,CAAC;gBAED,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;iBACf,CAAC,CAAC;YAChC,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACzD,OAAO,CACL,OAAU,EACV,YAAwD,EACxD,OAAwB,EACxB,EAAE;QACF,KAAK,YAAY,CAAC;QAElB,OAAO;YACL;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;aACpC;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function registerHandlebarsHelpers(): void;
@@ -0,0 +1,26 @@
1
+ import handlebars from 'handlebars';
2
+ import helpers from 'handlebars-helpers';
3
+ import { formatDate, formatDistanceToNow } from 'date-fns';
4
+ let helpersRegistered = false;
5
+ export function registerHandlebarsHelpers() {
6
+ if (helpersRegistered) {
7
+ return;
8
+ }
9
+ helpers();
10
+ handlebars.registerHelper('howLongAgo', (date) => {
11
+ return formatDistanceToNow(new Date(date), { addSuffix: true });
12
+ });
13
+ handlebars.registerHelper('formatDate', (date, formatString) => {
14
+ return formatDate(new Date(date), formatString && typeof formatString === 'string' ? formatString : 'MM/dd/yyyy HH:mm:ss aaa');
15
+ });
16
+ handlebars.registerHelper('formatCents', (cents) => {
17
+ if (cents === undefined || cents === null) {
18
+ return 'N/A';
19
+ }
20
+ const dollars = cents / 100;
21
+ return `$${dollars.toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 0 })}`;
22
+ });
23
+ handlebars.registerHelper('eq', (a, b) => a === b);
24
+ helpersRegistered = true;
25
+ }
26
+ //# sourceMappingURL=handlebars-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlebars-helpers.js","sourceRoot":"","sources":["../src/handlebars-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,OAAO,MAAM,oBAAoB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE3D,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAE9B,MAAM,UAAU,yBAAyB;IACvC,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO;IACT,CAAC;IAED,OAAO,EAAE,CAAC;IAEV,UAAU,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,IAAY,EAAE,EAAE;QACvD,OAAO,mBAAmB,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,IAAY,EAAE,YAAqB,EAAE,EAAE;QAC9E,OAAO,UAAU,CACf,IAAI,IAAI,CAAC,IAAI,CAAC,EACd,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,yBAAyB,CAC5F,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,KAAa,EAAE,EAAE;QACzD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,GAAG,GAAG,CAAC;QAC5B,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACvG,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,iBAAiB,GAAG,IAAI,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { TemplateManager, selectPromptVariant } from './TemplateManager.js';
2
+ export { getPartialNameFromFile, getPromptNameFromFile, getSkillNameFromFile, resolveTemplateDirectories, } from './template-files.js';
3
+ export { iterateAllPrompts } from './sources/langfuse.js';
4
+ export { fnv1a32, normalize, parseWeights, seededUnitFloat, weightedPick, } from './weighted-selector.js';
5
+ export type { DevPrompt, LangfuseReloadRequest, LangfuseHandlebarsTemplate, LangfusePromptDetail, PromptVariant, SkillSpec, TemplateApp, TemplateConfig, TemplateDirectories, TemplateManagerOptions, TemplatePartialSource, TemplateStore, WeightedPromptGroup, } from './types.js';
package/build/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { TemplateManager, selectPromptVariant } from './TemplateManager.js';
2
+ export { getPartialNameFromFile, getPromptNameFromFile, getSkillNameFromFile, resolveTemplateDirectories, } from './template-files.js';
3
+ export { iterateAllPrompts } from './sources/langfuse.js';
4
+ export { fnv1a32, normalize, parseWeights, seededUnitFloat, weightedPick, } from './weighted-selector.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EACL,OAAO,EACP,SAAS,EACT,YAAY,EACZ,eAAe,EACf,YAAY,GACb,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { TemplateApp, TemplatePartialSource, TemplateStore } from '../types.js';
2
+ export declare function loadFilesystemPartials(promptsDir: string): Promise<Map<string, TemplatePartialSource>>;
3
+ export declare function loadFilesystemPartialByName(promptsDir: string, partialName: string): {
4
+ source: "filesystem";
5
+ code: string;
6
+ name: string;
7
+ version: string;
8
+ } | undefined;
9
+ export declare function loadFilesystemTemplates(app: TemplateApp, store: TemplateStore, promptsDir: string): Promise<void>;
10
+ export declare function loadFilesystemTemplateByName(app: TemplateApp, store: TemplateStore, promptsDir: string, templateName: string): Promise<boolean>;
11
+ export declare function loadFilesystemSkills(app: TemplateApp, store: TemplateStore, skillsDir: string): Promise<void>;
12
+ export declare function loadFilesystemSkillByName(app: TemplateApp, store: TemplateStore, skillsDir: string, skillPath: string): Promise<boolean>;