@falai/agent 1.1.1 → 1.1.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/dist/cjs/core/Agent.d.ts +202 -67
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +366 -158
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/BatchExecutor.d.ts.map +1 -1
- package/dist/cjs/core/BatchExecutor.js +4 -2
- package/dist/cjs/core/BatchExecutor.js.map +1 -1
- package/dist/cjs/core/BatchPromptBuilder.d.ts.map +1 -1
- package/dist/cjs/core/BatchPromptBuilder.js +5 -2
- package/dist/cjs/core/BatchPromptBuilder.js.map +1 -1
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
- package/dist/cjs/core/ResponseEngine.js +6 -3
- package/dist/cjs/core/ResponseEngine.js.map +1 -1
- package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
- package/dist/cjs/core/ResponseModal.js +18 -17
- package/dist/cjs/core/ResponseModal.js.map +1 -1
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
- package/dist/cjs/core/RoutingEngine.js +8 -73
- package/dist/cjs/core/RoutingEngine.js.map +1 -1
- package/dist/core/Agent.d.ts +202 -67
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +366 -158
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/BatchExecutor.d.ts.map +1 -1
- package/dist/core/BatchExecutor.js +4 -2
- package/dist/core/BatchExecutor.js.map +1 -1
- package/dist/core/BatchPromptBuilder.d.ts.map +1 -1
- package/dist/core/BatchPromptBuilder.js +5 -2
- package/dist/core/BatchPromptBuilder.js.map +1 -1
- package/dist/core/ResponseEngine.d.ts.map +1 -1
- package/dist/core/ResponseEngine.js +6 -3
- package/dist/core/ResponseEngine.js.map +1 -1
- package/dist/core/ResponseModal.d.ts.map +1 -1
- package/dist/core/ResponseModal.js +18 -17
- package/dist/core/ResponseModal.js.map +1 -1
- package/dist/core/RoutingEngine.d.ts.map +1 -1
- package/dist/core/RoutingEngine.js +8 -73
- package/dist/core/RoutingEngine.js.map +1 -1
- package/docs/api/README.md +2 -2
- package/docs/api/overview.md +1 -1
- package/docs/architecture/data-extraction-flow.md +17 -19
- package/docs/core/conversation-flows/data-collection.md +2 -2
- package/docs/core/error-handling.md +3 -4
- package/package.json +2 -2
- package/src/core/Agent.ts +427 -195
- package/src/core/BatchExecutor.ts +5 -2
- package/src/core/BatchPromptBuilder.ts +41 -38
- package/src/core/ResponseEngine.ts +56 -53
- package/src/core/ResponseModal.ts +79 -81
- package/src/core/RoutingEngine.ts +67 -149
|
@@ -335,8 +335,11 @@ export class BatchExecutor<TContext = unknown, TData = unknown> {
|
|
|
335
335
|
const warning = `[Agent] Step "${step.description || step.id}" requires data [${missingRequires.join(', ')}] that was not collected by previous steps. ` +
|
|
336
336
|
`Ensure earlier steps collect these fields before this step can proceed.`;
|
|
337
337
|
logger.warn(warning);
|
|
338
|
-
|
|
339
|
-
console
|
|
338
|
+
|
|
339
|
+
// Also log to console for developer visibility (but silence in test suites to prevent fast-check spam)
|
|
340
|
+
if (process.env.NODE_ENV !== 'test') {
|
|
341
|
+
console.warn(warning);
|
|
342
|
+
}
|
|
340
343
|
}
|
|
341
344
|
|
|
342
345
|
logger.debug(`[BatchExecutor] Step ${step.id} needs input, stopping batch. Missing requires: [${missingRequires.join(', ')}], Collect fields: [${collectFields.join(', ')}]`);
|
|
@@ -66,7 +66,7 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
66
66
|
*/
|
|
67
67
|
async buildBatchPrompt(params: BuildBatchPromptParams<TContext, TData>): Promise<BatchPromptResult> {
|
|
68
68
|
const { steps, route, history, context, session, agentOptions } = params;
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
// Create template context for rendering
|
|
71
71
|
const templateContext = createTemplateContext<TContext, TData>({
|
|
72
72
|
context,
|
|
@@ -74,7 +74,7 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
74
74
|
session,
|
|
75
75
|
history,
|
|
76
76
|
});
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
// Collect all collect fields from all steps
|
|
79
79
|
const collectFields: string[] = [];
|
|
80
80
|
for (const step of steps) {
|
|
@@ -87,13 +87,13 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
// Build the combined prompt using PromptComposer for consistency
|
|
92
92
|
const composer = new PromptComposer<TContext, TData>(templateContext);
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
// Add agent meta information
|
|
95
95
|
await composer.addAgentMeta(agentOptions);
|
|
96
|
-
|
|
96
|
+
|
|
97
97
|
// Add route-specific identity/personality if available
|
|
98
98
|
if (route.identity) {
|
|
99
99
|
const identity = await render(route.identity, templateContext);
|
|
@@ -101,25 +101,25 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
101
101
|
await composer.addInstruction(`**Route Identity:** ${identity}`);
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
if (route.personality) {
|
|
106
106
|
const personality = await render(route.personality, templateContext);
|
|
107
107
|
if (personality) {
|
|
108
108
|
await composer.addInstruction(`**Route Personality:** ${personality}`);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
// Add knowledge base if available
|
|
113
113
|
await composer.addKnowledgeBase(agentOptions.knowledgeBase, route.getKnowledgeBase());
|
|
114
|
-
|
|
114
|
+
|
|
115
115
|
// Add glossary terms
|
|
116
116
|
const allTerms = [...(agentOptions.terms || []), ...route.getTerms()];
|
|
117
117
|
await composer.addGlossary(allTerms);
|
|
118
|
-
|
|
118
|
+
|
|
119
119
|
// Add guidelines
|
|
120
120
|
const allGuidelines = [...(agentOptions.guidelines || []), ...route.getGuidelines()];
|
|
121
121
|
await composer.addGuidelines(allGuidelines);
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
// Add combined rules (agent + route)
|
|
124
124
|
const allRules = [...(agentOptions.rules || []), ...route.getRules()];
|
|
125
125
|
if (allRules.length > 0) {
|
|
@@ -128,7 +128,7 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
128
128
|
await composer.addInstruction(`Rules:\n- ${renderedRules.join('\n- ')}`);
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
-
|
|
131
|
+
|
|
132
132
|
// Add combined prohibitions (agent + route)
|
|
133
133
|
const allProhibitions = [...(agentOptions.prohibitions || []), ...route.getProhibitions()];
|
|
134
134
|
if (allProhibitions.length > 0) {
|
|
@@ -137,13 +137,13 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
137
137
|
await composer.addInstruction(`Prohibitions:\n- ${renderedProhibitions.join('\n- ')}`);
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
|
-
|
|
140
|
+
|
|
141
141
|
// Add interaction history
|
|
142
142
|
await composer.addInteractionHistory(history, 'Recent conversation context:');
|
|
143
|
-
|
|
143
|
+
|
|
144
144
|
// Build the step sections
|
|
145
145
|
const stepSections = await this.buildStepSections(steps, templateContext);
|
|
146
|
-
|
|
146
|
+
|
|
147
147
|
// Add the conversation flow section
|
|
148
148
|
if (steps.length > 1) {
|
|
149
149
|
await composer.addInstruction(
|
|
@@ -157,27 +157,27 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
157
157
|
stepSections
|
|
158
158
|
);
|
|
159
159
|
}
|
|
160
|
-
|
|
160
|
+
|
|
161
161
|
// Add data collection section if there are fields to collect
|
|
162
162
|
if (collectFields.length > 0) {
|
|
163
163
|
const collectionSection = this.buildDataCollectionSection(collectFields, agentOptions);
|
|
164
164
|
await composer.addInstruction(collectionSection);
|
|
165
165
|
}
|
|
166
|
-
|
|
166
|
+
|
|
167
167
|
// Add response format instructions
|
|
168
168
|
const responseFormat = this.buildResponseFormatSection(collectFields);
|
|
169
169
|
await composer.addInstruction(responseFormat);
|
|
170
|
-
|
|
170
|
+
|
|
171
171
|
// Build the final prompt
|
|
172
172
|
const prompt = await composer.build();
|
|
173
|
-
|
|
173
|
+
|
|
174
174
|
return {
|
|
175
175
|
prompt,
|
|
176
176
|
collectFields,
|
|
177
177
|
stepCount: steps.length,
|
|
178
178
|
};
|
|
179
179
|
}
|
|
180
|
-
|
|
180
|
+
|
|
181
181
|
/**
|
|
182
182
|
* Build the step sections of the prompt
|
|
183
183
|
*
|
|
@@ -190,15 +190,15 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
190
190
|
templateContext: ReturnType<typeof createTemplateContext<TContext, TData>>
|
|
191
191
|
): Promise<string> {
|
|
192
192
|
const sections: string[] = [];
|
|
193
|
-
|
|
193
|
+
|
|
194
194
|
for (let i = 0; i < steps.length; i++) {
|
|
195
195
|
const step = steps[i];
|
|
196
196
|
const stepNumber = i + 1;
|
|
197
|
-
|
|
197
|
+
|
|
198
198
|
// Build step header
|
|
199
199
|
const description = step.description || `Step ${stepNumber}`;
|
|
200
200
|
let section = `### Step ${stepNumber}: ${description}\n`;
|
|
201
|
-
|
|
201
|
+
|
|
202
202
|
// Render and add step prompt if available
|
|
203
203
|
if (step.prompt) {
|
|
204
204
|
const renderedPrompt = await render(step.prompt, templateContext);
|
|
@@ -206,19 +206,19 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
206
206
|
section += `\n${renderedPrompt}\n`;
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
|
-
|
|
209
|
+
|
|
210
210
|
// Add collect fields for this step if any
|
|
211
211
|
if (step.collect && step.collect.length > 0) {
|
|
212
212
|
const collectList = step.collect.map(f => `\`${String(f)}\``).join(', ');
|
|
213
213
|
section += `\n**Collect:** ${collectList}\n`;
|
|
214
214
|
}
|
|
215
|
-
|
|
215
|
+
|
|
216
216
|
sections.push(section);
|
|
217
217
|
}
|
|
218
|
-
|
|
218
|
+
|
|
219
219
|
return sections.join('\n');
|
|
220
220
|
}
|
|
221
|
-
|
|
221
|
+
|
|
222
222
|
/**
|
|
223
223
|
* Build the data collection section of the prompt
|
|
224
224
|
*
|
|
@@ -236,36 +236,36 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
236
236
|
'Extract the following information from your response:',
|
|
237
237
|
''
|
|
238
238
|
];
|
|
239
|
-
|
|
239
|
+
|
|
240
240
|
// Get schema information if available
|
|
241
241
|
const schema = agentOptions.schema;
|
|
242
|
-
|
|
242
|
+
|
|
243
243
|
for (const field of collectFields) {
|
|
244
244
|
let fieldDescription = field;
|
|
245
|
-
|
|
245
|
+
|
|
246
246
|
// Try to get field type/description from schema
|
|
247
247
|
if (schema?.properties && schema.properties[field]) {
|
|
248
248
|
const fieldSchema = schema.properties[field] as Record<string, unknown>;
|
|
249
249
|
const rawType = fieldSchema.type;
|
|
250
250
|
const rawDescription = fieldSchema.description;
|
|
251
|
-
|
|
251
|
+
|
|
252
252
|
// Safely convert to string, handling objects and primitives
|
|
253
253
|
const type = typeof rawType === 'string' ? rawType : 'string';
|
|
254
254
|
const description = typeof rawDescription === 'string' ? rawDescription : '';
|
|
255
|
-
|
|
255
|
+
|
|
256
256
|
if (description) {
|
|
257
257
|
fieldDescription = `${field} (${type}): ${description}`;
|
|
258
258
|
} else {
|
|
259
259
|
fieldDescription = `${field} (${type})`;
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
|
-
|
|
262
|
+
|
|
263
263
|
lines.push(`- ${fieldDescription}`);
|
|
264
264
|
}
|
|
265
|
-
|
|
265
|
+
|
|
266
266
|
return lines.join('\n');
|
|
267
267
|
}
|
|
268
|
-
|
|
268
|
+
|
|
269
269
|
/**
|
|
270
270
|
* Build the response format section of the prompt
|
|
271
271
|
*
|
|
@@ -277,17 +277,20 @@ export class BatchPromptBuilder<TContext = unknown, TData = unknown> {
|
|
|
277
277
|
'## Response Format',
|
|
278
278
|
'',
|
|
279
279
|
'Return JSON with:',
|
|
280
|
-
'- `message`:
|
|
280
|
+
'- `message`: A natural, conversational response directed at the user. This MUST read like a human conversation.',
|
|
281
|
+
'',
|
|
282
|
+
'CRITICAL: The `message` field must NEVER contain field names, JSON keys, raw data values, or technical information.',
|
|
283
|
+
'Data goes in the separate JSON fields below, NOT in the message text.',
|
|
281
284
|
];
|
|
282
|
-
|
|
285
|
+
|
|
283
286
|
if (collectFields.length > 0) {
|
|
284
287
|
lines.push('');
|
|
285
|
-
lines.push('Include the following collected fields as top-level properties:');
|
|
288
|
+
lines.push('Include the following collected fields as top-level properties (separate from message):');
|
|
286
289
|
for (const field of collectFields) {
|
|
287
290
|
lines.push(`- \`${field}\``);
|
|
288
291
|
}
|
|
289
292
|
}
|
|
290
|
-
|
|
293
|
+
|
|
291
294
|
return lines.join('\n');
|
|
292
295
|
}
|
|
293
296
|
}
|
|
@@ -44,48 +44,48 @@ export interface BuildFallbackPromptParams<TContext = unknown, TData = unknown>
|
|
|
44
44
|
|
|
45
45
|
export class ResponseEngine<TContext = unknown, TData = unknown> {
|
|
46
46
|
responseSchemaForRoute(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
route: Route<TContext, TData>,
|
|
48
|
+
currentStep?: Step<TContext, TData>,
|
|
49
|
+
agentSchema?: StructuredSchema
|
|
50
|
+
): StructuredSchema {
|
|
51
|
+
const base: StructuredSchema = {
|
|
52
|
+
type: "object",
|
|
53
|
+
properties: {
|
|
54
|
+
message: { type: "string", description: "Natural, conversational response directed at the user. Must NOT contain field names, raw data, or internal information." },
|
|
55
|
+
},
|
|
56
|
+
required: ["message"],
|
|
57
|
+
additionalProperties: false,
|
|
58
|
+
};
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
// Add data field only if route has responseOutputSchema
|
|
61
|
+
if (route.responseOutputSchema) {
|
|
62
|
+
base.properties!.data = route.responseOutputSchema;
|
|
63
|
+
}
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
} else {
|
|
76
|
-
// No agent schema - generate dynamic schema from collect fields
|
|
77
|
-
for (const field of currentStep.collect) {
|
|
78
|
-
base.properties![field as string] = {
|
|
79
|
-
type: "string",
|
|
80
|
-
description: `Collected value for ${String(field)}`,
|
|
81
|
-
};
|
|
65
|
+
// Add collect fields from current step
|
|
66
|
+
if (currentStep?.collect) {
|
|
67
|
+
if (agentSchema?.properties) {
|
|
68
|
+
// Use agent schema definitions for collect fields
|
|
69
|
+
for (const field of currentStep.collect) {
|
|
70
|
+
const fieldSchema = agentSchema.properties[field as string];
|
|
71
|
+
if (fieldSchema) {
|
|
72
|
+
base.properties![field as string] = fieldSchema;
|
|
82
73
|
}
|
|
83
74
|
}
|
|
75
|
+
} else {
|
|
76
|
+
// No agent schema - generate dynamic schema from collect fields
|
|
77
|
+
for (const field of currentStep.collect) {
|
|
78
|
+
base.properties![field as string] = {
|
|
79
|
+
type: "string",
|
|
80
|
+
description: `Collected value for ${String(field)}`,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
84
83
|
}
|
|
85
|
-
|
|
86
|
-
return base;
|
|
87
84
|
}
|
|
88
85
|
|
|
86
|
+
return base;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
89
|
async buildResponsePrompt(
|
|
90
90
|
params: BuildResponsePromptParams<TContext, TData>
|
|
91
91
|
): Promise<string> {
|
|
@@ -155,11 +155,11 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
|
|
|
155
155
|
|
|
156
156
|
await pc.addInteractionHistory(history);
|
|
157
157
|
await pc.addLastMessage(lastMessage);
|
|
158
|
-
|
|
158
|
+
|
|
159
159
|
// Add data collection instructions - include ALL route fields, not just current step
|
|
160
160
|
// Collect all fields from route's required and optional fields
|
|
161
161
|
const allRouteFields = new Set<string>();
|
|
162
|
-
|
|
162
|
+
|
|
163
163
|
if (route.requiredFields) {
|
|
164
164
|
route.requiredFields.forEach(field => allRouteFields.add(String(field)));
|
|
165
165
|
}
|
|
@@ -173,7 +173,7 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
|
|
|
173
173
|
if (allRouteFields.size > 0) {
|
|
174
174
|
const stepCollectFields = new Set(currentStep?.collect?.map(f => String(f)) || []);
|
|
175
175
|
const fieldDescriptions: string[] = [];
|
|
176
|
-
|
|
176
|
+
|
|
177
177
|
for (const field of allRouteFields) {
|
|
178
178
|
if (agentSchema?.properties) {
|
|
179
179
|
const fieldSchema = agentSchema.properties[field];
|
|
@@ -181,22 +181,22 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
|
|
|
181
181
|
const fieldName = field;
|
|
182
182
|
const fieldDesc = fieldSchema.description || fieldName;
|
|
183
183
|
const fieldType = Array.isArray(fieldSchema.type) ? fieldSchema.type[0] : fieldSchema.type;
|
|
184
|
-
|
|
184
|
+
|
|
185
185
|
let fieldInfo = ` • ${fieldName} (${fieldType})`;
|
|
186
|
-
|
|
186
|
+
|
|
187
187
|
// Add enum values if present
|
|
188
188
|
if (fieldSchema.enum && Array.isArray(fieldSchema.enum)) {
|
|
189
189
|
fieldInfo += ` [${fieldSchema.enum.join(' | ')}]`;
|
|
190
190
|
}
|
|
191
|
-
|
|
191
|
+
|
|
192
192
|
// Add description
|
|
193
193
|
fieldInfo += `: ${fieldDesc}`;
|
|
194
|
-
|
|
194
|
+
|
|
195
195
|
// Mark if this is the current step's focus
|
|
196
196
|
if (stepCollectFields.has(field)) {
|
|
197
197
|
fieldInfo += ` ← FOCUS FOR THIS STEP`;
|
|
198
198
|
}
|
|
199
|
-
|
|
199
|
+
|
|
200
200
|
fieldDescriptions.push(fieldInfo);
|
|
201
201
|
}
|
|
202
202
|
} else {
|
|
@@ -208,7 +208,7 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
|
|
|
208
208
|
fieldDescriptions.push(fieldInfo);
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
|
-
|
|
211
|
+
|
|
212
212
|
if (fieldDescriptions.length > 0) {
|
|
213
213
|
const instruction = [
|
|
214
214
|
`## Data Collection Rules`,
|
|
@@ -231,22 +231,22 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
|
|
|
231
231
|
`- preferredDate: "next Tuesday"`,
|
|
232
232
|
`- preferredTime: "2 PM"`,
|
|
233
233
|
].join('\n');
|
|
234
|
-
|
|
234
|
+
|
|
235
235
|
await pc.addInstruction(instruction);
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
|
-
|
|
238
|
+
|
|
239
239
|
// Add response format instructions with explicit JSON structure
|
|
240
240
|
// Generate example JSON based on actual schema fields
|
|
241
241
|
const exampleFields: string[] = [' "message": "your response to the user"'];
|
|
242
|
-
|
|
242
|
+
|
|
243
243
|
for (const field of allRouteFields) {
|
|
244
244
|
if (agentSchema?.properties) {
|
|
245
245
|
const fieldSchema = agentSchema.properties[field];
|
|
246
246
|
if (fieldSchema) {
|
|
247
247
|
const fieldType = Array.isArray(fieldSchema.type) ? fieldSchema.type[0] : fieldSchema.type;
|
|
248
248
|
let exampleValue = '"value if extracted"';
|
|
249
|
-
|
|
249
|
+
|
|
250
250
|
// Generate type-appropriate example
|
|
251
251
|
if (fieldSchema.enum && Array.isArray(fieldSchema.enum) && fieldSchema.enum.length > 0) {
|
|
252
252
|
exampleValue = `"${fieldSchema.enum[0]}"`;
|
|
@@ -257,7 +257,7 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
|
|
|
257
257
|
} else if (fieldType === 'boolean') {
|
|
258
258
|
exampleValue = 'true';
|
|
259
259
|
}
|
|
260
|
-
|
|
260
|
+
|
|
261
261
|
exampleFields.push(` "${field}": ${exampleValue}`);
|
|
262
262
|
}
|
|
263
263
|
} else {
|
|
@@ -265,7 +265,7 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
|
|
|
265
265
|
exampleFields.push(` "${field}": "extracted value"`);
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
|
-
|
|
268
|
+
|
|
269
269
|
await pc.addInstruction(
|
|
270
270
|
[
|
|
271
271
|
`## Response Format`,
|
|
@@ -277,14 +277,17 @@ export class ResponseEngine<TContext = unknown, TData = unknown> {
|
|
|
277
277
|
``,
|
|
278
278
|
`CRITICAL RULES:`,
|
|
279
279
|
`- Return ONLY the JSON object, no other text`,
|
|
280
|
-
`- The "message" field is REQUIRED and must contain
|
|
281
|
-
`-
|
|
280
|
+
`- The "message" field is REQUIRED and must contain a natural, conversational response directed at the user`,
|
|
281
|
+
`- The "message" MUST read like a human conversation - warm, natural, and contextual`,
|
|
282
|
+
`- NEVER include field names, JSON keys, schema properties, raw data values, or technical/internal information in the "message"`,
|
|
283
|
+
`- NEVER echo back data in the format "fieldName: value" in the "message" - data goes in the JSON fields, not the message`,
|
|
284
|
+
`- Include ALL extracted data fields as separate top-level JSON properties (NOT inside the message text)`,
|
|
282
285
|
`- Only include data fields that were actually mentioned by the user`,
|
|
283
286
|
`- Do not wrap the JSON in markdown code blocks`,
|
|
284
287
|
`- Do not add any explanatory text before or after the JSON`,
|
|
285
288
|
].join('\n')
|
|
286
289
|
);
|
|
287
|
-
|
|
290
|
+
|
|
288
291
|
return pc.build();
|
|
289
292
|
}
|
|
290
293
|
|