@garrix82/reactgenie-dsl 1.0.1 → 1.0.2

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 (104) hide show
  1. package/.env +10 -0
  2. package/.env.example +17 -0
  3. package/.github/workflows/publish.yml +20 -0
  4. package/package.json +1 -5
  5. package/dist/__test__/dsl-descriptor.test.d.ts +0 -1
  6. package/dist/__test__/dsl-descriptor.test.js +0 -27
  7. package/dist/__test__/dsl-descriptor.test.js.map +0 -1
  8. package/dist/__test__/example_descriptor.d.ts +0 -125
  9. package/dist/__test__/example_descriptor.js +0 -607
  10. package/dist/__test__/example_descriptor.js.map +0 -1
  11. package/dist/__test__/food_descriptor.state.json +0 -1
  12. package/dist/__test__/food_descriptor.test.d.ts +0 -74
  13. package/dist/__test__/food_descriptor.test.js +0 -205
  14. package/dist/__test__/food_descriptor.test.js.map +0 -1
  15. package/dist/__test__/nl-interpreter-provider-selection.test.d.ts +0 -1
  16. package/dist/__test__/nl-interpreter-provider-selection.test.js +0 -73
  17. package/dist/__test__/nl-interpreter-provider-selection.test.js.map +0 -1
  18. package/dist/__test__/nl-interpreter.test.d.ts +0 -1
  19. package/dist/__test__/nl-interpreter.test.js +0 -86
  20. package/dist/__test__/nl-interpreter.test.js.map +0 -1
  21. package/dist/decorators/__test__/decorators.test.d.ts +0 -1
  22. package/dist/decorators/__test__/decorators.test.js +0 -182
  23. package/dist/decorators/__test__/decorators.test.js.map +0 -1
  24. package/dist/decorators/__test__/inheritance-descriptor.test.d.ts +0 -1
  25. package/dist/decorators/__test__/inheritance-descriptor.test.js +0 -107
  26. package/dist/decorators/__test__/inheritance-descriptor.test.js.map +0 -1
  27. package/dist/dsl/__test__/dsl-interpreter.test.d.ts +0 -1
  28. package/dist/dsl/__test__/dsl-interpreter.test.js +0 -334
  29. package/dist/dsl/__test__/dsl-interpreter.test.js.map +0 -1
  30. package/dist/dsl/__test__/parser.gen.test.d.ts +0 -1
  31. package/dist/dsl/__test__/parser.gen.test.js +0 -283
  32. package/dist/dsl/__test__/parser.gen.test.js.map +0 -1
  33. package/dist/nl/__test__/context-aware-prompt.test.d.ts +0 -1
  34. package/dist/nl/__test__/context-aware-prompt.test.js +0 -247
  35. package/dist/nl/__test__/context-aware-prompt.test.js.map +0 -1
  36. package/dist/nl/__test__/context-selector.test.d.ts +0 -1
  37. package/dist/nl/__test__/context-selector.test.js +0 -20
  38. package/dist/nl/__test__/context-selector.test.js.map +0 -1
  39. package/dist/nl/__test__/nl-parser-groq-transport.test.d.ts +0 -1
  40. package/dist/nl/__test__/nl-parser-groq-transport.test.js +0 -87
  41. package/dist/nl/__test__/nl-parser-groq-transport.test.js.map +0 -1
  42. package/dist/nl/__test__/nl-parser-openai-parity.test.d.ts +0 -1
  43. package/dist/nl/__test__/nl-parser-openai-parity.test.js +0 -206
  44. package/dist/nl/__test__/nl-parser-openai-parity.test.js.map +0 -1
  45. package/dist/nl/__test__/nl-parser-openai-sampling.test.d.ts +0 -1
  46. package/dist/nl/__test__/nl-parser-openai-sampling.test.js +0 -44
  47. package/dist/nl/__test__/nl-parser-openai-sampling.test.js.map +0 -1
  48. package/dist/nl/__test__/nl-parser-openai-transport.test.d.ts +0 -1
  49. package/dist/nl/__test__/nl-parser-openai-transport.test.js +0 -55
  50. package/dist/nl/__test__/nl-parser-openai-transport.test.js.map +0 -1
  51. package/dist/nl/__test__/nl-parser-utils.test.d.ts +0 -1
  52. package/dist/nl/__test__/nl-parser-utils.test.js +0 -70
  53. package/dist/nl/__test__/nl-parser-utils.test.js.map +0 -1
  54. package/dist/nl/__test__/nl-parser.test.d.ts +0 -1
  55. package/dist/nl/__test__/nl-parser.test.js +0 -64
  56. package/dist/nl/__test__/nl-parser.test.js.map +0 -1
  57. package/dist/nl/__test__/parameter-tuning.test.d.ts +0 -1
  58. package/dist/nl/__test__/parameter-tuning.test.js +0 -95
  59. package/dist/nl/__test__/parameter-tuning.test.js.map +0 -1
  60. package/dist/nl/__test__/semantic-parsing-experiment.test.d.ts +0 -1
  61. package/dist/nl/__test__/semantic-parsing-experiment.test.js +0 -178
  62. package/dist/nl/__test__/semantic-parsing-experiment.test.js.map +0 -1
  63. package/dist/nl/llm-monitoring.test.d.ts +0 -5
  64. package/dist/nl/llm-monitoring.test.js +0 -101
  65. package/dist/nl/llm-monitoring.test.js.map +0 -1
  66. package/lib/__test__/dsl-descriptor.test.ts +0 -27
  67. package/lib/__test__/example_descriptor.ts +0 -762
  68. package/lib/__test__/food_descriptor.state.json +0 -1
  69. package/lib/__test__/food_descriptor.test.ts +0 -331
  70. package/lib/__test__/nl-interpreter-provider-selection.test.ts +0 -126
  71. package/lib/__test__/nl-interpreter.test.ts +0 -129
  72. package/lib/decorators/__test__/decorators.test.ts +0 -177
  73. package/lib/decorators/__test__/inheritance-descriptor.test.ts +0 -92
  74. package/lib/decorators/decorators.ts +0 -754
  75. package/lib/decorators/index.ts +0 -2
  76. package/lib/decorators/store.ts +0 -47
  77. package/lib/dsl/__test__/dsl-interpreter.test.ts +0 -453
  78. package/lib/dsl/__test__/parser.gen.test.ts +0 -296
  79. package/lib/dsl/dsl-interpreter.ts +0 -974
  80. package/lib/dsl/index.ts +0 -1
  81. package/lib/dsl/parser.gen.js +0 -1479
  82. package/lib/dsl/parser.pegjs +0 -130
  83. package/lib/dsl-descriptor.ts +0 -241
  84. package/lib/index.ts +0 -5
  85. package/lib/nl/__test__/context-aware-prompt.test.ts +0 -372
  86. package/lib/nl/__test__/context-selector.test.ts +0 -27
  87. package/lib/nl/__test__/nl-parser-groq-transport.test.ts +0 -139
  88. package/lib/nl/__test__/nl-parser-openai-parity.test.ts +0 -381
  89. package/lib/nl/__test__/nl-parser-openai-sampling.test.ts +0 -73
  90. package/lib/nl/__test__/nl-parser-openai-transport.test.ts +0 -79
  91. package/lib/nl/__test__/nl-parser-utils.test.ts +0 -98
  92. package/lib/nl/__test__/nl-parser.test.ts +0 -119
  93. package/lib/nl/__test__/parameter-tuning.test.ts +0 -137
  94. package/lib/nl/__test__/semantic-parsing-experiment.test.ts +0 -260
  95. package/lib/nl/context-selector.ts +0 -123
  96. package/lib/nl/index.ts +0 -19
  97. package/lib/nl/llm-monitoring.test.ts +0 -136
  98. package/lib/nl/llm-monitoring.ts +0 -339
  99. package/lib/nl/nl-parser-groq.ts +0 -510
  100. package/lib/nl/nl-parser-utils.ts +0 -310
  101. package/lib/nl/nl-parser.ts +0 -616
  102. package/lib/nl/prompt-gen.ts +0 -607
  103. package/lib/nl/prompt-res.ts +0 -207
  104. package/lib/nl-interpreter.ts +0 -262
