@goreal-ai/echo-pdk 0.1.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/dist/ai-judge/index.d.ts +177 -0
- package/dist/ai-judge/index.d.ts.map +1 -0
- package/dist/ai-judge/index.js +299 -0
- package/dist/ai-judge/index.js.map +1 -0
- package/dist/evaluator/evaluator.d.ts +136 -0
- package/dist/evaluator/evaluator.d.ts.map +1 -0
- package/dist/evaluator/evaluator.js +407 -0
- package/dist/evaluator/evaluator.js.map +1 -0
- package/dist/evaluator/index.d.ts +7 -0
- package/dist/evaluator/index.d.ts.map +1 -0
- package/dist/evaluator/index.js +8 -0
- package/dist/evaluator/index.js.map +1 -0
- package/dist/evaluator/operators.d.ts +105 -0
- package/dist/evaluator/operators.d.ts.map +1 -0
- package/dist/evaluator/operators.js +371 -0
- package/dist/evaluator/operators.js.map +1 -0
- package/dist/index.d.ts +115 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +388 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/ast.d.ts +106 -0
- package/dist/parser/ast.d.ts.map +1 -0
- package/dist/parser/ast.js +260 -0
- package/dist/parser/ast.js.map +1 -0
- package/dist/parser/index.d.ts +8 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +13 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/lexer.d.ts +199 -0
- package/dist/parser/lexer.d.ts.map +1 -0
- package/dist/parser/lexer.js +491 -0
- package/dist/parser/lexer.js.map +1 -0
- package/dist/parser/parser.d.ts +49 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/parser/parser.js +615 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/plugins/index.d.ts +62 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +170 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/renderer/index.d.ts +6 -0
- package/dist/renderer/index.d.ts.map +1 -0
- package/dist/renderer/index.js +5 -0
- package/dist/renderer/index.js.map +1 -0
- package/dist/renderer/renderer.d.ts +97 -0
- package/dist/renderer/renderer.d.ts.map +1 -0
- package/dist/renderer/renderer.js +243 -0
- package/dist/renderer/renderer.js.map +1 -0
- package/dist/types.d.ts +255 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Plugin System - Load and manage Echo plugins
|
|
3
|
+
*
|
|
4
|
+
* This module handles loading and registering plugins for Echo.
|
|
5
|
+
* Plugins can add custom operators, validators, and transformations.
|
|
6
|
+
*
|
|
7
|
+
* IMPLEMENTATION GUIDE:
|
|
8
|
+
*
|
|
9
|
+
* 1. PLUGIN LOADING
|
|
10
|
+
* - Load from npm packages: @goreal-ai/echo-pdk-validators
|
|
11
|
+
* - Load from local paths: ./plugins/my-plugin.ts
|
|
12
|
+
* - Validate plugin structure
|
|
13
|
+
*
|
|
14
|
+
* 2. OPERATOR REGISTRATION
|
|
15
|
+
* - Merge plugin operators with built-ins
|
|
16
|
+
* - Handle conflicts (plugin can override built-in)
|
|
17
|
+
*
|
|
18
|
+
* 3. LIFECYCLE HOOKS
|
|
19
|
+
* - onLoad: Called when plugin is loaded
|
|
20
|
+
* - Future: onRender, onValidate, etc.
|
|
21
|
+
*/
|
|
22
|
+
import type { EchoPlugin, OperatorDefinition } from '../types.js';
|
|
23
|
+
/**
|
|
24
|
+
* Plugin registry managing all loaded plugins.
|
|
25
|
+
*/
|
|
26
|
+
export interface PluginRegistry {
|
|
27
|
+
/** All loaded plugins */
|
|
28
|
+
plugins: EchoPlugin[];
|
|
29
|
+
/** Merged operator definitions from all plugins */
|
|
30
|
+
operators: Map<string, OperatorDefinition>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a new plugin registry.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createPluginRegistry(): PluginRegistry;
|
|
36
|
+
/**
|
|
37
|
+
* Load a plugin into the registry.
|
|
38
|
+
*
|
|
39
|
+
* @param registry - The plugin registry
|
|
40
|
+
* @param plugin - The plugin to load
|
|
41
|
+
*/
|
|
42
|
+
export declare function loadPlugin(registry: PluginRegistry, plugin: EchoPlugin): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Load a plugin from a path (npm package or local file).
|
|
45
|
+
*
|
|
46
|
+
* @param registry - The plugin registry
|
|
47
|
+
* @param path - Path to the plugin
|
|
48
|
+
*/
|
|
49
|
+
export declare function loadPluginFromPath(_registry: PluginRegistry, path: string): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Validate a plugin structure.
|
|
52
|
+
*
|
|
53
|
+
* @param plugin - The plugin to validate
|
|
54
|
+
* @throws If the plugin is invalid
|
|
55
|
+
*/
|
|
56
|
+
export declare function validatePlugin(plugin: unknown): asserts plugin is EchoPlugin;
|
|
57
|
+
/**
|
|
58
|
+
* Helper function for creating plugins with type safety.
|
|
59
|
+
* Re-exported from main index.ts
|
|
60
|
+
*/
|
|
61
|
+
export declare function definePlugin(plugin: EchoPlugin): EchoPlugin;
|
|
62
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAMlE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,yBAAyB;IACzB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,mDAAmD;IACnD,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CAC5C;AAMD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAKrD;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,cAAc,EACzB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAiBf;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,IAAI,UAAU,CAyB5E;AA+BD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAI3D"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Plugin System - Load and manage Echo plugins
|
|
3
|
+
*
|
|
4
|
+
* This module handles loading and registering plugins for Echo.
|
|
5
|
+
* Plugins can add custom operators, validators, and transformations.
|
|
6
|
+
*
|
|
7
|
+
* IMPLEMENTATION GUIDE:
|
|
8
|
+
*
|
|
9
|
+
* 1. PLUGIN LOADING
|
|
10
|
+
* - Load from npm packages: @goreal-ai/echo-pdk-validators
|
|
11
|
+
* - Load from local paths: ./plugins/my-plugin.ts
|
|
12
|
+
* - Validate plugin structure
|
|
13
|
+
*
|
|
14
|
+
* 2. OPERATOR REGISTRATION
|
|
15
|
+
* - Merge plugin operators with built-ins
|
|
16
|
+
* - Handle conflicts (plugin can override built-in)
|
|
17
|
+
*
|
|
18
|
+
* 3. LIFECYCLE HOOKS
|
|
19
|
+
* - onLoad: Called when plugin is loaded
|
|
20
|
+
* - Future: onRender, onValidate, etc.
|
|
21
|
+
*/
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// PLUGIN REGISTRY
|
|
24
|
+
// =============================================================================
|
|
25
|
+
/**
|
|
26
|
+
* Create a new plugin registry.
|
|
27
|
+
*/
|
|
28
|
+
export function createPluginRegistry() {
|
|
29
|
+
return {
|
|
30
|
+
plugins: [],
|
|
31
|
+
operators: new Map(),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Load a plugin into the registry.
|
|
36
|
+
*
|
|
37
|
+
* @param registry - The plugin registry
|
|
38
|
+
* @param plugin - The plugin to load
|
|
39
|
+
*/
|
|
40
|
+
export async function loadPlugin(registry, plugin) {
|
|
41
|
+
// Validate plugin structure
|
|
42
|
+
validatePlugin(plugin);
|
|
43
|
+
// Register operators
|
|
44
|
+
if (plugin.operators) {
|
|
45
|
+
for (const [name, definition] of Object.entries(plugin.operators)) {
|
|
46
|
+
registry.operators.set(name, definition);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Call onLoad hook
|
|
50
|
+
if (plugin.onLoad) {
|
|
51
|
+
await plugin.onLoad();
|
|
52
|
+
}
|
|
53
|
+
// Add to registry
|
|
54
|
+
registry.plugins.push(plugin);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Load a plugin from a path (npm package or local file).
|
|
58
|
+
*
|
|
59
|
+
* @param registry - The plugin registry
|
|
60
|
+
* @param path - Path to the plugin
|
|
61
|
+
*/
|
|
62
|
+
export async function loadPluginFromPath(_registry, path) {
|
|
63
|
+
// TODO: Implement plugin loading from path
|
|
64
|
+
//
|
|
65
|
+
// IMPLEMENTATION:
|
|
66
|
+
//
|
|
67
|
+
// 1. DETERMINE PATH TYPE
|
|
68
|
+
// - If starts with @, ., or / -> resolve as module path
|
|
69
|
+
// - Otherwise -> resolve as npm package
|
|
70
|
+
//
|
|
71
|
+
// 2. DYNAMIC IMPORT
|
|
72
|
+
// const module = await import(resolvedPath);
|
|
73
|
+
// const plugin = module.default;
|
|
74
|
+
//
|
|
75
|
+
// 3. LOAD PLUGIN
|
|
76
|
+
// await loadPlugin(registry, plugin);
|
|
77
|
+
throw new Error(`Plugin loading not implemented: ${path}`);
|
|
78
|
+
}
|
|
79
|
+
// =============================================================================
|
|
80
|
+
// VALIDATION
|
|
81
|
+
// =============================================================================
|
|
82
|
+
/**
|
|
83
|
+
* Validate a plugin structure.
|
|
84
|
+
*
|
|
85
|
+
* @param plugin - The plugin to validate
|
|
86
|
+
* @throws If the plugin is invalid
|
|
87
|
+
*/
|
|
88
|
+
export function validatePlugin(plugin) {
|
|
89
|
+
if (!plugin || typeof plugin !== 'object') {
|
|
90
|
+
throw new Error('Plugin must be an object');
|
|
91
|
+
}
|
|
92
|
+
const p = plugin;
|
|
93
|
+
if (typeof p.name !== 'string' || p.name.length === 0) {
|
|
94
|
+
throw new Error('Plugin must have a name');
|
|
95
|
+
}
|
|
96
|
+
if (typeof p.version !== 'string') {
|
|
97
|
+
throw new Error('Plugin must have a version');
|
|
98
|
+
}
|
|
99
|
+
if (p.operators !== undefined) {
|
|
100
|
+
if (typeof p.operators !== 'object') {
|
|
101
|
+
throw new Error('Plugin operators must be an object');
|
|
102
|
+
}
|
|
103
|
+
// Validate each operator
|
|
104
|
+
for (const [name, def] of Object.entries(p.operators)) {
|
|
105
|
+
validateOperatorDefinition(name, def);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Validate an operator definition.
|
|
111
|
+
*/
|
|
112
|
+
function validateOperatorDefinition(name, def) {
|
|
113
|
+
if (!def || typeof def !== 'object') {
|
|
114
|
+
throw new Error(`Operator ${name} must be an object`);
|
|
115
|
+
}
|
|
116
|
+
const d = def;
|
|
117
|
+
if (!['comparison', 'unary', 'ai'].includes(d.type)) {
|
|
118
|
+
throw new Error(`Operator ${name} must have type: comparison, unary, or ai`);
|
|
119
|
+
}
|
|
120
|
+
if (typeof d.handler !== 'function') {
|
|
121
|
+
throw new Error(`Operator ${name} must have a handler function`);
|
|
122
|
+
}
|
|
123
|
+
if (typeof d.description !== 'string') {
|
|
124
|
+
throw new Error(`Operator ${name} must have a description`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// =============================================================================
|
|
128
|
+
// PLUGIN CREATION HELPER
|
|
129
|
+
// =============================================================================
|
|
130
|
+
/**
|
|
131
|
+
* Helper function for creating plugins with type safety.
|
|
132
|
+
* Re-exported from main index.ts
|
|
133
|
+
*/
|
|
134
|
+
export function definePlugin(plugin) {
|
|
135
|
+
// Validate at definition time
|
|
136
|
+
validatePlugin(plugin);
|
|
137
|
+
return plugin;
|
|
138
|
+
}
|
|
139
|
+
// =============================================================================
|
|
140
|
+
// IMPLEMENTATION NOTES
|
|
141
|
+
// =============================================================================
|
|
142
|
+
/*
|
|
143
|
+
NEXT STEPS TO IMPLEMENT:
|
|
144
|
+
|
|
145
|
+
1. PATH RESOLUTION
|
|
146
|
+
- Handle npm packages (@goreal-ai/echo-pdk-foo)
|
|
147
|
+
- Handle relative paths (./foo)
|
|
148
|
+
- Handle absolute paths (/path/to/foo)
|
|
149
|
+
|
|
150
|
+
2. HOT RELOADING (FUTURE)
|
|
151
|
+
For development mode, support reloading plugins without restart.
|
|
152
|
+
|
|
153
|
+
3. PLUGIN DISCOVERY
|
|
154
|
+
- Scan node_modules for echo-pdk plugins
|
|
155
|
+
- Read from echo.config.yaml
|
|
156
|
+
|
|
157
|
+
4. LIFECYCLE HOOKS
|
|
158
|
+
Add more hooks:
|
|
159
|
+
- onValidate: Custom validation rules
|
|
160
|
+
- onBeforeRender: Transform AST before render
|
|
161
|
+
- onAfterRender: Transform output after render
|
|
162
|
+
|
|
163
|
+
5. TESTS
|
|
164
|
+
Create plugins.test.ts with tests for:
|
|
165
|
+
- Plugin validation
|
|
166
|
+
- Operator registration
|
|
167
|
+
- Path loading
|
|
168
|
+
- Lifecycle hooks
|
|
169
|
+
*/
|
|
170
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Echo Renderer - AST to text output
|
|
3
|
+
*
|
|
4
|
+
* This file implements the renderer for Echo DSL.
|
|
5
|
+
* The renderer traverses the evaluated AST and produces the final text output.
|
|
6
|
+
*
|
|
7
|
+
* By the time the renderer runs:
|
|
8
|
+
* 1. All conditions have been evaluated
|
|
9
|
+
* 2. Only the nodes that should be rendered are in the AST
|
|
10
|
+
* 3. AI judges have been resolved
|
|
11
|
+
*
|
|
12
|
+
* The renderer's job is to:
|
|
13
|
+
* 1. Walk the AST
|
|
14
|
+
* 2. For text nodes: output the text as-is
|
|
15
|
+
* 3. For variable nodes: substitute the value from context
|
|
16
|
+
* 4. Preserve whitespace (prompts are whitespace-sensitive)
|
|
17
|
+
*/
|
|
18
|
+
import type { ASTNode, EchoConfig, OperatorDefinition } from '../types.js';
|
|
19
|
+
/**
|
|
20
|
+
* Options for the renderer.
|
|
21
|
+
*/
|
|
22
|
+
export interface RenderOptions {
|
|
23
|
+
/** Variable context */
|
|
24
|
+
context: Record<string, unknown>;
|
|
25
|
+
/** Echo configuration */
|
|
26
|
+
config?: EchoConfig;
|
|
27
|
+
/** Trim leading/trailing whitespace from output */
|
|
28
|
+
trim?: boolean;
|
|
29
|
+
/** Collapse multiple newlines into one */
|
|
30
|
+
collapseNewlines?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Render an evaluated AST to a string.
|
|
34
|
+
*
|
|
35
|
+
* @param ast - The evaluated AST nodes
|
|
36
|
+
* @param options - Render options
|
|
37
|
+
* @returns The rendered string
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const output = render(evaluatedAst, {
|
|
42
|
+
* context: { name: 'Alice' },
|
|
43
|
+
* trim: true,
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function render(ast: ASTNode[], options: RenderOptions): string;
|
|
48
|
+
/**
|
|
49
|
+
* Full render pipeline: parse -> evaluate -> render.
|
|
50
|
+
*
|
|
51
|
+
* This is the main entry point for rendering a template.
|
|
52
|
+
*
|
|
53
|
+
* @param template - The Echo template string
|
|
54
|
+
* @param context - Variable context
|
|
55
|
+
* @param config - Echo configuration
|
|
56
|
+
* @param operators - Custom operators from plugins
|
|
57
|
+
* @returns The rendered string
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const output = await renderTemplate(
|
|
62
|
+
* 'Hello {{name}}!',
|
|
63
|
+
* { name: 'Alice' }
|
|
64
|
+
* );
|
|
65
|
+
* // Output: "Hello Alice!"
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const template = `
|
|
71
|
+
* [#IF {{tier}} #equals(premium)]
|
|
72
|
+
* Welcome, premium user!
|
|
73
|
+
* [ELSE]
|
|
74
|
+
* Upgrade to premium for more features.
|
|
75
|
+
* [END IF]
|
|
76
|
+
* `;
|
|
77
|
+
*
|
|
78
|
+
* const output = await renderTemplate(template, { tier: 'premium' });
|
|
79
|
+
* // Output: " Welcome, premium user!\n"
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function renderTemplate(template: string, context: Record<string, unknown>, config?: EchoConfig, operators?: Map<string, OperatorDefinition>): Promise<string>;
|
|
83
|
+
/**
|
|
84
|
+
* Format errors with source context for display.
|
|
85
|
+
*
|
|
86
|
+
* @param template - The original template
|
|
87
|
+
* @param errors - Parse or evaluation errors
|
|
88
|
+
* @returns Formatted error string
|
|
89
|
+
*/
|
|
90
|
+
export declare function formatErrors(template: string, errors: {
|
|
91
|
+
message: string;
|
|
92
|
+
location?: {
|
|
93
|
+
startLine: number;
|
|
94
|
+
startColumn: number;
|
|
95
|
+
};
|
|
96
|
+
}[]): string;
|
|
97
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/renderer/renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,OAAO,EAGP,UAAU,EACV,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAQrB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,yBAAyB;IACzB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,mDAAmD;IACnD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAsBrE;AAiID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,MAAM,GAAE,UAAe,EACvB,SAAS,GAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAa,GACrD,OAAO,CAAC,MAAM,CAAC,CAwBjB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAAE,GACnF,MAAM,CAwBR"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Echo Renderer - AST to text output
|
|
3
|
+
*
|
|
4
|
+
* This file implements the renderer for Echo DSL.
|
|
5
|
+
* The renderer traverses the evaluated AST and produces the final text output.
|
|
6
|
+
*
|
|
7
|
+
* By the time the renderer runs:
|
|
8
|
+
* 1. All conditions have been evaluated
|
|
9
|
+
* 2. Only the nodes that should be rendered are in the AST
|
|
10
|
+
* 3. AI judges have been resolved
|
|
11
|
+
*
|
|
12
|
+
* The renderer's job is to:
|
|
13
|
+
* 1. Walk the AST
|
|
14
|
+
* 2. For text nodes: output the text as-is
|
|
15
|
+
* 3. For variable nodes: substitute the value from context
|
|
16
|
+
* 4. Preserve whitespace (prompts are whitespace-sensitive)
|
|
17
|
+
*/
|
|
18
|
+
import { parse } from '../parser/parser.js';
|
|
19
|
+
import { evaluate, resolveVariable } from '../evaluator/evaluator.js';
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// RENDERER
|
|
22
|
+
// =============================================================================
|
|
23
|
+
/**
|
|
24
|
+
* Render an evaluated AST to a string.
|
|
25
|
+
*
|
|
26
|
+
* @param ast - The evaluated AST nodes
|
|
27
|
+
* @param options - Render options
|
|
28
|
+
* @returns The rendered string
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const output = render(evaluatedAst, {
|
|
33
|
+
* context: { name: 'Alice' },
|
|
34
|
+
* trim: true,
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function render(ast, options) {
|
|
39
|
+
const parts = [];
|
|
40
|
+
for (const node of ast) {
|
|
41
|
+
const rendered = renderNode(node, options);
|
|
42
|
+
if (rendered !== undefined) {
|
|
43
|
+
parts.push(rendered);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
let result = parts.join('');
|
|
47
|
+
// Apply post-processing
|
|
48
|
+
if (options.collapseNewlines) {
|
|
49
|
+
result = collapseNewlines(result);
|
|
50
|
+
}
|
|
51
|
+
if (options.trim) {
|
|
52
|
+
result = result.trim();
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Render a single AST node.
|
|
58
|
+
*
|
|
59
|
+
* @param node - The node to render
|
|
60
|
+
* @param options - Render options
|
|
61
|
+
* @returns The rendered string or undefined if nothing to render
|
|
62
|
+
*/
|
|
63
|
+
function renderNode(node, options) {
|
|
64
|
+
switch (node.type) {
|
|
65
|
+
case 'text':
|
|
66
|
+
return renderText(node);
|
|
67
|
+
case 'variable':
|
|
68
|
+
return renderVariable(node, options);
|
|
69
|
+
case 'conditional':
|
|
70
|
+
// By the time we render, conditionals should have been evaluated
|
|
71
|
+
// This shouldn't happen, but handle gracefully
|
|
72
|
+
return render(node.consequent, options);
|
|
73
|
+
case 'section':
|
|
74
|
+
// Section definitions are not rendered inline
|
|
75
|
+
// They're stored for [#INCLUDE] references
|
|
76
|
+
return undefined;
|
|
77
|
+
case 'import':
|
|
78
|
+
// Imports should be resolved before rendering
|
|
79
|
+
// If we see one here, it means it wasn't resolved
|
|
80
|
+
if (options.config?.strict) {
|
|
81
|
+
throw new Error(`Unresolved import: ${node.path}`);
|
|
82
|
+
}
|
|
83
|
+
return undefined;
|
|
84
|
+
case 'include':
|
|
85
|
+
// Includes should be resolved before rendering
|
|
86
|
+
if (options.config?.strict) {
|
|
87
|
+
throw new Error(`Unresolved include: ${node.name}`);
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
default: {
|
|
91
|
+
// Exhaustiveness check
|
|
92
|
+
const _exhaustive = node;
|
|
93
|
+
throw new Error(`Unknown node type: ${_exhaustive.type}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Render a text node.
|
|
99
|
+
*/
|
|
100
|
+
function renderText(node) {
|
|
101
|
+
return node.value;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Render a variable node.
|
|
105
|
+
*
|
|
106
|
+
* @param node - The variable node
|
|
107
|
+
* @param options - Render options
|
|
108
|
+
* @returns The variable value as string
|
|
109
|
+
*/
|
|
110
|
+
function renderVariable(node, options) {
|
|
111
|
+
const value = resolveVariable(node.path, options.context, {
|
|
112
|
+
strict: options.config?.strict,
|
|
113
|
+
});
|
|
114
|
+
// Handle undefined
|
|
115
|
+
if (value === undefined || value === null) {
|
|
116
|
+
// Use default value if provided
|
|
117
|
+
if (node.defaultValue !== undefined) {
|
|
118
|
+
return node.defaultValue;
|
|
119
|
+
}
|
|
120
|
+
// In strict mode, throw
|
|
121
|
+
if (options.config?.strict) {
|
|
122
|
+
throw new Error(`Undefined variable: ${node.path}`);
|
|
123
|
+
}
|
|
124
|
+
// Lenient mode: render empty string
|
|
125
|
+
return '';
|
|
126
|
+
}
|
|
127
|
+
// Convert to string
|
|
128
|
+
return stringify(value);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Convert a value to string for rendering.
|
|
132
|
+
*
|
|
133
|
+
* @param value - The value to stringify
|
|
134
|
+
* @returns String representation
|
|
135
|
+
*/
|
|
136
|
+
function stringify(value) {
|
|
137
|
+
if (typeof value === 'string') {
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
140
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
141
|
+
return String(value);
|
|
142
|
+
}
|
|
143
|
+
if (Array.isArray(value)) {
|
|
144
|
+
return value.map(stringify).join(', ');
|
|
145
|
+
}
|
|
146
|
+
if (typeof value === 'object' && value !== null) {
|
|
147
|
+
return JSON.stringify(value);
|
|
148
|
+
}
|
|
149
|
+
return String(value);
|
|
150
|
+
}
|
|
151
|
+
// =============================================================================
|
|
152
|
+
// POST-PROCESSING
|
|
153
|
+
// =============================================================================
|
|
154
|
+
/**
|
|
155
|
+
* Collapse multiple consecutive newlines into a maximum of two.
|
|
156
|
+
*
|
|
157
|
+
* This is useful for cleaning up output when conditionals
|
|
158
|
+
* leave empty lines.
|
|
159
|
+
*/
|
|
160
|
+
function collapseNewlines(text) {
|
|
161
|
+
return text.replace(/\n{3,}/g, '\n\n');
|
|
162
|
+
}
|
|
163
|
+
// =============================================================================
|
|
164
|
+
// FULL RENDER PIPELINE
|
|
165
|
+
// =============================================================================
|
|
166
|
+
/**
|
|
167
|
+
* Full render pipeline: parse -> evaluate -> render.
|
|
168
|
+
*
|
|
169
|
+
* This is the main entry point for rendering a template.
|
|
170
|
+
*
|
|
171
|
+
* @param template - The Echo template string
|
|
172
|
+
* @param context - Variable context
|
|
173
|
+
* @param config - Echo configuration
|
|
174
|
+
* @param operators - Custom operators from plugins
|
|
175
|
+
* @returns The rendered string
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* const output = await renderTemplate(
|
|
180
|
+
* 'Hello {{name}}!',
|
|
181
|
+
* { name: 'Alice' }
|
|
182
|
+
* );
|
|
183
|
+
* // Output: "Hello Alice!"
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* const template = `
|
|
189
|
+
* [#IF {{tier}} #equals(premium)]
|
|
190
|
+
* Welcome, premium user!
|
|
191
|
+
* [ELSE]
|
|
192
|
+
* Upgrade to premium for more features.
|
|
193
|
+
* [END IF]
|
|
194
|
+
* `;
|
|
195
|
+
*
|
|
196
|
+
* const output = await renderTemplate(template, { tier: 'premium' });
|
|
197
|
+
* // Output: " Welcome, premium user!\n"
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
export async function renderTemplate(template, context, config = {}, operators = new Map()) {
|
|
201
|
+
// Step 1: Parse the template to AST
|
|
202
|
+
const parseResult = parse(template);
|
|
203
|
+
if (!parseResult.success || !parseResult.ast) {
|
|
204
|
+
const formattedErrors = formatErrors(template, parseResult.errors);
|
|
205
|
+
throw new Error(`Parse error:\n${formattedErrors}`);
|
|
206
|
+
}
|
|
207
|
+
// Step 2: Evaluate the AST
|
|
208
|
+
const { ast: evaluatedAst } = await evaluate(parseResult.ast, context, config, operators);
|
|
209
|
+
// Step 3: Render the evaluated AST
|
|
210
|
+
return render(evaluatedAst, {
|
|
211
|
+
context,
|
|
212
|
+
config,
|
|
213
|
+
trim: false, // Preserve whitespace by default
|
|
214
|
+
collapseNewlines: true, // Clean up empty lines from conditionals
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Format errors with source context for display.
|
|
219
|
+
*
|
|
220
|
+
* @param template - The original template
|
|
221
|
+
* @param errors - Parse or evaluation errors
|
|
222
|
+
* @returns Formatted error string
|
|
223
|
+
*/
|
|
224
|
+
export function formatErrors(template, errors) {
|
|
225
|
+
const lines = template.split('\n');
|
|
226
|
+
const formatted = [];
|
|
227
|
+
for (const error of errors) {
|
|
228
|
+
formatted.push(`Error: ${error.message}`);
|
|
229
|
+
if (error.location) {
|
|
230
|
+
const { startLine, startColumn } = error.location;
|
|
231
|
+
const lineIndex = startLine - 1;
|
|
232
|
+
if (lineIndex >= 0 && lineIndex < lines.length) {
|
|
233
|
+
const sourceLine = lines[lineIndex];
|
|
234
|
+
const pointer = ' '.repeat(startColumn - 1) + '^';
|
|
235
|
+
formatted.push(` ${startLine} | ${sourceLine}`);
|
|
236
|
+
formatted.push(` | ${pointer}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
formatted.push('');
|
|
240
|
+
}
|
|
241
|
+
return formatted.join('\n');
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/renderer/renderer.ts"],"names":[],"mappings":"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"}
|