@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.
- package/.env +10 -0
- package/.env.example +17 -0
- package/.github/workflows/publish.yml +20 -0
- package/package.json +1 -5
- package/dist/__test__/dsl-descriptor.test.d.ts +0 -1
- package/dist/__test__/dsl-descriptor.test.js +0 -27
- package/dist/__test__/dsl-descriptor.test.js.map +0 -1
- package/dist/__test__/example_descriptor.d.ts +0 -125
- package/dist/__test__/example_descriptor.js +0 -607
- package/dist/__test__/example_descriptor.js.map +0 -1
- package/dist/__test__/food_descriptor.state.json +0 -1
- package/dist/__test__/food_descriptor.test.d.ts +0 -74
- package/dist/__test__/food_descriptor.test.js +0 -205
- package/dist/__test__/food_descriptor.test.js.map +0 -1
- package/dist/__test__/nl-interpreter-provider-selection.test.d.ts +0 -1
- package/dist/__test__/nl-interpreter-provider-selection.test.js +0 -73
- package/dist/__test__/nl-interpreter-provider-selection.test.js.map +0 -1
- package/dist/__test__/nl-interpreter.test.d.ts +0 -1
- package/dist/__test__/nl-interpreter.test.js +0 -86
- package/dist/__test__/nl-interpreter.test.js.map +0 -1
- package/dist/decorators/__test__/decorators.test.d.ts +0 -1
- package/dist/decorators/__test__/decorators.test.js +0 -182
- package/dist/decorators/__test__/decorators.test.js.map +0 -1
- package/dist/decorators/__test__/inheritance-descriptor.test.d.ts +0 -1
- package/dist/decorators/__test__/inheritance-descriptor.test.js +0 -107
- package/dist/decorators/__test__/inheritance-descriptor.test.js.map +0 -1
- package/dist/dsl/__test__/dsl-interpreter.test.d.ts +0 -1
- package/dist/dsl/__test__/dsl-interpreter.test.js +0 -334
- package/dist/dsl/__test__/dsl-interpreter.test.js.map +0 -1
- package/dist/dsl/__test__/parser.gen.test.d.ts +0 -1
- package/dist/dsl/__test__/parser.gen.test.js +0 -283
- package/dist/dsl/__test__/parser.gen.test.js.map +0 -1
- package/dist/nl/__test__/context-aware-prompt.test.d.ts +0 -1
- package/dist/nl/__test__/context-aware-prompt.test.js +0 -247
- package/dist/nl/__test__/context-aware-prompt.test.js.map +0 -1
- package/dist/nl/__test__/context-selector.test.d.ts +0 -1
- package/dist/nl/__test__/context-selector.test.js +0 -20
- package/dist/nl/__test__/context-selector.test.js.map +0 -1
- package/dist/nl/__test__/nl-parser-groq-transport.test.d.ts +0 -1
- package/dist/nl/__test__/nl-parser-groq-transport.test.js +0 -87
- package/dist/nl/__test__/nl-parser-groq-transport.test.js.map +0 -1
- package/dist/nl/__test__/nl-parser-openai-parity.test.d.ts +0 -1
- package/dist/nl/__test__/nl-parser-openai-parity.test.js +0 -206
- package/dist/nl/__test__/nl-parser-openai-parity.test.js.map +0 -1
- package/dist/nl/__test__/nl-parser-openai-sampling.test.d.ts +0 -1
- package/dist/nl/__test__/nl-parser-openai-sampling.test.js +0 -44
- package/dist/nl/__test__/nl-parser-openai-sampling.test.js.map +0 -1
- package/dist/nl/__test__/nl-parser-openai-transport.test.d.ts +0 -1
- package/dist/nl/__test__/nl-parser-openai-transport.test.js +0 -55
- package/dist/nl/__test__/nl-parser-openai-transport.test.js.map +0 -1
- package/dist/nl/__test__/nl-parser-utils.test.d.ts +0 -1
- package/dist/nl/__test__/nl-parser-utils.test.js +0 -70
- package/dist/nl/__test__/nl-parser-utils.test.js.map +0 -1
- package/dist/nl/__test__/nl-parser.test.d.ts +0 -1
- package/dist/nl/__test__/nl-parser.test.js +0 -64
- package/dist/nl/__test__/nl-parser.test.js.map +0 -1
- package/dist/nl/__test__/parameter-tuning.test.d.ts +0 -1
- package/dist/nl/__test__/parameter-tuning.test.js +0 -95
- package/dist/nl/__test__/parameter-tuning.test.js.map +0 -1
- package/dist/nl/__test__/semantic-parsing-experiment.test.d.ts +0 -1
- package/dist/nl/__test__/semantic-parsing-experiment.test.js +0 -178
- package/dist/nl/__test__/semantic-parsing-experiment.test.js.map +0 -1
- package/dist/nl/llm-monitoring.test.d.ts +0 -5
- package/dist/nl/llm-monitoring.test.js +0 -101
- package/dist/nl/llm-monitoring.test.js.map +0 -1
- package/lib/__test__/dsl-descriptor.test.ts +0 -27
- package/lib/__test__/example_descriptor.ts +0 -762
- package/lib/__test__/food_descriptor.state.json +0 -1
- package/lib/__test__/food_descriptor.test.ts +0 -331
- package/lib/__test__/nl-interpreter-provider-selection.test.ts +0 -126
- package/lib/__test__/nl-interpreter.test.ts +0 -129
- package/lib/decorators/__test__/decorators.test.ts +0 -177
- package/lib/decorators/__test__/inheritance-descriptor.test.ts +0 -92
- package/lib/decorators/decorators.ts +0 -754
- package/lib/decorators/index.ts +0 -2
- package/lib/decorators/store.ts +0 -47
- package/lib/dsl/__test__/dsl-interpreter.test.ts +0 -453
- package/lib/dsl/__test__/parser.gen.test.ts +0 -296
- package/lib/dsl/dsl-interpreter.ts +0 -974
- package/lib/dsl/index.ts +0 -1
- package/lib/dsl/parser.gen.js +0 -1479
- package/lib/dsl/parser.pegjs +0 -130
- package/lib/dsl-descriptor.ts +0 -241
- package/lib/index.ts +0 -5
- package/lib/nl/__test__/context-aware-prompt.test.ts +0 -372
- package/lib/nl/__test__/context-selector.test.ts +0 -27
- package/lib/nl/__test__/nl-parser-groq-transport.test.ts +0 -139
- package/lib/nl/__test__/nl-parser-openai-parity.test.ts +0 -381
- package/lib/nl/__test__/nl-parser-openai-sampling.test.ts +0 -73
- package/lib/nl/__test__/nl-parser-openai-transport.test.ts +0 -79
- package/lib/nl/__test__/nl-parser-utils.test.ts +0 -98
- package/lib/nl/__test__/nl-parser.test.ts +0 -119
- package/lib/nl/__test__/parameter-tuning.test.ts +0 -137
- package/lib/nl/__test__/semantic-parsing-experiment.test.ts +0 -260
- package/lib/nl/context-selector.ts +0 -123
- package/lib/nl/index.ts +0 -19
- package/lib/nl/llm-monitoring.test.ts +0 -136
- package/lib/nl/llm-monitoring.ts +0 -339
- package/lib/nl/nl-parser-groq.ts +0 -510
- package/lib/nl/nl-parser-utils.ts +0 -310
- package/lib/nl/nl-parser.ts +0 -616
- package/lib/nl/prompt-gen.ts +0 -607
- package/lib/nl/prompt-res.ts +0 -207
- package/lib/nl-interpreter.ts +0 -262
package/lib/nl/prompt-gen.ts
DELETED
|
@@ -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
|