@@ -1,207 +0,0 @@
1
- import { ExampleParse } from "./prompt-gen";
2
-
3
- export const pre_section_separator = "\n";
4
- export const post_section_separator = "\n\n\n";
5
-
6
- export const class_prequel = "// Here are all the functions";
7
-
8
- export const array_definition =
9
- "extension Array<Type> {\n" +
10
- " // Find items with matching fields in an array\n" +
11
- " Array<Type> matching(field: Field, value: Type);\n" +
12
- "\n" +
13
- " // Find items with field in an array that contains a specific value\n" +
14
- " Array<Type> contains(field: Field, value: Type);\n" +
15
- "\n" +
16
- " // Find items with exact fields in an array\n" +
17
- " Array<Type> equals(field: Field, value: Type);\n" +
18
- "\n" +
19
- " // Find items with the field above from (if provided) and below to (if provided).\n" +
20
- " Array<Type> between(field: Field, from?: Type, to?: Type);\n" +
21
- "\n" +
22
- " // Sort an array based on a specific field in ascending or descending order\n" +
23
- " Array<Type> sort(field: Field, ascending: bool);\n" +
24
- "\n" +
25
- " // Get length of an array\n" +
26
- " int length();\n" +
27
- "}";
28
-
29
- export const class_separator = "\n\n";
30
-
31
- export const example_prequel = "// Here are all the examples that we have";
32
-
33
- export function example_pair(example: ExampleParse) {
34
- return (
35
- `user: ${example.user_utterance}\n` + `parsed: ${example.example_parsed}`
36
- );
37
- }
38
-
39
- export const example_separator = "\n\n";
40
-
41
- export const accessor_parameter_rules =
42
- "// Accessor parameter rules\n" +
43
- "// For matching, contains, equals, between, and sort, the field parameter MUST be a dotted accessor, never a quoted string.\n" +
44
- '// ✅ CORRECT: Probe.getAllProbes().contains(field: .customerName, value: "Freshmarket")\n' +
45
- '// ❌ WRONG: Probe.getAllProbes().contains(field: "customerName", value: "Freshmarket")\n' +
46
- "// Use nested dotted accessors for nested fields, for example .dateTime.day.\n";
47
-
48
- export function example_parses(examples: ExampleParse[]) {
49
- return examples
50
- .map((example) => example_pair(example))
51
- .join(example_separator);
52
- }
53
-
54
- export const user_interaction_prequel = "// New user interaction";
55
-
56
- export function user_interaction_prompt(user_utterance: string) {
57
- return `user: ${user_utterance}\n` + `parsed:`;
58
- }
59
-
60
- export function agent_response_prompt(
61
- user_utterance: string,
62
- parsed: string,
63
- result: string
64
- ) {
65
- return (
66
- `user: ${user_utterance}\n` +
67
- `parsed: ${parsed}\n` +
68
- `response_context: ${result}\n` +
69
- `Generate STRICT JSON with keys: minimalText, fullText, type, shouldSpeak.\n` +
70
- `Rules: minimalText MUST be exactly one or two words, easy to speak, and no DSL/code.\n` +
71
- `Rules: minimalText should sound task/equipment-work professional (lab persona), low emotion, low cognitive load.\n` +
72
- `Rules: minimalText examples: "Completed", "In progress", "Check sample", "Retry task".\n` +
73
- `Rules: fullText should be informative but concise (<=240 chars).\n` +
74
- `Rules: type must be one of info|error|success|warning.\n` +
75
- `Rules: shouldSpeak must be true only when spoken feedback helps the user.\n` +
76
- `agent_response_json:`
77
- );
78
- }
79
-
80
- export const parse_issues = `
81
- // Here are the issues that need to be noticed
82
- // 1. Use "Array[index]" instead of index related functions. For example, "hotels[0]" instead of "hotels.first()"
83
- // 2. Use "setProperty(value) instead of "property = value". For example, "hotel.setName(123)" instead of "hotel.name = 123"
84
- // 3. Use ";" between multiple function calls. For example, "hotel.setName(123); hotel.setDesc(123)"`
85
-
86
- const exampleDeveloperClasses = `
87
- // Here are all the function that we have
88
- extension Array<Type> {
89
- // find items with matching field in an array
90
- Array<Type> matching(field: Field, value: Type);
91
-
92
- // find items with field in an array that contains a specific value
93
- Array<Type> contains(field: Field, value: Type);
94
-
95
- // find items with exact field in an array
96
- Array<Type> equals(field: Field, value: Type);
97
-
98
- // find items with field between two values in an array
99
- Array<Type> between(field: Field, from: Type, to: Type);
100
-
101
- // sort an array based on a specific field in ascending or descending order
102
- Array<Type> sort(field: Field, ascending: bool);
103
- }
104
-
105
- class Counter {
106
- string name;
107
- string type;
108
- int count;
109
- static float Version;
110
- static Counter GetCounter(name: string);
111
- void increment();
112
- void decrement();
113
- static Counter[] All();
114
- static Counter Current();
115
- }
116
-
117
-
118
- // Here are all the examples that we have
119
- user: increment
120
- parsed: Counter.Current().increment()
121
-
122
- user: what is the count
123
- parsed: Counter.Current().count
124
-
125
- user: what is the count of potato
126
- parsed: Counter.GetCounter(name: "potato").count
127
-
128
- user: increment potato counter
129
- parsed: Counter.GetCounter(name: "potato").increment()
130
-
131
- user: show me all vegetables counters
132
- parsed: Counter.All().matching(field: .type, value: "vegetable")
133
- `
134
-
135
- export function parseCodePrompt(appBasicPrompt: string): string {
136
- return `
137
- Below are the developer class definitions, methods, and their descriptions as the comments of an example app.
138
- After that, code parses from another app using ReactGenieDSL will be given.
139
- A code parse is a voice command the user gives to be parsed into code that completes the requested action.
140
-
141
- BEGIN
142
- \`
143
- ${exampleDeveloperClasses}
144
- \`
145
- END
146
-
147
- Note that all function calls have to have explicit parameter names in ReactGenieDSL.
148
-
149
- For example:
150
- \`
151
- parsed: Counter.All().matching(.type, "vegetable")
152
- \`
153
- Is INCORRECT.
154
-
155
- This is correct:
156
- \`
157
- parsed: Counter.All().matching(field: .type, value: "vegetable")
158
- \`
159
-
160
- And here is the developer classes and (optionally) code parses for this app in ReactGenieDSL:\n
161
- BEGIN
162
- \`
163
- ${appBasicPrompt}
164
- \`
165
- END
166
-
167
- For code translation using \`ReactGenieDSL\`, follow these guidelines:
168
-
169
- 1. Formatting: Directly output code without code blocks. Use semicolons for separating multiple statements.
170
- 2. Follow declarations: Only use existing functions, do not introduce new functions.
171
- 3. Retrieval Over Answers: Translate user queries into code for information retrieval, not direct answers.
172
- 4. Contextual 'Current': Use 'Current' for items the user is directly interacting with or viewing.
173
- 5. Indexing: Use bracket notation for array indexing, supporting negative indices for last element.
174
- 6. No Math Operations: Replace direct math operations with method calls (e.g., 1.plus(1)).
175
- 7. Simplified Array Operations: Avoid map/lambda expressions; apply functions directly to array elements.
176
- 8. No Default Constructors: Use 'Create' methods for object creation; otherwise, selection from existing options.
177
- 9. Static vs. Non-Static Methods: Use static methods for direct class calls; retrieve instances for non-static methods.
178
- 10. Optional Parameters: Optional parameters are noted by \`?\` after their type, they can be omitted in function calls.
179
- 11. Use Setters: Avoid assignments; utilize function calls (set[Something]) for selections or changes.
180
- 12. Property Access: When accessing nested properties, ensure to navigate through all necessary parent properties.
181
-
182
- **CRITICAL - Array Parameter Syntax:**
183
- 13. When passing array values to function parameters, you MUST wrap them in square brackets [...] even if the expression already returns an array.
184
-
185
- ✅ CORRECT: Order.current().addFoods(foods: [Order.all().matching(field: .restaurant, value: Restaurant.all()[0]).foods()])
186
- ❌ WRONG: Order.current().addFoods(foods: Order.all().matching(field: .restaurant, value: Restaurant.all()[0]).foods())
187
-
188
- ✅ CORRECT: someFunction(items: [array.matching(field: .name, value: "test")])
189
- ❌ WRONG: someFunction(items: array.matching(field: .name, value: "test"))
190
-
191
- Even though the expression returns an array type, the DSL syntax requires explicit brackets for array parameters.
192
-
193
- **CRITICAL - Accessor Parameter Syntax:**
194
- 14. For matching, contains, equals, between, and sort, the \`field\` parameter MUST be a dotted accessor, never a quoted string literal.
195
-
196
- ✅ CORRECT: Probe.getAllProbes().contains(field: .customerName, value: "Freshmarket")
197
- ❌ WRONG: Probe.getAllProbes().contains(field: "customerName", value: "Freshmarket")
198
-
199
- ✅ CORRECT: Probe.getAllProbes().sort(field: .receivedAt, ascending: false)
200
- ❌ WRONG: Probe.getAllProbes().sort(field: "receivedAt", ascending: false)
201
-
202
- For nested fields, keep the full dotted path, for example \`.dateTime.day\`.
203
-
204
- New user interaction (think carefully)
205
-
206
- `;
207
- }
@@ -1,262 +0,0 @@
1
- import { PromptGen, SamplingParams } from "./nl";
2
- import { ClassDescriptor, GenieObject } from "./dsl-descriptor";
3
- import { NlParser, NlParserGroq } from "./nl";
4
- import { DslInterpreter } from "./dsl";
5
- import {
6
- AgentResponsePayload,
7
- ContextAwareDescriptorPromptGen,
8
- ExampleParse,
9
- PromptInteractionRecorder,
10
- PromptRuntimeContextSetter,
11
- RuntimeUiContext,
12
- } from "./nl/prompt-gen";
13
-
14
- export type NlParserProvider = "groq" | "openai";
15
-
16
- export interface NlInterpreterProviderSettings {
17
- baseUrl?: string;
18
- model?: string;
19
- samplingParams?: SamplingParams;
20
- statefulValidationRetry?: boolean;
21
- }
22
-
23
- export interface NlInterpreterParserConfig {
24
- provider?: NlParserProvider;
25
- groq?: NlInterpreterProviderSettings;
26
- openai?: NlInterpreterProviderSettings;
27
- }
28
-
29
- export interface NlInterpreterMonitoringConfig {
30
- langsmithApiKey?: string;
31
- langsmithProject?: string;
32
- langsmithEndpoint?: string;
33
- }
34
-
35
- export interface NlInterpreterOptions {
36
- parser?: NlInterpreterParserConfig;
37
- monitoring?: NlInterpreterMonitoringConfig;
38
- }
39
-
40
- const DEFAULT_GROQ_BASE_URL = "https://api.groq.com/openai/v1";
41
- const DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
42
- const PROVIDER_ENV_KEY = "GENIE_PARSER_PROVIDER";
43
-
44
- function normalizeBaseUrl(baseUrl: string): string {
45
- return baseUrl.trim().replace(/\/+$/, "");
46
- }
47
-
48
- function stripChatCompletionsSuffix(baseUrl: string): string {
49
- if (!baseUrl.endsWith("/chat/completions")) {
50
- return baseUrl;
51
- }
52
- return baseUrl.slice(0, -"/chat/completions".length);
53
- }
54
-
55
- function isDirectOpenAIBaseUrl(baseUrl: string): boolean {
56
- try {
57
- const url = new URL(baseUrl);
58
- return url.hostname === "api.openai.com";
59
- } catch {
60
- return false;
61
- }
62
- }
63
-
64
- function normalizeProviderBaseUrl(
65
- provider: NlParserProvider,
66
- baseUrl?: string
67
- ): string {
68
- const fallbackBaseUrl =
69
- provider === "openai" ? DEFAULT_OPENAI_BASE_URL : DEFAULT_GROQ_BASE_URL;
70
-
71
- if (!baseUrl || baseUrl.trim().length === 0) {
72
- return fallbackBaseUrl;
73
- }
74
-
75
- const normalizedBaseUrl = stripChatCompletionsSuffix(normalizeBaseUrl(baseUrl));
76
-
77
- if (
78
- normalizedBaseUrl.endsWith("/openai/v1") ||
79
- normalizedBaseUrl.endsWith("/v1")
80
- ) {
81
- return normalizedBaseUrl;
82
- }
83
-
84
- if (provider === "openai" && isDirectOpenAIBaseUrl(normalizedBaseUrl)) {
85
- return `${normalizedBaseUrl}/v1`;
86
- }
87
-
88
- return `${normalizedBaseUrl}/openai/v1`;
89
- }
90
-
91
- function resolveParserProvider(
92
- parserConfig?: NlInterpreterParserConfig
93
- ): NlParserProvider {
94
- if (parserConfig?.provider === "openai" || parserConfig?.provider === "groq") {
95
- return parserConfig.provider;
96
- }
97
-
98
- const envProvider = process.env[PROVIDER_ENV_KEY]?.trim().toLowerCase();
99
- if (envProvider === "openai" || envProvider === "groq") {
100
- return envProvider;
101
- }
102
-
103
- return "groq";
104
- }
105
-
106
- function requireOpenAIModel(model?: string): string {
107
- const trimmed = model?.trim();
108
- if (!trimmed) {
109
- throw new Error(
110
- "OpenAI parser requires parser.openai.model / semanticModel / SEMANTIC_MODEL configuration."
111
- );
112
- }
113
- return trimmed;
114
- }
115
-
116
- export class NlInterpreter {
117
- public nlParser: NlParser | NlParserGroq;
118
- public dslInterpreter: DslInterpreter;
119
- private dslValidator: DslInterpreter;
120
-
121
- constructor(
122
- private descriptions: ClassDescriptor<GenieObject>[],
123
- private apiKey: string,
124
- private prompt?: PromptGen,
125
- private examples?: ExampleParse[],
126
- private extraPrompt?: string,
127
- private options: NlInterpreterOptions = {}
128
- ) {
129
- if (this.prompt === undefined) {
130
- console.assert(this.examples !== undefined);
131
- this.prompt = new ContextAwareDescriptorPromptGen(
132
- this.descriptions,
133
- this.examples!,
134
- extraPrompt
135
- );
136
- }
137
-
138
- const parserConfig = this.options.parser;
139
- const monitoringConfig = this.options.monitoring;
140
- const provider = resolveParserProvider(parserConfig);
141
-
142
- this.dslInterpreter = new DslInterpreter([...descriptions]);
143
- this.dslValidator = new DslInterpreter([...descriptions], true);
144
-
145
- const validateCommand = async (command: string) => {
146
- await this.dslValidator.interpret(command);
147
- };
148
-
149
- if (provider === "openai") {
150
- const openAIConfig = parserConfig?.openai;
151
- this.nlParser = new NlParser(
152
- this.prompt,
153
- apiKey,
154
- normalizeProviderBaseUrl("openai", openAIConfig?.baseUrl),
155
- requireOpenAIModel(openAIConfig?.model),
156
- openAIConfig?.samplingParams,
157
- monitoringConfig?.langsmithApiKey,
158
- monitoringConfig?.langsmithProject,
159
- monitoringConfig?.langsmithEndpoint,
160
- validateCommand,
161
- {
162
- statefulValidationRetry: !!openAIConfig?.statefulValidationRetry,
163
- }
164
- );
165
- } else {
166
- const groqConfig = parserConfig?.groq;
167
- const resolvedGroqModel =
168
- groqConfig?.model ||
169
- process.env.SEMANTIC_MODEL ||
170
- "llama-3.3-70b-versatile";
171
- this.nlParser = new NlParserGroq(
172
- this.prompt,
173
- apiKey,
174
- resolvedGroqModel,
175
- groqConfig?.samplingParams,
176
- normalizeProviderBaseUrl("groq", groqConfig?.baseUrl),
177
- monitoringConfig?.langsmithApiKey,
178
- monitoringConfig?.langsmithProject,
179
- monitoringConfig?.langsmithEndpoint,
180
- validateCommand
181
- );
182
- }
183
- }
184
-
185
- private recordInteraction(record: {
186
- utterance: string;
187
- parsed?: string | null;
188
- success: boolean;
189
- resultSummary?: string;
190
- }) {
191
- const recorder = this.prompt as unknown as PromptInteractionRecorder;
192
- if (typeof recorder?.recordInteraction === "function") {
193
- recorder.recordInteraction(record);
194
- }
195
- }
196
-
197
- public recordTurn(record: {
198
- utterance: string;
199
- parsed?: string | null;
200
- success: boolean;
201
- resultSummary?: string;
202
- }): void {
203
- this.recordInteraction(record);
204
- }
205
-
206
- setRuntimeContext(context: RuntimeUiContext | null): void {
207
- const runtimeContextSetter = this.prompt as unknown as PromptRuntimeContextSetter;
208
- if (typeof runtimeContextSetter?.setRuntimeContext === "function") {
209
- runtimeContextSetter.setRuntimeContext(context);
210
- }
211
- }
212
-
213
- async interpret(nl: string): Promise<GenieObject | null> {
214
- let command: string | null = null;
215
- try {
216
- command = await this.nlParser.parse(nl);
217
- } catch (error) {
218
- this.recordInteraction({
219
- utterance: nl,
220
- success: false,
221
- resultSummary: `parse_error:${error instanceof Error ? error.message : String(error)}`,
222
- });
223
- throw error;
224
- }
225
-
226
- if (command === null) {
227
- this.recordInteraction({
228
- utterance: nl,
229
- success: false,
230
- resultSummary: "parse_empty",
231
- });
232
- return null;
233
- }
234
-
235
- try {
236
- const result = await this.dslInterpreter.interpret(command);
237
- this.recordInteraction({
238
- utterance: nl,
239
- parsed: command,
240
- success: true,
241
- resultSummary: "execute_ok",
242
- });
243
- return result;
244
- } catch (error) {
245
- this.recordInteraction({
246
- utterance: nl,
247
- parsed: command,
248
- success: false,
249
- resultSummary: `execute_error:${error instanceof Error ? error.message : String(error)}`,
250
- });
251
- throw error;
252
- }
253
- }
254
-
255
- async respond(
256
- nl: string,
257
- parsed: string,
258
- result: string
259
- ): Promise<AgentResponsePayload | null> {
260
- return await this.nlParser.respond(nl, parsed, result);
261
- }
262
- }