@vertesia/studio-utils 1.6.0-dev.20260923.085325Z → 1.6.0-dev.20261004.085740Z
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/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -1
- package/lib/index.js.map +1 -1
- package/lib/prompts/extract-vars.d.ts +44 -12
- package/lib/prompts/extract-vars.d.ts.map +1 -1
- package/lib/prompts/extract-vars.js +165 -78
- package/lib/prompts/extract-vars.js.map +1 -1
- package/lib/prompts/render.d.ts +7 -9
- package/lib/prompts/render.d.ts.map +1 -1
- package/lib/prompts/render.js +12 -15
- package/lib/prompts/render.js.map +1 -1
- package/lib/prompts/validate.d.ts +8 -2
- package/lib/prompts/validate.d.ts.map +1 -1
- package/lib/prompts/validate.js +87 -51
- package/lib/prompts/validate.js.map +1 -1
- package/lib/roles/agent-runs.d.ts +8 -0
- package/lib/roles/agent-runs.d.ts.map +1 -0
- package/lib/roles/agent-runs.js +36 -0
- package/lib/roles/agent-runs.js.map +1 -0
- package/lib/roles/classes.d.ts +15 -1
- package/lib/roles/classes.d.ts.map +1 -1
- package/lib/roles/classes.js +10 -1
- package/lib/roles/classes.js.map +1 -1
- package/lib/roles/content.d.ts.map +1 -1
- package/lib/roles/content.js +14 -4
- package/lib/roles/content.js.map +1 -1
- package/lib/roles/index.d.ts +4 -3
- package/lib/roles/index.d.ts.map +1 -1
- package/lib/roles/index.js +7 -5
- package/lib/roles/index.js.map +1 -1
- package/lib/vertesia-studio-utils.js +2 -1
- package/lib/vertesia-studio-utils.js.map +1 -1
- package/package.json +11 -10
- package/src/index.ts +20 -1
- package/src/prompts/extract-vars.ts +212 -71
- package/src/prompts/render.ts +24 -15
- package/src/prompts/validate.ts +113 -57
- package/src/roles/agent-runs.ts +41 -0
- package/src/roles/classes.ts +7 -0
- package/src/roles/content.ts +21 -5
- package/src/roles/index.ts +7 -5
- package/src/apps/index.test.ts +0 -166
- package/src/conditions/match.test.ts +0 -134
- package/src/prompts/render.test.ts +0 -110
- package/src/prompts/validate.test.ts +0 -309
- package/src/roles/index.test.ts +0 -221
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
export { describeTemplateSystemVariables, HANDLEBARS_HELPER_NAMES, isTemplateSystemVariable, TEMPLATE_SYSTEM_VARIABLE_NAMES, TEMPLATE_SYSTEM_VARIABLES, type TemplateSystemContext, type TemplateSystemVariable, type TemplateSystemVariableName, withTemplateSystemVariables, } from '@vertesia/jst';
|
|
1
2
|
export { substituteEndpoints } from './apps/index.js';
|
|
2
|
-
export { extractHandlebarsVariables } from './prompts/extract-vars.js';
|
|
3
|
+
export { analyzeHandlebarsTemplate, extractHandlebarsVariables, type HandlebarsHelperMisuse, type HandlebarsTemplateAnalysis, type HandlebarsVariableReference, } from './prompts/extract-vars.js';
|
|
3
4
|
export { generateMockData } from './prompts/mock-data.js';
|
|
4
5
|
export { executeHandlebars, executeJST, renderPrompt, renderSegments, renderSegmentsOrErrors, renderTemplate, type SegmentPreview, } from './prompts/render.js';
|
|
5
6
|
export { type PromptValidationInput, type PromptValidationIssue, type PromptValidationIssueSeverity, type PromptValidationIssueType, type PromptValidationResult, validatePrompt, } from './prompts/validate.js';
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,+BAA+B,EAC/B,uBAAuB,EACvB,wBAAwB,EACxB,8BAA8B,EAC9B,yBAAyB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,2BAA2B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EACH,yBAAyB,EACzB,0BAA0B,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,GACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACH,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,KAAK,cAAc,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,cAAc,GACjB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,kBAAkB,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
// The template runtime's registry, re-exported so consumers validating or documenting prompts
|
|
2
|
+
// read the same names the renderer uses.
|
|
3
|
+
export { describeTemplateSystemVariables, HANDLEBARS_HELPER_NAMES, isTemplateSystemVariable, TEMPLATE_SYSTEM_VARIABLE_NAMES, TEMPLATE_SYSTEM_VARIABLES, withTemplateSystemVariables, } from '@vertesia/jst';
|
|
1
4
|
export { substituteEndpoints } from './apps/index.js';
|
|
2
|
-
export { extractHandlebarsVariables } from './prompts/extract-vars.js';
|
|
5
|
+
export { analyzeHandlebarsTemplate, extractHandlebarsVariables, } from './prompts/extract-vars.js';
|
|
3
6
|
export { generateMockData } from './prompts/mock-data.js';
|
|
4
7
|
export { executeHandlebars, executeJST, renderPrompt, renderSegments, renderSegmentsOrErrors, renderTemplate, } from './prompts/render.js';
|
|
5
8
|
export { validatePrompt, } from './prompts/validate.js';
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,yCAAyC;AACzC,OAAO,EACH,+BAA+B,EAC/B,uBAAuB,EACvB,wBAAwB,EACxB,8BAA8B,EAC9B,yBAAyB,EAIzB,2BAA2B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EACH,yBAAyB,EACzB,0BAA0B,GAI7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACH,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,cAAc,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAMH,cAAc,GACjB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,kBAAkB,CAAC"}
|
|
@@ -1,19 +1,51 @@
|
|
|
1
|
+
/** A read of a root-level template variable. */
|
|
2
|
+
export interface HandlebarsVariableReference {
|
|
3
|
+
/** Root identifier: `customer` for `{{customer.name}}`, `{{../customer}}` or `{{@root.customer}}`. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** The path as written, e.g. `customer.name`. */
|
|
6
|
+
expression: string;
|
|
7
|
+
/** True when the path reads a property of the variable (`customer.name`). */
|
|
8
|
+
hasPath: boolean;
|
|
9
|
+
/** Source of the tag that contains the read, e.g. `{{#if customer}}`. */
|
|
10
|
+
tag: string;
|
|
11
|
+
}
|
|
12
|
+
/** A helper name used where Handlebars will not call it. */
|
|
13
|
+
export interface HandlebarsHelperMisuse {
|
|
14
|
+
helper: string;
|
|
15
|
+
/**
|
|
16
|
+
* - `used_as_value`: passed as an argument (`{{#if stringify}}`), where Handlebars reads the data.
|
|
17
|
+
* - `missing_arguments`: called bare (`{{stringify}}`) with none of the arguments it needs.
|
|
18
|
+
*/
|
|
19
|
+
problem: 'used_as_value' | 'missing_arguments';
|
|
20
|
+
tag: string;
|
|
21
|
+
}
|
|
22
|
+
export interface HandlebarsTemplateAnalysis {
|
|
23
|
+
references: HandlebarsVariableReference[];
|
|
24
|
+
helperMisuses: HandlebarsHelperMisuse[];
|
|
25
|
+
}
|
|
1
26
|
/**
|
|
2
|
-
*
|
|
27
|
+
* Analyze the variables and helpers a Handlebars template uses, resolving names the way the
|
|
28
|
+
* prompt renderer does (helpers and system variables come from `@vertesia/jst`).
|
|
3
29
|
*
|
|
4
|
-
*
|
|
5
|
-
* - `{{
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - `
|
|
9
|
-
* - `{{@index}}
|
|
30
|
+
* Scoping rules:
|
|
31
|
+
* - Inside `{{#each}}` / `{{#with}}` (and `{{#section}}` over data), bare names read the current item,
|
|
32
|
+
* whose shape the input schema does not describe — they are not reported. `../x` and `@root.x`
|
|
33
|
+
* read the enclosing or root context and are reported.
|
|
34
|
+
* - `as |x|` block params are local bindings, not variables.
|
|
35
|
+
* - `{{@index}}` and other `@`-data (except `@root.x`) are runtime values, not variables.
|
|
10
36
|
*
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
37
|
+
* Returns null when the template does not parse; the render check reports the syntax error.
|
|
38
|
+
*/
|
|
39
|
+
export declare function analyzeHandlebarsTemplate(template: string): HandlebarsTemplateAnalysis | null;
|
|
40
|
+
/**
|
|
41
|
+
* Extract the set of root-level input variable names a Handlebars template reads.
|
|
42
|
+
*
|
|
43
|
+
* - `{{foo}}` → `foo`; `{{obj.bar.baz}}` → `obj`
|
|
44
|
+
* - `{{#each items as |item|}}{{item.name}}{{/each}}` → `items` (`item` is a block param)
|
|
45
|
+
* - `{{lookup obj key}}` → `obj`, `key` (helper name skipped)
|
|
46
|
+
* - `{{@index}}`, `{{this}}`, and bare names inside `#each`/`#with` → ignored
|
|
14
47
|
*
|
|
15
|
-
* Returns an empty set on parse failure
|
|
16
|
-
* (e.g. `executeHandlebars`) to surface parse errors separately.
|
|
48
|
+
* Returns an empty set on parse failure.
|
|
17
49
|
*/
|
|
18
50
|
export declare function extractHandlebarsVariables(template: string): Set<string>;
|
|
19
51
|
//# sourceMappingURL=extract-vars.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-vars.d.ts","sourceRoot":"","sources":["../../src/prompts/extract-vars.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"extract-vars.d.ts","sourceRoot":"","sources":["../../src/prompts/extract-vars.ts"],"names":[],"mappings":"AAGA,gDAAgD;AAChD,MAAM,WAAW,2BAA2B;IACxC,sGAAsG;IACtG,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAC;IACjB,yEAAyE;IACzE,GAAG,EAAE,MAAM,CAAC;CACf;AAED,4DAA4D;AAC5D,MAAM,WAAW,sBAAsB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,EAAE,eAAe,GAAG,mBAAmB,CAAC;IAC/C,GAAG,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACvC,UAAU,EAAE,2BAA2B,EAAE,CAAC;IAC1C,aAAa,EAAE,sBAAsB,EAAE,CAAC;CAC3C;AAyCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,0BAA0B,GAAG,IAAI,CA2J7F;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAGxE"}
|
|
@@ -1,114 +1,201 @@
|
|
|
1
|
+
import { HANDLEBARS_CONTEXT_HELPERS, isHandlebarsHelper, isTemplateSystemVariable } from '@vertesia/jst';
|
|
1
2
|
import Handlebars from 'handlebars';
|
|
3
|
+
function isPath(node) {
|
|
4
|
+
return !!node && typeof node === 'object' && node.type === 'PathExpression';
|
|
5
|
+
}
|
|
6
|
+
/** `this.x`, `./x` and `this` read the context explicitly — Handlebars never treats them as helpers. */
|
|
7
|
+
function isScoped(path) {
|
|
8
|
+
return /^\.|this\b/.test(path.original);
|
|
9
|
+
}
|
|
10
|
+
/** A single bare identifier — the only form Handlebars may resolve to a helper. */
|
|
11
|
+
function isSimpleId(path) {
|
|
12
|
+
return path.parts.length === 1 && !isScoped(path) && !path.data && path.depth === 0;
|
|
13
|
+
}
|
|
14
|
+
function lineOffsets(template) {
|
|
15
|
+
const offsets = [0];
|
|
16
|
+
for (let i = 0; i < template.length; i++) {
|
|
17
|
+
if (template[i] === '\n')
|
|
18
|
+
offsets.push(i + 1);
|
|
19
|
+
}
|
|
20
|
+
return offsets;
|
|
21
|
+
}
|
|
2
22
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* - `{{foo}}` → `foo`
|
|
6
|
-
* - `{{obj.bar.baz}}` → `obj` (only the root identifier; nested access doesn't add `bar` or `baz`)
|
|
7
|
-
* - `{{#if cond}}{{name}}{{/if}}` → `cond`, `name`
|
|
8
|
-
* - `{{#each items as |item|}}{{item.name}}{{/each}}` → `items` (NOT `item` — bound by `as |item|`)
|
|
9
|
-
* - `{{lookup obj key}}` → `obj`, `key` (helper name skipped)
|
|
10
|
-
* - `{{@index}}`, `{{this}}` → ignored (built-in data vars / self)
|
|
23
|
+
* Analyze the variables and helpers a Handlebars template uses, resolving names the way the
|
|
24
|
+
* prompt renderer does (helpers and system variables come from `@vertesia/jst`).
|
|
11
25
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
26
|
+
* Scoping rules:
|
|
27
|
+
* - Inside `{{#each}}` / `{{#with}}` (and `{{#section}}` over data), bare names read the current item,
|
|
28
|
+
* whose shape the input schema does not describe — they are not reported. `../x` and `@root.x`
|
|
29
|
+
* read the enclosing or root context and are reported.
|
|
30
|
+
* - `as |x|` block params are local bindings, not variables.
|
|
31
|
+
* - `{{@index}}` and other `@`-data (except `@root.x`) are runtime values, not variables.
|
|
15
32
|
*
|
|
16
|
-
* Returns
|
|
17
|
-
* (e.g. `executeHandlebars`) to surface parse errors separately.
|
|
33
|
+
* Returns null when the template does not parse; the render check reports the syntax error.
|
|
18
34
|
*/
|
|
19
|
-
export function
|
|
35
|
+
export function analyzeHandlebarsTemplate(template) {
|
|
20
36
|
let ast;
|
|
21
37
|
try {
|
|
22
38
|
ast = Handlebars.parse(template);
|
|
23
39
|
}
|
|
24
40
|
catch {
|
|
25
|
-
return
|
|
41
|
+
return null;
|
|
26
42
|
}
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
43
|
+
const offsets = lineOffsets(template);
|
|
44
|
+
const tagAt = (loc) => {
|
|
45
|
+
if (!loc)
|
|
46
|
+
return '';
|
|
47
|
+
const start = (offsets[loc.start.line - 1] ?? 0) + loc.start.column;
|
|
48
|
+
const end = template.indexOf('}}', start);
|
|
49
|
+
if (end < 0)
|
|
50
|
+
return template.slice(start);
|
|
51
|
+
return template.slice(start, template[end + 2] === '}' ? end + 3 : end + 2);
|
|
52
|
+
};
|
|
53
|
+
const references = [];
|
|
54
|
+
const helperMisuses = [];
|
|
55
|
+
const contexts = ['root'];
|
|
56
|
+
const blockParams = [];
|
|
57
|
+
let tag = '';
|
|
58
|
+
const isBlockParam = (name) => blockParams.some((scope) => scope.has(name));
|
|
59
|
+
/** Record a data read of `path`, if it reads the root input. */
|
|
60
|
+
const readData = (path) => {
|
|
61
|
+
if (path.data) {
|
|
62
|
+
// `@root.x` reads the input root; `@index`, `@key`, ... are runtime values.
|
|
63
|
+
if (path.parts[0] === 'root' && path.parts.length > 1) {
|
|
64
|
+
references.push({
|
|
65
|
+
name: path.parts[1],
|
|
66
|
+
expression: path.original,
|
|
67
|
+
hasPath: path.parts.length > 2,
|
|
68
|
+
tag,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (path.parts.length === 0)
|
|
74
|
+
return; // `this` / `.`
|
|
75
|
+
const root = path.parts[0];
|
|
76
|
+
if (path.depth === 0 && !isScoped(path) && isBlockParam(root))
|
|
77
|
+
return;
|
|
78
|
+
// Handlebars stops at the root context when `../` goes past it.
|
|
79
|
+
const context = contexts[Math.max(0, contexts.length - 1 - path.depth)];
|
|
80
|
+
if (context !== 'root')
|
|
81
|
+
return;
|
|
82
|
+
references.push({ name: root, expression: path.original, hasPath: path.parts.length > 1, tag });
|
|
83
|
+
};
|
|
84
|
+
/** A path in argument position (params, hash values): Handlebars reads data, never calls a helper. */
|
|
85
|
+
const visitArgument = (node) => {
|
|
86
|
+
if (isPath(node)) {
|
|
87
|
+
const name = node.parts[0];
|
|
88
|
+
// System variables are injected as data too, so they resolve as arguments.
|
|
89
|
+
if (isSimpleId(node) &&
|
|
90
|
+
!isBlockParam(name) &&
|
|
91
|
+
isHandlebarsHelper(name) &&
|
|
92
|
+
!isTemplateSystemVariable(name)) {
|
|
93
|
+
helperMisuses.push({ helper: name, problem: 'used_as_value', tag });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
readData(node);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
visit(node);
|
|
100
|
+
};
|
|
101
|
+
const visitCall = (n) => {
|
|
102
|
+
const params = n.params ?? [];
|
|
103
|
+
for (const p of params)
|
|
104
|
+
visitArgument(p);
|
|
105
|
+
const pairs = n.hash?.pairs ?? [];
|
|
106
|
+
for (const pair of pairs)
|
|
107
|
+
visitArgument(pair.value);
|
|
108
|
+
};
|
|
109
|
+
const hasArguments = (n) => (n.params?.length ?? 0) > 0 ||
|
|
110
|
+
(n.hash?.pairs?.length ?? 0) > 0;
|
|
30
111
|
const visit = (node) => {
|
|
31
112
|
if (!node || typeof node !== 'object')
|
|
32
113
|
return;
|
|
33
114
|
const n = node;
|
|
34
115
|
switch (n.type) {
|
|
35
116
|
case 'Program': {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
117
|
+
for (const stmt of n.body ?? [])
|
|
118
|
+
visit(stmt);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
case 'MustacheStatement': {
|
|
122
|
+
tag = tagAt(n.loc);
|
|
123
|
+
const path = n.path;
|
|
124
|
+
if (hasArguments(n)) {
|
|
125
|
+
// `{{helper arg}}`: the head is a helper name (a missing one fails the render check).
|
|
126
|
+
visitCall(n);
|
|
127
|
+
}
|
|
128
|
+
else if (isPath(path)) {
|
|
129
|
+
// A bare `{{name}}` calls a helper of that name when there is one, else reads data.
|
|
130
|
+
// System variables are helpers returning their injected value, meant to be used bare.
|
|
131
|
+
const name = path.parts[0];
|
|
132
|
+
if (isSimpleId(path) && !isBlockParam(name) && isHandlebarsHelper(name)) {
|
|
133
|
+
if (!isTemplateSystemVariable(name)) {
|
|
134
|
+
helperMisuses.push({ helper: name, problem: 'missing_arguments', tag });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
readData(path);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
visit(path);
|
|
143
|
+
}
|
|
40
144
|
break;
|
|
41
145
|
}
|
|
42
146
|
case 'BlockStatement': {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
147
|
+
tag = tagAt(n.loc);
|
|
148
|
+
const path = n.path;
|
|
149
|
+
const helper = isPath(path) && isSimpleId(path) ? path.parts[0] : undefined;
|
|
150
|
+
let itemContext;
|
|
151
|
+
if (hasArguments(n) || (helper && isHandlebarsHelper(helper))) {
|
|
152
|
+
visitCall(n);
|
|
153
|
+
itemContext = !!helper && HANDLEBARS_CONTEXT_HELPERS.includes(helper);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
// `{{#section}}…{{/section}}` over data: iterates or enters `section`.
|
|
157
|
+
if (isPath(path))
|
|
158
|
+
readData(path);
|
|
159
|
+
itemContext = true;
|
|
160
|
+
}
|
|
51
161
|
const program = n.program;
|
|
52
162
|
const inverse = n.inverse;
|
|
53
|
-
|
|
54
|
-
|
|
163
|
+
blockParams.push(new Set(program?.blockParams ?? []));
|
|
164
|
+
contexts.push(itemContext ? 'item' : contexts[contexts.length - 1]);
|
|
55
165
|
visit(n.program);
|
|
166
|
+
contexts.pop();
|
|
167
|
+
blockParams.pop();
|
|
168
|
+
// `{{else}}` renders with the enclosing context.
|
|
169
|
+
blockParams.push(new Set(inverse?.blockParams ?? []));
|
|
56
170
|
visit(n.inverse);
|
|
57
|
-
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
case 'MustacheStatement': {
|
|
61
|
-
// Bare mustache (no params, no hash) → it's a variable reference.
|
|
62
|
-
// With params/hash, it's a helper call — skip the path (helper name), visit args.
|
|
63
|
-
const params = n.params;
|
|
64
|
-
const hash = n.hash;
|
|
65
|
-
const isHelperCall = (params?.length ?? 0) > 0 || (hash?.pairs?.length ?? 0) > 0;
|
|
66
|
-
// The renderer registers _now as a zero-argument helper. Only the bare
|
|
67
|
-
// helper invocation is implicit; paths such as this._now remain data reads.
|
|
68
|
-
const path = n.path;
|
|
69
|
-
if (!isHelperCall && path?.original !== '_now') {
|
|
70
|
-
visit(n.path);
|
|
71
|
-
}
|
|
72
|
-
if (params)
|
|
73
|
-
for (const p of params)
|
|
74
|
-
visit(p);
|
|
75
|
-
visit(hash);
|
|
171
|
+
blockParams.pop();
|
|
76
172
|
break;
|
|
77
173
|
}
|
|
78
174
|
case 'SubExpression': {
|
|
79
|
-
// (helper
|
|
80
|
-
|
|
81
|
-
if (params)
|
|
82
|
-
for (const p of params)
|
|
83
|
-
visit(p);
|
|
84
|
-
visit(n.hash);
|
|
175
|
+
// `(helper arg)`: the head is a call, like a bare `{{helper}}`.
|
|
176
|
+
visitCall(n);
|
|
85
177
|
break;
|
|
86
178
|
}
|
|
87
|
-
|
|
88
|
-
if (n.data)
|
|
89
|
-
break; // `@-data` references (@index, @key, etc.)
|
|
90
|
-
const parts = n.parts;
|
|
91
|
-
if (!parts || parts.length === 0)
|
|
92
|
-
break; // `this` / `.`
|
|
93
|
-
const root = parts[0];
|
|
94
|
-
if (isLocal(root))
|
|
95
|
-
break;
|
|
96
|
-
variables.add(root);
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
case 'Hash': {
|
|
100
|
-
const pairs = n.pairs;
|
|
101
|
-
if (pairs)
|
|
102
|
-
for (const pair of pairs)
|
|
103
|
-
visit(pair.value);
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
// ContentStatement, CommentStatement, *Literal, PartialStatement — no variables to extract.
|
|
179
|
+
// ContentStatement, CommentStatement, literals, partials — no variables.
|
|
107
180
|
default:
|
|
108
181
|
break;
|
|
109
182
|
}
|
|
110
183
|
};
|
|
111
184
|
visit(ast);
|
|
112
|
-
return
|
|
185
|
+
return { references, helperMisuses };
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Extract the set of root-level input variable names a Handlebars template reads.
|
|
189
|
+
*
|
|
190
|
+
* - `{{foo}}` → `foo`; `{{obj.bar.baz}}` → `obj`
|
|
191
|
+
* - `{{#each items as |item|}}{{item.name}}{{/each}}` → `items` (`item` is a block param)
|
|
192
|
+
* - `{{lookup obj key}}` → `obj`, `key` (helper name skipped)
|
|
193
|
+
* - `{{@index}}`, `{{this}}`, and bare names inside `#each`/`#with` → ignored
|
|
194
|
+
*
|
|
195
|
+
* Returns an empty set on parse failure.
|
|
196
|
+
*/
|
|
197
|
+
export function extractHandlebarsVariables(template) {
|
|
198
|
+
const analysis = analyzeHandlebarsTemplate(template);
|
|
199
|
+
return new Set(analysis?.references.map((r) => r.name) ?? []);
|
|
113
200
|
}
|
|
114
201
|
//# sourceMappingURL=extract-vars.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-vars.js","sourceRoot":"","sources":["../../src/prompts/extract-vars.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"extract-vars.js","sourceRoot":"","sources":["../../src/prompts/extract-vars.ts"],"names":[],"mappings":"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"}
|
package/lib/prompts/render.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { JSONObject, JSONSchema, PromptSegment } from '@llumiverse/common';
|
|
2
2
|
import { type PromptSegmentDef, type PromptTemplate, TemplateType } from '@vertesia/common';
|
|
3
|
+
import { type TemplateSystemContext } from '@vertesia/jst';
|
|
3
4
|
export interface SegmentPreview {
|
|
4
5
|
error?: Error;
|
|
5
6
|
title: string;
|
|
@@ -9,21 +10,18 @@ export interface SegmentPreview {
|
|
|
9
10
|
/**
|
|
10
11
|
* Render a prompt template with the given input data.
|
|
11
12
|
*
|
|
12
|
-
* Handlebars templates use {{variable}} interpolation against `data`.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* studio-server executor
|
|
16
|
-
*
|
|
17
|
-
* and `apps/studio-server/src/executor/rendering/template.ts`). Listing it here keeps
|
|
18
|
-
* the Playground preview and `validatePrompt` in sync with runtime resolution — a JST
|
|
19
|
-
* template referencing `_model` validates fine here and renders fine in production.
|
|
13
|
+
* Handlebars templates use {{variable}} interpolation against `data`. JST (JavaScript template)
|
|
14
|
+
* bodies evaluate against `data` with the schema's top-level property names exposed as globals.
|
|
15
|
+
* Both see the system variables (`TEMPLATE_SYSTEM_VARIABLES` in `@vertesia/jst`), added here the
|
|
16
|
+
* same way the studio-server executor adds them, so a preview renders what an execution would.
|
|
17
|
+
* `_model` is only set when the caller passes `system.model` or the data already carries it.
|
|
20
18
|
*
|
|
21
19
|
* For `TemplateType.text`, the content is returned verbatim — it is static text, not a
|
|
22
20
|
* template — matching the studio-server executor (see `apps/studio-server/src/executor/
|
|
23
21
|
* rendering/template.ts`). Routing it through the JST evaluator would compile the prose as
|
|
24
22
|
* JavaScript and throw on any plain sentence (e.g. "You are a helpful assistant.").
|
|
25
23
|
*/
|
|
26
|
-
export declare function renderTemplate(code: string, contentType: TemplateType, schema: JSONSchema, data: JSONObject): string;
|
|
24
|
+
export declare function renderTemplate(code: string, contentType: TemplateType, schema: JSONSchema, data: JSONObject, system?: TemplateSystemContext): string;
|
|
27
25
|
/**
|
|
28
26
|
* Execute a JST (JavaScript Template) with given data.
|
|
29
27
|
* Returns a discriminated union to surface errors without throwing.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/prompts/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,KAAK,gBAAgB,EAAwB,KAAK,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/prompts/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,KAAK,gBAAgB,EAAwB,KAAK,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAClH,OAAO,EAIH,KAAK,qBAAqB,EAE7B,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,cAAc;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC1B,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAChB,MAAM,CAAC,EAAE,qBAAqB,GAC/B,MAAM,CASR;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,GACjB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAOxE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC7B,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,GACjB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAOxE;AAqCD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,GAAG,cAAc,EAAE,CAU/G;AAED,wBAAgB,sBAAsB,CAClC,QAAQ,EAAE,gBAAgB,CAAC,cAAc,CAAC,EAAE,EAC5C,YAAY,EAAE,MAAM,GAAG,UAAU,GAClC,cAAc,EAAE,CAsBlB;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,CAAC,cAAc,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,aAAa,EAAE,CAwB/G"}
|
package/lib/prompts/render.js
CHANGED
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
import { PromptSegmentDefType, TemplateType } from '@vertesia/common';
|
|
2
|
-
import { CompositeError, renderHandlebarsTemplate, renderJsTemplate } from '@vertesia/jst';
|
|
2
|
+
import { CompositeError, renderHandlebarsTemplate, renderJsTemplate, withTemplateSystemVariables, } from '@vertesia/jst';
|
|
3
3
|
/**
|
|
4
4
|
* Render a prompt template with the given input data.
|
|
5
5
|
*
|
|
6
|
-
* Handlebars templates use {{variable}} interpolation against `data`.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* studio-server executor
|
|
10
|
-
*
|
|
11
|
-
* and `apps/studio-server/src/executor/rendering/template.ts`). Listing it here keeps
|
|
12
|
-
* the Playground preview and `validatePrompt` in sync with runtime resolution — a JST
|
|
13
|
-
* template referencing `_model` validates fine here and renders fine in production.
|
|
6
|
+
* Handlebars templates use {{variable}} interpolation against `data`. JST (JavaScript template)
|
|
7
|
+
* bodies evaluate against `data` with the schema's top-level property names exposed as globals.
|
|
8
|
+
* Both see the system variables (`TEMPLATE_SYSTEM_VARIABLES` in `@vertesia/jst`), added here the
|
|
9
|
+
* same way the studio-server executor adds them, so a preview renders what an execution would.
|
|
10
|
+
* `_model` is only set when the caller passes `system.model` or the data already carries it.
|
|
14
11
|
*
|
|
15
12
|
* For `TemplateType.text`, the content is returned verbatim — it is static text, not a
|
|
16
13
|
* template — matching the studio-server executor (see `apps/studio-server/src/executor/
|
|
17
14
|
* rendering/template.ts`). Routing it through the JST evaluator would compile the prose as
|
|
18
15
|
* JavaScript and throw on any plain sentence (e.g. "You are a helpful assistant.").
|
|
19
16
|
*/
|
|
20
|
-
export function renderTemplate(code, contentType, schema, data) {
|
|
21
|
-
if (contentType === TemplateType.handlebars) {
|
|
22
|
-
return renderHandlebarsTemplate(code, data);
|
|
23
|
-
}
|
|
17
|
+
export function renderTemplate(code, contentType, schema, data, system) {
|
|
24
18
|
if (contentType === TemplateType.text) {
|
|
25
19
|
return code;
|
|
26
20
|
}
|
|
27
|
-
const
|
|
28
|
-
|
|
21
|
+
const input = withTemplateSystemVariables(data, system);
|
|
22
|
+
if (contentType === TemplateType.handlebars) {
|
|
23
|
+
return renderHandlebarsTemplate(code, input);
|
|
24
|
+
}
|
|
25
|
+
return renderJsTemplate(code, schema.properties ? Object.keys(schema.properties) : [], input);
|
|
29
26
|
}
|
|
30
27
|
/**
|
|
31
28
|
* Execute a JST (JavaScript Template) with given data.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/prompts/render.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,oBAAoB,EAAuB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAClH,OAAO,
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/prompts/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type JSONSchema, TemplateType } from '@vertesia/common';
|
|
2
|
-
export type PromptValidationIssueType = 'undeclared_template_variable' | 'unused_schema_variable' | 'handlebars_render_error' | 'jst_unsafe_construct' | 'jst_render_error';
|
|
2
|
+
export type PromptValidationIssueType = 'undeclared_template_variable' | 'unused_schema_variable' | 'reserved_variable_declared' | 'system_variable_property_access' | 'helper_used_as_value' | 'helper_missing_arguments' | 'handlebars_render_error' | 'jst_unsafe_construct' | 'jst_render_error';
|
|
3
3
|
export type PromptValidationIssueSeverity = 'error' | 'warning';
|
|
4
4
|
export interface PromptValidationIssue {
|
|
5
5
|
/** Discriminator for issue kind */
|
|
@@ -32,9 +32,15 @@ export interface PromptValidationInput {
|
|
|
32
32
|
*
|
|
33
33
|
* For `handlebars` and `jst` templates, the following checks are performed:
|
|
34
34
|
* 1. Every variable referenced in the template must be declared as a top-level property
|
|
35
|
-
* in `inputSchema.properties` (else → `undeclared_template_variable` error).
|
|
35
|
+
* in `inputSchema.properties` (else → `undeclared_template_variable` error). System variables
|
|
36
|
+
* (`TEMPLATE_SYSTEM_VARIABLES` in `@vertesia/jst`) are supplied at runtime and need no declaration;
|
|
37
|
+
* declaring one → `reserved_variable_declared` warning, reading a property of one →
|
|
38
|
+
* `system_variable_property_access` error.
|
|
36
39
|
* 2. Every property declared in `inputSchema.properties` should be referenced by the template
|
|
37
40
|
* (else → `unused_schema_variable` warning — non-blocking).
|
|
41
|
+
* For Handlebars only: a helper passed as an argument (`{{#if stringify}}`) →
|
|
42
|
+
* `helper_used_as_value` error; a helper called bare without the arguments it needs
|
|
43
|
+
* (`{{stringify}}`) → `helper_missing_arguments` error.
|
|
38
44
|
* 3. The template must render successfully against schema-derived mock data
|
|
39
45
|
* (else → `handlebars_render_error` / `jst_render_error` error).
|
|
40
46
|
* 4. For JST only: unsafe constructs (`with`, `for`, `while`, `import`, class, `this`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/prompts/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/prompts/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAcjE,MAAM,MAAM,yBAAyB,GAC/B,8BAA8B,GAC9B,wBAAwB,GACxB,4BAA4B,GAC5B,iCAAiC,GACjC,sBAAsB,GACtB,0BAA0B,GAC1B,yBAAyB,GACzB,sBAAsB,GACtB,kBAAkB,CAAC;AAEzB,MAAM,MAAM,6BAA6B,GAAG,OAAO,GAAG,SAAS,CAAC;AAEhE,MAAM,WAAW,qBAAqB;IAClC,mCAAmC;IACnC,IAAI,EAAE,yBAAyB,CAAC;IAChC,uEAAuE;IACvE,QAAQ,EAAE,6BAA6B,CAAC;IACxC,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACnC,2FAA2F;IAC3F,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IAClC,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,WAAW,EAAE,YAAY,CAAC;IAC1B,gEAAgE;IAChE,WAAW,CAAC,EAAE,UAAU,CAAC;CAC5B;AAyLD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAWnF"}
|