@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,607 +0,0 @@
1
- import {
2
- agent_response_prompt,
3
- array_definition,
4
- accessor_parameter_rules,
5
- class_prequel,
6
- class_separator,
7
- example_parses,
8
- example_prequel,
9
- post_section_separator,
10
- pre_section_separator,
11
- user_interaction_prequel,
12
- user_interaction_prompt,
13
- parse_issues, parseCodePrompt
14
- } from "./prompt-res";
15
- import { ClassDescriptor, GenieObject } from "../dsl-descriptor";
16
- import { BoundedCache, normalizeCacheKey, rankByQuery } from "./context-selector";
17
-
18
- export interface PromptGen {
19
- prompt(user_utterance: string): string;
20
- zero_shot_prompt(user_utterance: string): string;
21
-
22
- response_prompt(
23
- user_utterance: string,
24
- parsed: string,
25
- result: string
26
- ): string;
27
- }
28
-
29
- export type ResponseSeverity = "info" | "error" | "success" | "warning";
30
-
31
- export interface AgentResponsePayload {
32
- minimalText: string;
33
- fullText: string;
34
- type: ResponseSeverity;
35
- shouldSpeak: boolean;
36
- }
37
-
38
- export interface PromptInteractionRecord {
39
- utterance: string;
40
- parsed?: string | null;
41
- success: boolean;
42
- resultSummary?: string;
43
- }
44
-
45
- export interface PromptInteractionRecorder {
46
- recordInteraction(record: PromptInteractionRecord): void;
47
- }
48
-
49
- export interface PromptSelectionConfig {
50
- enabled: boolean;
51
- topNClassDescriptions: number;
52
- topMExamples: number;
53
- recentTurnsWindow: number;
54
- olderSummaryMaxChars: number;
55
- cacheSize: number;
56
- }
57
-
58
- export interface RuntimeUiContext {
59
- tapClassName?: string;
60
- visibleClassNames: string[];
61
- isDeicticUtterance: boolean;
62
- }
63
-
64
- export interface PromptRuntimeContextSetter {
65
- setRuntimeContext(context: RuntimeUiContext | null): void;
66
- }
67
-
68
- interface PromptSelection {
69
- classDescriptions: string[];
70
- examples: ExampleParse[];
71
- }
72
-
73
- interface RankedEntry {
74
- index: number;
75
- }
76
-
77
- const DEFAULT_PROMPT_SELECTION_CONFIG: PromptSelectionConfig = {
78
- enabled: true,
79
- topNClassDescriptions: 12,
80
- topMExamples: 4,
81
- recentTurnsWindow: 4,
82
- olderSummaryMaxChars: 600,
83
- cacheSize: 64,
84
- };
85
-
86
- export class ExampleParse {
87
- constructor(readonly user_utterance, readonly example_parsed) {}
88
- }
89
-
90
- export class BasicPromptGen {
91
- constructor(
92
- private class_descriptions: string[],
93
- private examples: ExampleParse[],
94
- private extraPrompt?: string
95
- ) {}
96
-
97
- prompt_basic(): string {
98
- let prompt =
99
- `${class_prequel}${pre_section_separator}` +
100
- `${array_definition}${class_separator}` +
101
- `${this.class_descriptions.join(
102
- class_separator
103
- )}${post_section_separator}` +
104
- `${example_prequel}${pre_section_separator}` +
105
- `${example_parses(this.examples)}${post_section_separator}` +
106
- `${accessor_parameter_rules}${post_section_separator}` +
107
- // `${parse_issues}${post_section_separator}` +
108
- `${user_interaction_prequel}${pre_section_separator}`;
109
- if (this.extraPrompt !== undefined) {
110
- prompt += `${this.extraPrompt}${pre_section_separator}`;
111
- }
112
- return prompt;
113
- }
114
-
115
- zero_shot_prompt_basic(): string {
116
- return parseCodePrompt(this.prompt_basic())
117
- }
118
-
119
- prompt(user_utterance: string): string {
120
- let prompt = this.prompt_basic();
121
- prompt += `${user_interaction_prompt(user_utterance)}`;
122
- return prompt;
123
- }
124
-
125
- zero_shot_prompt(user_utterance: string): string {
126
- let prompt = this.zero_shot_prompt_basic();
127
- prompt += `${user_interaction_prompt(user_utterance)}`;
128
- return prompt;
129
- }
130
-
131
- response_prompt(
132
- user_utterance: string,
133
- parsed: string,
134
- result: string
135
- ): string {
136
- return agent_response_prompt(user_utterance, parsed, result);
137
- }
138
- }
139
-
140
- export class DescriptorPromptGen extends BasicPromptGen {
141
- constructor(
142
- private class_descriptors: ClassDescriptor<GenieObject>[],
143
- examples: ExampleParse[],
144
- extraPrompt?: string
145
- ) {
146
- super(
147
- class_descriptors.map((c) => c.description()),
148
- examples,
149
- extraPrompt
150
- );
151
- }
152
- }
153
-
154
- export class ContextAwareDescriptorPromptGen
155
- implements PromptGen, PromptInteractionRecorder, PromptRuntimeContextSetter
156
- {
157
- private readonly allClassNames: string[];
158
- private readonly allClassDescriptions: string[];
159
- private readonly allExamples: ExampleParse[];
160
- private readonly allExampleRootClasses: string[];
161
- private readonly config: PromptSelectionConfig;
162
- private readonly selectionCache: BoundedCache<PromptSelection>;
163
- private recentTurns: PromptInteractionRecord[] = [];
164
- private olderTurnsSummary = "";
165
- private runtimeUiContext: RuntimeUiContext | null = null;
166
-
167
- constructor(
168
- class_descriptors: ClassDescriptor<GenieObject>[],
169
- examples: ExampleParse[],
170
- private extraPrompt?: string,
171
- config?: Partial<PromptSelectionConfig>
172
- ) {
173
- this.allClassNames = class_descriptors.map((c) => c.className);
174
- this.allClassDescriptions = class_descriptors.map((c) => c.description());
175
- this.allExamples = examples;
176
- this.allExampleRootClasses = examples.map((example) =>
177
- ContextAwareDescriptorPromptGen.extractRootClass(example.example_parsed)
178
- );
179
- this.config = {
180
- ...DEFAULT_PROMPT_SELECTION_CONFIG,
181
- ...config,
182
- };
183
- this.selectionCache = new BoundedCache<PromptSelection>(this.config.cacheSize);
184
- }
185
-
186
- setRuntimeContext(context: RuntimeUiContext | null): void {
187
- if (!context) {
188
- this.runtimeUiContext = null;
189
- return;
190
- }
191
-
192
- this.runtimeUiContext = {
193
- tapClassName: context.tapClassName,
194
- visibleClassNames: Array.from(
195
- new Set((context.visibleClassNames || []).filter((entry) => !!entry))
196
- ),
197
- isDeicticUtterance: !!context.isDeicticUtterance,
198
- };
199
- }
200
-
201
- private static normalizeClassName(className: string): string {
202
- return className.replace(/\[\]$/g, "");
203
- }
204
-
205
- private static extractRootClass(parsedExpression: string): string {
206
- const match = parsedExpression.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*\./);
207
- return match?.[1] || "";
208
- }
209
-
210
- private static isScreenIndependentExample(example: ExampleParse): boolean {
211
- return !/\b(?:AllCurrent|Current|getCurrent|current)\s*\(/.test(
212
- example.example_parsed
213
- );
214
- }
215
-
216
- private getAllowedRootClassesForDeicticContext(): Set<string> {
217
- const context = this.runtimeUiContext;
218
- const allowed = new Set<string>();
219
- if (!context || !context.isDeicticUtterance) {
220
- return allowed;
221
- }
222
-
223
- if (context.tapClassName) {
224
- allowed.add(ContextAwareDescriptorPromptGen.normalizeClassName(context.tapClassName));
225
- return allowed;
226
- }
227
-
228
- context.visibleClassNames
229
- .map((className) => ContextAwareDescriptorPromptGen.normalizeClassName(className))
230
- .forEach((className) => {
231
- if (this.allClassNames.includes(className)) {
232
- allowed.add(className);
233
- }
234
- });
235
- return allowed;
236
- }
237
-
238
- private getPreferredRootClassesForVisibleScreenContext(): Set<string> {
239
- const context = this.runtimeUiContext;
240
- const preferred = new Set<string>();
241
- if (!context || context.isDeicticUtterance) {
242
- return preferred;
243
- }
244
-
245
- if (context.tapClassName) {
246
- const normalizedTapClass = ContextAwareDescriptorPromptGen.normalizeClassName(
247
- context.tapClassName
248
- );
249
- if (this.allClassNames.includes(normalizedTapClass)) {
250
- preferred.add(normalizedTapClass);
251
- }
252
- return preferred;
253
- }
254
-
255
- const visibleRootClasses = Array.from(
256
- new Set(
257
- context.visibleClassNames
258
- .map((className) =>
259
- ContextAwareDescriptorPromptGen.normalizeClassName(className)
260
- )
261
- .filter((className) => this.allClassNames.includes(className))
262
- )
263
- );
264
-
265
- if (visibleRootClasses.length === 1) {
266
- preferred.add(visibleRootClasses[0]);
267
- }
268
- return preferred;
269
- }
270
-
271
- private buildRuntimeUiContextBlock(): string {
272
- const context = this.runtimeUiContext;
273
- if (!context) {
274
- return "";
275
- }
276
- const hasExplicitContext =
277
- !!context.tapClassName || context.visibleClassNames.length > 0;
278
-
279
- const lines = ["// Runtime UI context"];
280
- lines.push(
281
- `ui_context: current_tap_class=${context.tapClassName || "none"}; visible_classes=${
282
- context.visibleClassNames.length > 0
283
- ? context.visibleClassNames.join(", ")
284
- : "none"
285
- }; deictic_utterance=${context.isDeicticUtterance ? "true" : "false"}`
286
- );
287
- lines.push("deictic_rules:");
288
- lines.push(
289
- "1. If deictic_utterance=true and current_tap_class exists, root the DSL chain on current_tap_class."
290
- );
291
- lines.push(
292
- "2. If deictic_utterance=true and current_tap_class=none, prefer root classes that are in visible_classes."
293
- );
294
- lines.push(
295
- "3. For deictic utterances, avoid root classes outside visible_classes unless the user explicitly names another class."
296
- );
297
- if (context.isDeicticUtterance && !hasExplicitContext) {
298
- lines.push(
299
- "4. No visible object context is available. Do not use Current()/AllCurrent()/getCurrent(); resolve the command from the utterance itself."
300
- );
301
- }
302
- lines.push("deictic_examples:");
303
- lines.push('- user: "show this item" parsed: Item.Current()');
304
- lines.push('- user: "update this status to done" parsed: Task.Current().setStatus(value: "done")');
305
- return lines.join("\n");
306
- }
307
-
308
- private buildPromptBasic(
309
- classDescriptions: string[],
310
- examples: ExampleParse[],
311
- historyContext: string,
312
- uiContext: string
313
- ): string {
314
- let prompt =
315
- `${class_prequel}${pre_section_separator}` +
316
- `${array_definition}${class_separator}` +
317
- `${classDescriptions.join(class_separator)}${post_section_separator}` +
318
- `${example_prequel}${pre_section_separator}` +
319
- `${example_parses(examples)}${post_section_separator}` +
320
- `${accessor_parameter_rules}${post_section_separator}` +
321
- `${user_interaction_prequel}${pre_section_separator}`;
322
-
323
- if (historyContext) {
324
- prompt += `${historyContext}${post_section_separator}`;
325
- }
326
-
327
- if (uiContext) {
328
- prompt += `${uiContext}${post_section_separator}`;
329
- }
330
-
331
- if (this.extraPrompt !== undefined) {
332
- prompt += `${this.extraPrompt}${pre_section_separator}`;
333
- }
334
-
335
- return prompt;
336
- }
337
-
338
- private buildHistoryContext(): string {
339
- if (this.recentTurns.length === 0 && !this.olderTurnsSummary) {
340
- return "";
341
- }
342
-
343
- const sections: string[] = ["// Conversation context"];
344
- if (this.olderTurnsSummary) {
345
- sections.push(`summary: ${this.olderTurnsSummary}`);
346
- }
347
-
348
- if (this.recentTurns.length > 0) {
349
- sections.push("recent_turns:");
350
- this.recentTurns.forEach((turn, index) => {
351
- const parsed = turn.parsed ? ` parsed=${turn.parsed}` : "";
352
- const result = turn.resultSummary ? ` result=${turn.resultSummary}` : "";
353
- sections.push(
354
- `- t${index + 1}: user=${turn.utterance} success=${turn.success}${parsed}${result}`
355
- );
356
- });
357
- }
358
-
359
- return sections.join("\n");
360
- }
361
-
362
- private summarizeRecord(record: PromptInteractionRecord): string {
363
- const parsed = record.parsed ? `parsed=${record.parsed}` : "parsed=<none>";
364
- const result = record.resultSummary
365
- ? `result=${record.resultSummary}`
366
- : "result=<none>";
367
- return `user=${record.utterance} success=${record.success} ${parsed} ${result}`;
368
- }
369
-
370
- private appendOlderSummary(summaryLine: string): void {
371
- const next = this.olderTurnsSummary
372
- ? `${this.olderTurnsSummary} | ${summaryLine}`
373
- : summaryLine;
374
-
375
- if (next.length <= this.config.olderSummaryMaxChars) {
376
- this.olderTurnsSummary = next;
377
- return;
378
- }
379
-
380
- this.olderTurnsSummary = next.slice(next.length - this.config.olderSummaryMaxChars);
381
- }
382
-
383
- private selectionFromCache(cacheKey: string): PromptSelection | undefined {
384
- const key = normalizeCacheKey(cacheKey);
385
- if (!key) {
386
- return undefined;
387
- }
388
- return this.selectionCache.get(key);
389
- }
390
-
391
- private cacheSelection(cacheKey: string, selection: PromptSelection): void {
392
- const key = normalizeCacheKey(cacheKey);
393
- if (!key) {
394
- return;
395
- }
396
- this.selectionCache.set(key, selection);
397
- }
398
-
399
- private selectionCacheKeyForUtterance(user_utterance: string): string {
400
- const context = this.runtimeUiContext;
401
- if (!context) {
402
- return user_utterance;
403
- }
404
-
405
- const preferredVisibleRoots = this.getPreferredRootClassesForVisibleScreenContext();
406
- if (!context.isDeicticUtterance && preferredVisibleRoots.size === 0) {
407
- return user_utterance;
408
- }
409
-
410
- const visibleKey = [...context.visibleClassNames].sort().join(",");
411
- return `${user_utterance}::tap=${context.tapClassName || ""}::visible=${visibleKey}::deictic=${
412
- context.isDeicticUtterance ? 1 : 0
413
- }`;
414
- }
415
-
416
- private buildSelectionFromExampleIndexes(exampleIndexes: number[]): PromptSelection {
417
- if (exampleIndexes.length === 0) {
418
- return {
419
- classDescriptions: [],
420
- examples: [],
421
- };
422
- }
423
-
424
- const uniqueExampleIndexes = Array.from(new Set(exampleIndexes)).sort((a, b) => a - b);
425
- const examples = uniqueExampleIndexes.map((index) => this.allExamples[index]);
426
- const exampleRootClasses = new Set(
427
- uniqueExampleIndexes
428
- .map((index) => this.allExampleRootClasses[index])
429
- .filter((className) => className.length > 0)
430
- );
431
- const classDescriptions = this.allClassNames
432
- .map((className, index) => ({ className, index }))
433
- .filter((entry) => exampleRootClasses.has(entry.className))
434
- .map((entry) => this.allClassDescriptions[entry.index]);
435
-
436
- return {
437
- classDescriptions,
438
- examples,
439
- };
440
- }
441
-
442
- private rescueSelectionWithoutVisibleContext(
443
- user_utterance: string,
444
- rankedExamples: RankedEntry[]
445
- ): PromptSelection {
446
- const rescuedExampleIndexes = rankedExamples
447
- .filter((entry) =>
448
- ContextAwareDescriptorPromptGen.isScreenIndependentExample(
449
- this.allExamples[entry.index]
450
- )
451
- )
452
- .slice(0, this.config.topMExamples)
453
- .map((entry) => entry.index);
454
-
455
- return this.buildSelectionFromExampleIndexes(rescuedExampleIndexes);
456
- }
457
-
458
- private computeSelection(user_utterance: string): PromptSelection {
459
- if (!this.config.enabled) {
460
- return {
461
- classDescriptions: this.allClassDescriptions,
462
- examples: this.allExamples,
463
- };
464
- }
465
-
466
- const cacheKey = this.selectionCacheKeyForUtterance(user_utterance);
467
- const cached = this.selectionFromCache(cacheKey);
468
- if (cached) {
469
- return cached;
470
- }
471
-
472
- const allowedDeicticRootClasses = this.getAllowedRootClassesForDeicticContext();
473
- const preferredVisibleRootClasses =
474
- this.getPreferredRootClassesForVisibleScreenContext();
475
- const contextRootClasses =
476
- allowedDeicticRootClasses.size > 0
477
- ? allowedDeicticRootClasses
478
- : preferredVisibleRootClasses;
479
- const isDeicticUtterance = !!this.runtimeUiContext?.isDeicticUtterance;
480
- const isContextConstrained = contextRootClasses.size > 0;
481
- const rankingQuery = isContextConstrained
482
- ? `${user_utterance} ${Array.from(contextRootClasses).join(" ")}`
483
- : user_utterance;
484
-
485
- const rankedClassDescriptions = rankByQuery(
486
- rankingQuery,
487
- this.allClassDescriptions,
488
- (description) => description,
489
- isContextConstrained
490
- ? this.allClassDescriptions.length
491
- : this.config.topNClassDescriptions,
492
- {
493
- allowZeroScoreBackfill: !isContextConstrained,
494
- }
495
- );
496
- const candidateClassEntries = isContextConstrained
497
- ? rankedClassDescriptions.filter((entry) =>
498
- contextRootClasses.has(this.allClassNames[entry.index])
499
- )
500
- : rankedClassDescriptions;
501
- const classIndexes = candidateClassEntries
502
- .slice(0, this.config.topNClassDescriptions)
503
- .map((entry) => entry.index)
504
- .sort((a, b) => a - b);
505
- const selectedClassDescriptions = classIndexes.map(
506
- (index) => this.allClassDescriptions[index]
507
- );
508
-
509
- const rankedExamples = rankByQuery(
510
- rankingQuery,
511
- this.allExamples,
512
- (example) => `${example.user_utterance}\n${example.example_parsed}`,
513
- isContextConstrained ? this.allExamples.length : this.config.topMExamples,
514
- {
515
- allowZeroScoreBackfill: !isContextConstrained,
516
- }
517
- );
518
- const candidateExampleEntries = isContextConstrained
519
- ? rankedExamples.filter((entry) =>
520
- contextRootClasses.has(this.allExampleRootClasses[entry.index])
521
- )
522
- : rankedExamples;
523
-
524
- if (isDeicticUtterance && contextRootClasses.size === 0) {
525
- const rescuedSelection = this.rescueSelectionWithoutVisibleContext(
526
- user_utterance,
527
- rankedExamples
528
- );
529
- this.cacheSelection(cacheKey, rescuedSelection);
530
- return rescuedSelection;
531
- }
532
-
533
- const exampleIndexes = candidateExampleEntries
534
- .slice(0, this.config.topMExamples)
535
- .map((entry) => entry.index)
536
- .sort((a, b) => a - b);
537
- const selectedExamples = exampleIndexes.map((index) => this.allExamples[index]);
538
-
539
- const selection = {
540
- classDescriptions:
541
- selectedClassDescriptions.length > 0
542
- ? selectedClassDescriptions
543
- : isDeicticUtterance
544
- ? []
545
- : this.allClassDescriptions,
546
- examples:
547
- selectedExamples.length > 0
548
- ? selectedExamples
549
- : isContextConstrained
550
- ? []
551
- : this.allExamples,
552
- };
553
-
554
- this.cacheSelection(cacheKey, selection);
555
- return selection;
556
- }
557
-
558
- private zeroShotPromptForSelection(
559
- user_utterance: string,
560
- selection: PromptSelection
561
- ): string {
562
- const historyContext = this.buildHistoryContext();
563
- const uiContext = this.buildRuntimeUiContextBlock();
564
- const basic = this.buildPromptBasic(
565
- selection.classDescriptions,
566
- selection.examples,
567
- historyContext,
568
- uiContext
569
- );
570
- return `${parseCodePrompt(basic)}${user_interaction_prompt(user_utterance)}`;
571
- }
572
-
573
- prompt(user_utterance: string): string {
574
- const selection = this.computeSelection(user_utterance);
575
- const historyContext = this.buildHistoryContext();
576
- const uiContext = this.buildRuntimeUiContextBlock();
577
- const basic = this.buildPromptBasic(
578
- selection.classDescriptions,
579
- selection.examples,
580
- historyContext,
581
- uiContext
582
- );
583
- return `${basic}${user_interaction_prompt(user_utterance)}`;
584
- }
585
-
586
- zero_shot_prompt(user_utterance: string): string {
587
- const selection = this.computeSelection(user_utterance);
588
- return this.zeroShotPromptForSelection(user_utterance, selection);
589
- }
590
-
591
- response_prompt(user_utterance: string, parsed: string, result: string): string {
592
- return agent_response_prompt(user_utterance, parsed, result);
593
- }
594
-
595
- recordInteraction(record: PromptInteractionRecord): void {
596
- this.recentTurns.push(record);
597
-
598
- while (this.recentTurns.length > this.config.recentTurnsWindow) {
599
- const shifted = this.recentTurns.shift();
600
- if (shifted) {
601
- this.appendOlderSummary(this.summarizeRecord(shifted));
602
- }
603
- }
604
- }
605
- }
606
-
607
- // TODO: automatically generate prompt from DSL Descriptors