@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.
Files changed (47) hide show
  1. package/lib/index.d.ts +2 -1
  2. package/lib/index.d.ts.map +1 -1
  3. package/lib/index.js +4 -1
  4. package/lib/index.js.map +1 -1
  5. package/lib/prompts/extract-vars.d.ts +44 -12
  6. package/lib/prompts/extract-vars.d.ts.map +1 -1
  7. package/lib/prompts/extract-vars.js +165 -78
  8. package/lib/prompts/extract-vars.js.map +1 -1
  9. package/lib/prompts/render.d.ts +7 -9
  10. package/lib/prompts/render.d.ts.map +1 -1
  11. package/lib/prompts/render.js +12 -15
  12. package/lib/prompts/render.js.map +1 -1
  13. package/lib/prompts/validate.d.ts +8 -2
  14. package/lib/prompts/validate.d.ts.map +1 -1
  15. package/lib/prompts/validate.js +87 -51
  16. package/lib/prompts/validate.js.map +1 -1
  17. package/lib/roles/agent-runs.d.ts +8 -0
  18. package/lib/roles/agent-runs.d.ts.map +1 -0
  19. package/lib/roles/agent-runs.js +36 -0
  20. package/lib/roles/agent-runs.js.map +1 -0
  21. package/lib/roles/classes.d.ts +15 -1
  22. package/lib/roles/classes.d.ts.map +1 -1
  23. package/lib/roles/classes.js +10 -1
  24. package/lib/roles/classes.js.map +1 -1
  25. package/lib/roles/content.d.ts.map +1 -1
  26. package/lib/roles/content.js +14 -4
  27. package/lib/roles/content.js.map +1 -1
  28. package/lib/roles/index.d.ts +4 -3
  29. package/lib/roles/index.d.ts.map +1 -1
  30. package/lib/roles/index.js +7 -5
  31. package/lib/roles/index.js.map +1 -1
  32. package/lib/vertesia-studio-utils.js +2 -1
  33. package/lib/vertesia-studio-utils.js.map +1 -1
  34. package/package.json +11 -10
  35. package/src/index.ts +20 -1
  36. package/src/prompts/extract-vars.ts +212 -71
  37. package/src/prompts/render.ts +24 -15
  38. package/src/prompts/validate.ts +113 -57
  39. package/src/roles/agent-runs.ts +41 -0
  40. package/src/roles/classes.ts +7 -0
  41. package/src/roles/content.ts +21 -5
  42. package/src/roles/index.ts +7 -5
  43. package/src/apps/index.test.ts +0 -166
  44. package/src/conditions/match.test.ts +0 -134
  45. package/src/prompts/render.test.ts +0 -110
  46. package/src/prompts/validate.test.ts +0 -309
  47. 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';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,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"}
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,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,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
+ {"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
- * Extract the set of root-level variable names referenced by a Handlebars template.
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
- * - `{{foo}}` → `foo`
5
- * - `{{obj.bar.baz}}` → `obj` (only the root identifier; nested access doesn't add `bar` or `baz`)
6
- * - `{{#if cond}}{{name}}{{/if}}` → `cond`, `name`
7
- * - `{{#each items as |item|}}{{item.name}}{{/each}}` → `items` (NOT `item` — bound by `as |item|`)
8
- * - `{{lookup obj key}}` → `obj`, `key` (helper name skipped)
9
- * - `{{@index}}`, `{{this}}` → ignored (built-in data vars / self)
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
- * Helper names in mustaches and block heads (`{{customHelper x}}`, `{{#if x}}`) are NOT added to
12
- * the set — only the arguments and inner template references are. This matches the typical use
13
- * case for prompt validation: detect which schema properties the template actually reads.
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 — callers should also run a syntactic render check
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":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA6FxE"}
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
- * Extract the set of root-level variable names referenced by a Handlebars template.
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
- * Helper names in mustaches and block heads (`{{customHelper x}}`, `{{#if x}}`) are NOT added to
13
- * the set — only the arguments and inner template references are. This matches the typical use
14
- * case for prompt validation: detect which schema properties the template actually reads.
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 an empty set on parse failure — callers should also run a syntactic render check
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 extractHandlebarsVariables(template) {
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 new Set();
41
+ return null;
26
42
  }
27
- const variables = new Set();
28
- const localScopes = [];
29
- const isLocal = (name) => localScopes.some((scope) => scope.has(name));
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 body = n.body;
37
- if (body)
38
- for (const stmt of body)
39
- visit(stmt);
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
- // n.path is the helper name (`#if`, `#each`, `#customBlock`) — never a variable.
44
- // Visit params + hash to capture variables passed to the block helper.
45
- const params = n.params;
46
- if (params)
47
- for (const p of params)
48
- visit(p);
49
- visit(n.hash);
50
- // Track `as |x y|` block params — these are local bindings, not variables.
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
- const scope = new Set([...(program?.blockParams ?? []), ...(inverse?.blockParams ?? [])]);
54
- localScopes.push(scope);
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
- localScopes.pop();
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 arg1 arg2) — helper name in path is skipped, args carry variables.
80
- const params = n.params;
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
- case 'PathExpression': {
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 variables;
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":"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"}
1
+ {"version":3,"file":"extract-vars.js","sourceRoot":"","sources":["../../src/prompts/extract-vars.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,UAAU,MAAM,YAAY,CAAC;AA+CpC,SAAS,MAAM,CAAC,IAAa;IACzB,OAAO,CAAC,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAK,IAAa,CAAC,IAAI,KAAK,gBAAgB,CAAC;AAC1F,CAAC;AAED,wGAAwG;AACxG,SAAS,QAAQ,CAAC,IAAc;IAC5B,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED,mFAAmF;AACnF,SAAS,UAAU,CAAC,IAAc;IAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;AACxF,CAAC;AAED,SAAS,WAAW,CAAC,QAAgB;IACjC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAAgB;IACtD,IAAI,GAAoB,CAAC;IACzB,IAAI,CAAC;QACD,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,CAAC,GAA+B,EAAU,EAAE;QACtD,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;QACpE,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1C,IAAI,GAAG,GAAG,CAAC;YAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC;IAEF,MAAM,UAAU,GAAkC,EAAE,CAAC;IACrD,MAAM,aAAa,GAA6B,EAAE,CAAC;IACnD,MAAM,QAAQ,GAAkB,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,WAAW,GAAuB,EAAE,CAAC;IAC3C,IAAI,GAAG,GAAG,EAAE,CAAC;IAEb,MAAM,YAAY,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAE7F,gEAAgE;IAChE,MAAM,QAAQ,GAAG,CAAC,IAAc,EAAQ,EAAE;QACtC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,4EAA4E;YAC5E,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpD,UAAU,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;oBACnB,UAAU,EAAE,IAAI,CAAC,QAAQ;oBACzB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;oBAC9B,GAAG;iBACN,CAAC,CAAC;YACP,CAAC;YACD,OAAO;QACX,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,eAAe;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC;YAAE,OAAO;QACtE,gEAAgE;QAChE,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,IAAI,OAAO,KAAK,MAAM;YAAE,OAAO;QAC/B,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACpG,CAAC,CAAC;IAEF,sGAAsG;IACtG,MAAM,aAAa,GAAG,CAAC,IAAa,EAAQ,EAAE;QAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC3B,2EAA2E;YAC3E,IACI,UAAU,CAAC,IAAI,CAAC;gBAChB,CAAC,YAAY,CAAC,IAAI,CAAC;gBACnB,kBAAkB,CAAC,IAAI,CAAC;gBACxB,CAAC,wBAAwB,CAAC,IAAI,CAAC,EACjC,CAAC;gBACC,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;gBACpE,OAAO;YACX,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,OAAO;QACX,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,CAAC,CAAO,EAAQ,EAAE;QAChC,MAAM,MAAM,GAAI,CAAC,CAAC,MAAgC,IAAI,EAAE,CAAC;QACzD,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,aAAa,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,KAAK,GAAI,CAAC,CAAC,IAA0D,EAAE,KAAK,IAAI,EAAE,CAAC;QACzF,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,CAAO,EAAW,EAAE,CACtC,CAAE,CAAC,CAAC,MAAgC,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;QACtD,CAAE,CAAC,CAAC,IAA0C,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAE5E,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QAClC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO;QAC9C,MAAM,CAAC,GAAG,IAAY,CAAC;QAEvB,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACb,KAAK,SAAS,EAAE,CAAC;gBACb,KAAK,MAAM,IAAI,IAAK,CAAC,CAAC,IAA8B,IAAI,EAAE;oBAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBACxE,MAAM;YACV,CAAC;YAED,KAAK,mBAAmB,EAAE,CAAC;gBACvB,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACnB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;gBACpB,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;oBAClB,sFAAsF;oBACtF,SAAS,CAAC,CAAC,CAAC,CAAC;gBACjB,CAAC;qBAAM,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtB,oFAAoF;oBACpF,sFAAsF;oBACtF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC3B,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;wBACtE,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC;4BAClC,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;wBAC5E,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACJ,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACnB,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC;gBACD,MAAM;YACV,CAAC;YAED,KAAK,gBAAgB,EAAE,CAAC;gBACpB,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACnB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;gBACpB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC5E,IAAI,WAAoB,CAAC;gBACzB,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;oBAC5D,SAAS,CAAC,CAAC,CAAC,CAAC;oBACb,WAAW,GAAG,CAAC,CAAC,MAAM,IAAI,0BAA0B,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAC1E,CAAC;qBAAM,CAAC;oBACJ,uEAAuE;oBACvE,IAAI,MAAM,CAAC,IAAI,CAAC;wBAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACjC,WAAW,GAAG,IAAI,CAAC;gBACvB,CAAC;gBAED,MAAM,OAAO,GAAG,CAAC,CAAC,OAAiD,CAAC;gBACpE,MAAM,OAAO,GAAG,CAAC,CAAC,OAAiD,CAAC;gBACpE,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;gBACtD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gBACpE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBACjB,QAAQ,CAAC,GAAG,EAAE,CAAC;gBACf,WAAW,CAAC,GAAG,EAAE,CAAC;gBAElB,iDAAiD;gBACjD,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;gBACtD,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBACjB,WAAW,CAAC,GAAG,EAAE,CAAC;gBAClB,MAAM;YACV,CAAC;YAED,KAAK,eAAe,EAAE,CAAC;gBACnB,gEAAgE;gBAChE,SAAS,CAAC,CAAC,CAAC,CAAC;gBACb,MAAM;YACV,CAAC;YAED,yEAAyE;YACzE;gBACI,MAAM;QACd,CAAC;IACL,CAAC,CAAC;IAEF,KAAK,CAAC,GAAG,CAAC,CAAC;IACX,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;AACzC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IACvD,MAAM,QAAQ,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IACrD,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAClE,CAAC"}
@@ -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
- * JST (JavaScript template) bodies evaluate against `data` with the schema's top-level
14
- * property names exposed as globals, plus `_model` — the active model id, which the
15
- * studio-server executor injects into the input as `{ ..._model: run.modelId }` when
16
- * executing an interaction (see `apps/studio-server/src/executor/ExecutionRequest.ts`
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;AAGlH,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;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CASpH;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"}
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"}
@@ -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
- * JST (JavaScript template) bodies evaluate against `data` with the schema's top-level
8
- * property names exposed as globals, plus `_model` — the active model id, which the
9
- * studio-server executor injects into the input as `{ ..._model: run.modelId }` when
10
- * executing an interaction (see `apps/studio-server/src/executor/ExecutionRequest.ts`
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 globals = [...(schema.properties ? Object.keys(schema.properties) : []), '_model'];
28
- return renderJsTemplate(code, globals, data);
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":"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"}
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;AAMjE,MAAM,MAAM,yBAAyB,GAC/B,8BAA8B,GAC9B,wBAAwB,GACxB,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;AAmJD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAWnF"}
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"}