signalwire-agents 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +112 -0
- package/README.md +417 -0
- package/dist/AgentBase.d.ts +481 -0
- package/dist/AgentBase.js +1155 -0
- package/dist/AgentBase.js.map +1 -0
- package/dist/AgentServer.d.ts +60 -0
- package/dist/AgentServer.js +128 -0
- package/dist/AgentServer.js.map +1 -0
- package/dist/AuthHandler.d.ts +56 -0
- package/dist/AuthHandler.js +119 -0
- package/dist/AuthHandler.js.map +1 -0
- package/dist/ConfigLoader.d.ts +68 -0
- package/dist/ConfigLoader.js +150 -0
- package/dist/ConfigLoader.js.map +1 -0
- package/dist/ContextBuilder.d.ts +431 -0
- package/dist/ContextBuilder.js +751 -0
- package/dist/ContextBuilder.js.map +1 -0
- package/dist/DataMap.d.ts +179 -0
- package/dist/DataMap.js +321 -0
- package/dist/DataMap.js.map +1 -0
- package/dist/Logger.d.ts +91 -0
- package/dist/Logger.js +191 -0
- package/dist/Logger.js.map +1 -0
- package/dist/PomBuilder.d.ts +144 -0
- package/dist/PomBuilder.js +249 -0
- package/dist/PomBuilder.js.map +1 -0
- package/dist/PromptManager.d.ts +85 -0
- package/dist/PromptManager.js +108 -0
- package/dist/PromptManager.js.map +1 -0
- package/dist/SchemaUtils.d.ts +42 -0
- package/dist/SchemaUtils.js +148 -0
- package/dist/SchemaUtils.js.map +1 -0
- package/dist/ServerlessAdapter.d.ts +100 -0
- package/dist/ServerlessAdapter.js +166 -0
- package/dist/ServerlessAdapter.js.map +1 -0
- package/dist/SessionManager.d.ts +86 -0
- package/dist/SessionManager.js +155 -0
- package/dist/SessionManager.js.map +1 -0
- package/dist/SslConfig.d.ts +77 -0
- package/dist/SslConfig.js +100 -0
- package/dist/SslConfig.js.map +1 -0
- package/dist/SwaigFunction.d.ts +88 -0
- package/dist/SwaigFunction.js +125 -0
- package/dist/SwaigFunction.js.map +1 -0
- package/dist/SwaigFunctionResult.d.ts +442 -0
- package/dist/SwaigFunctionResult.js +735 -0
- package/dist/SwaigFunctionResult.js.map +1 -0
- package/dist/SwmlBuilder.d.ts +37 -0
- package/dist/SwmlBuilder.js +55 -0
- package/dist/SwmlBuilder.js.map +1 -0
- package/dist/cli/agent-loader.d.ts +22 -0
- package/dist/cli/agent-loader.js +106 -0
- package/dist/cli/agent-loader.js.map +1 -0
- package/dist/cli/mock-data.d.ts +37 -0
- package/dist/cli/mock-data.js +79 -0
- package/dist/cli/mock-data.js.map +1 -0
- package/dist/cli/swaig-test.d.ts +32 -0
- package/dist/cli/swaig-test.js +405 -0
- package/dist/cli/swaig-test.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/prefabs/ConciergeAgent.d.ts +64 -0
- package/dist/prefabs/ConciergeAgent.js +188 -0
- package/dist/prefabs/ConciergeAgent.js.map +1 -0
- package/dist/prefabs/FAQBotAgent.d.ts +68 -0
- package/dist/prefabs/FAQBotAgent.js +206 -0
- package/dist/prefabs/FAQBotAgent.js.map +1 -0
- package/dist/prefabs/InfoGathererAgent.d.ts +73 -0
- package/dist/prefabs/InfoGathererAgent.js +202 -0
- package/dist/prefabs/InfoGathererAgent.js.map +1 -0
- package/dist/prefabs/ReceptionistAgent.d.ts +65 -0
- package/dist/prefabs/ReceptionistAgent.js +205 -0
- package/dist/prefabs/ReceptionistAgent.js.map +1 -0
- package/dist/prefabs/SurveyAgent.d.ts +84 -0
- package/dist/prefabs/SurveyAgent.js +324 -0
- package/dist/prefabs/SurveyAgent.js.map +1 -0
- package/dist/prefabs/index.d.ts +13 -0
- package/dist/prefabs/index.js +14 -0
- package/dist/prefabs/index.js.map +1 -0
- package/dist/skills/SkillBase.d.ts +134 -0
- package/dist/skills/SkillBase.js +105 -0
- package/dist/skills/SkillBase.js.map +1 -0
- package/dist/skills/SkillManager.d.ts +83 -0
- package/dist/skills/SkillManager.js +159 -0
- package/dist/skills/SkillManager.js.map +1 -0
- package/dist/skills/SkillRegistry.d.ts +105 -0
- package/dist/skills/SkillRegistry.js +195 -0
- package/dist/skills/SkillRegistry.js.map +1 -0
- package/dist/skills/builtin/api_ninjas_trivia.d.ts +35 -0
- package/dist/skills/builtin/api_ninjas_trivia.js +161 -0
- package/dist/skills/builtin/api_ninjas_trivia.js.map +1 -0
- package/dist/skills/builtin/claude_skills.d.ts +34 -0
- package/dist/skills/builtin/claude_skills.js +156 -0
- package/dist/skills/builtin/claude_skills.js.map +1 -0
- package/dist/skills/builtin/custom_skills.d.ts +59 -0
- package/dist/skills/builtin/custom_skills.js +231 -0
- package/dist/skills/builtin/custom_skills.js.map +1 -0
- package/dist/skills/builtin/datasphere.d.ts +34 -0
- package/dist/skills/builtin/datasphere.js +163 -0
- package/dist/skills/builtin/datasphere.js.map +1 -0
- package/dist/skills/builtin/datasphere_serverless.d.ts +54 -0
- package/dist/skills/builtin/datasphere_serverless.js +155 -0
- package/dist/skills/builtin/datasphere_serverless.js.map +1 -0
- package/dist/skills/builtin/datetime.d.ts +31 -0
- package/dist/skills/builtin/datetime.js +95 -0
- package/dist/skills/builtin/datetime.js.map +1 -0
- package/dist/skills/builtin/google_maps.d.ts +33 -0
- package/dist/skills/builtin/google_maps.js +233 -0
- package/dist/skills/builtin/google_maps.js.map +1 -0
- package/dist/skills/builtin/index.d.ts +28 -0
- package/dist/skills/builtin/index.js +75 -0
- package/dist/skills/builtin/index.js.map +1 -0
- package/dist/skills/builtin/info_gatherer.d.ts +52 -0
- package/dist/skills/builtin/info_gatherer.js +237 -0
- package/dist/skills/builtin/info_gatherer.js.map +1 -0
- package/dist/skills/builtin/joke.d.ts +32 -0
- package/dist/skills/builtin/joke.js +142 -0
- package/dist/skills/builtin/joke.js.map +1 -0
- package/dist/skills/builtin/math.d.ts +33 -0
- package/dist/skills/builtin/math.js +120 -0
- package/dist/skills/builtin/math.js.map +1 -0
- package/dist/skills/builtin/mcp_gateway.d.ts +35 -0
- package/dist/skills/builtin/mcp_gateway.js +85 -0
- package/dist/skills/builtin/mcp_gateway.js.map +1 -0
- package/dist/skills/builtin/native_vector_search.d.ts +44 -0
- package/dist/skills/builtin/native_vector_search.js +248 -0
- package/dist/skills/builtin/native_vector_search.js.map +1 -0
- package/dist/skills/builtin/play_background_file.d.ts +34 -0
- package/dist/skills/builtin/play_background_file.js +135 -0
- package/dist/skills/builtin/play_background_file.js.map +1 -0
- package/dist/skills/builtin/spider.d.ts +34 -0
- package/dist/skills/builtin/spider.js +164 -0
- package/dist/skills/builtin/spider.js.map +1 -0
- package/dist/skills/builtin/swml_transfer.d.ts +44 -0
- package/dist/skills/builtin/swml_transfer.js +204 -0
- package/dist/skills/builtin/swml_transfer.js.map +1 -0
- package/dist/skills/builtin/weather_api.d.ts +34 -0
- package/dist/skills/builtin/weather_api.js +136 -0
- package/dist/skills/builtin/weather_api.js.map +1 -0
- package/dist/skills/builtin/web_search.d.ts +34 -0
- package/dist/skills/builtin/web_search.js +141 -0
- package/dist/skills/builtin/web_search.js.map +1 -0
- package/dist/skills/builtin/wikipedia_search.d.ts +34 -0
- package/dist/skills/builtin/wikipedia_search.js +166 -0
- package/dist/skills/builtin/wikipedia_search.js.map +1 -0
- package/dist/skills/index.d.ts +11 -0
- package/dist/skills/index.js +10 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/docs/agent-guide.md +869 -0
- package/docs/api-reference.md +2419 -0
- package/docs/architecture.md +843 -0
- package/docs/cli-guide.md +579 -0
- package/docs/configuration.md +422 -0
- package/docs/contexts-guide.md +787 -0
- package/docs/datamap-guide.md +1141 -0
- package/docs/prefabs-guide.md +830 -0
- package/docs/security.md +436 -0
- package/docs/serverless-guide.md +513 -0
- package/docs/skills-guide.md +845 -0
- package/docs/swaig-reference.md +1627 -0
- package/examples/call-flow.ts +60 -0
- package/examples/contexts-steps.ts +62 -0
- package/examples/datamap-tools.ts +52 -0
- package/examples/dynamic-config.ts +51 -0
- package/examples/multi-agent.ts +67 -0
- package/examples/pom-prompt.ts +68 -0
- package/examples/simple-agent.ts +33 -0
- package/package.json +35 -0
- package/src/AgentBase.ts +1279 -0
- package/src/AgentServer.ts +149 -0
- package/src/AuthHandler.ts +141 -0
- package/src/ConfigLoader.ts +165 -0
- package/src/ContextBuilder.ts +796 -0
- package/src/DataMap.ts +365 -0
- package/src/Logger.ts +197 -0
- package/src/PomBuilder.ts +298 -0
- package/src/PromptManager.ts +133 -0
- package/src/SchemaUtils.ts +170 -0
- package/src/ServerlessAdapter.ts +218 -0
- package/src/SessionManager.ts +161 -0
- package/src/SslConfig.ts +118 -0
- package/src/SwaigFunction.ts +168 -0
- package/src/SwaigFunctionResult.ts +864 -0
- package/src/SwmlBuilder.ts +62 -0
- package/src/cli/agent-loader.ts +122 -0
- package/src/cli/mock-data.ts +110 -0
- package/src/cli/swaig-test.ts +440 -0
- package/src/index.ts +99 -0
- package/src/prefabs/ConciergeAgent.ts +251 -0
- package/src/prefabs/FAQBotAgent.ts +263 -0
- package/src/prefabs/InfoGathererAgent.ts +276 -0
- package/src/prefabs/ReceptionistAgent.ts +277 -0
- package/src/prefabs/SurveyAgent.ts +413 -0
- package/src/prefabs/index.ts +23 -0
- package/src/skills/SkillBase.ts +184 -0
- package/src/skills/SkillManager.ts +177 -0
- package/src/skills/SkillRegistry.ts +231 -0
- package/src/skills/builtin/api_ninjas_trivia.ts +230 -0
- package/src/skills/builtin/claude_skills.ts +239 -0
- package/src/skills/builtin/custom_skills.ts +326 -0
- package/src/skills/builtin/datasphere.ts +225 -0
- package/src/skills/builtin/datasphere_serverless.ts +194 -0
- package/src/skills/builtin/datetime.ts +115 -0
- package/src/skills/builtin/google_maps.ts +347 -0
- package/src/skills/builtin/index.ts +79 -0
- package/src/skills/builtin/info_gatherer.ts +331 -0
- package/src/skills/builtin/joke.ts +180 -0
- package/src/skills/builtin/math.ts +150 -0
- package/src/skills/builtin/mcp_gateway.ts +99 -0
- package/src/skills/builtin/native_vector_search.ts +327 -0
- package/src/skills/builtin/play_background_file.ts +189 -0
- package/src/skills/builtin/spider.ts +232 -0
- package/src/skills/builtin/swml_transfer.ts +285 -0
- package/src/skills/builtin/weather_api.ts +193 -0
- package/src/skills/builtin/web_search.ts +212 -0
- package/src/skills/builtin/wikipedia_search.ts +248 -0
- package/src/skills/index.ts +12 -0
- package/src/types.ts +99 -0
- package/tests/AgentBase.test.ts +693 -0
- package/tests/AgentServer.test.ts +102 -0
- package/tests/AuthHandler.test.ts +121 -0
- package/tests/ConfigLoader.test.ts +121 -0
- package/tests/DataMap.test.ts +286 -0
- package/tests/Logger.test.ts +218 -0
- package/tests/PomBuilder.test.ts +164 -0
- package/tests/ProxyDetection.test.ts +185 -0
- package/tests/SchemaUtils.test.ts +106 -0
- package/tests/ServerlessAdapter.test.ts +200 -0
- package/tests/SessionManager.test.ts +139 -0
- package/tests/SslConfig.test.ts +97 -0
- package/tests/SwaigFunctionResult.test.ts +298 -0
- package/tests/cli/mock-data.test.ts +94 -0
- package/tests/cli/swaig-test.test.ts +96 -0
- package/tests/prefabs/prefabs.test.ts +854 -0
- package/tests/setup.ts +6 -0
- package/tests/skills/SkillBase.test.ts +118 -0
- package/tests/skills/SkillManager.test.ts +164 -0
- package/tests/skills/SkillRegistry.test.ts +124 -0
- package/tests/skills/builtin.test.ts +924 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConciergeAgent - A prefab agent that provides multi-department routing
|
|
3
|
+
* with a knowledge base of department info, hours, and transfer capabilities.
|
|
4
|
+
*/
|
|
5
|
+
import { AgentBase } from '../AgentBase.js';
|
|
6
|
+
import { SwaigFunctionResult } from '../SwaigFunctionResult.js';
|
|
7
|
+
// ── Agent ───────────────────────────────────────────────────────────────────
|
|
8
|
+
/** Prefab agent that provides multi-department routing with a knowledge base of department info, hours, and transfer capabilities. */
|
|
9
|
+
export class ConciergeAgent extends AgentBase {
|
|
10
|
+
departments;
|
|
11
|
+
companyName;
|
|
12
|
+
generalInfo;
|
|
13
|
+
afterHoursMessage;
|
|
14
|
+
/** Declarative prompt sections merged by AgentBase constructor. */
|
|
15
|
+
static PROMPT_SECTIONS = [
|
|
16
|
+
{
|
|
17
|
+
title: 'Role',
|
|
18
|
+
body: 'You are a professional concierge agent. Help callers find the right department, provide information about available services, and transfer calls when requested.',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
title: 'Rules',
|
|
22
|
+
bullets: [
|
|
23
|
+
'Greet the caller warmly and ask how you can help.',
|
|
24
|
+
'Use list_departments to describe available departments if the caller is unsure where to go.',
|
|
25
|
+
'Use get_department_info to provide detailed information about a specific department.',
|
|
26
|
+
'Use transfer_to_department to connect the caller to the right department.',
|
|
27
|
+
'If a department has hours of operation listed, mention them before transferring.',
|
|
28
|
+
'If a department does not have a transfer number, inform the caller and offer alternatives.',
|
|
29
|
+
'Be polite, professional, and efficient.',
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Create a ConciergeAgent with the specified departments and company info.
|
|
35
|
+
* @param config - Configuration including departments, company name, and after-hours message.
|
|
36
|
+
*/
|
|
37
|
+
constructor(config) {
|
|
38
|
+
const agentName = config.name ?? 'Concierge';
|
|
39
|
+
super({
|
|
40
|
+
name: agentName,
|
|
41
|
+
...config.agentOptions,
|
|
42
|
+
});
|
|
43
|
+
this.departments = config.departments;
|
|
44
|
+
this.companyName = config.companyName ?? 'our company';
|
|
45
|
+
this.generalInfo = config.generalInfo ?? '';
|
|
46
|
+
this.afterHoursMessage = config.afterHoursMessage ?? 'This department is currently closed. Please try again during business hours.';
|
|
47
|
+
// Company intro section
|
|
48
|
+
let introBody = `You are the concierge for ${this.companyName}.`;
|
|
49
|
+
if (this.generalInfo) {
|
|
50
|
+
introBody += ` Company information: ${this.generalInfo}`;
|
|
51
|
+
}
|
|
52
|
+
this.promptAddSection('Company', { body: introBody });
|
|
53
|
+
// Build department overview section
|
|
54
|
+
const deptBullets = this.departments.map((dept) => {
|
|
55
|
+
let desc = `${dept.name}: ${dept.description}`;
|
|
56
|
+
if (dept.hoursOfOperation)
|
|
57
|
+
desc += ` (Hours: ${dept.hoursOfOperation})`;
|
|
58
|
+
if (dept.transferNumber)
|
|
59
|
+
desc += ' [transfer available]';
|
|
60
|
+
return desc;
|
|
61
|
+
});
|
|
62
|
+
this.promptAddSection('Available Departments', { bullets: deptBullets });
|
|
63
|
+
// Speech recognition hints from department names and keywords
|
|
64
|
+
const hints = this.departments.map((d) => d.name);
|
|
65
|
+
for (const dept of this.departments) {
|
|
66
|
+
if (dept.keywords)
|
|
67
|
+
hints.push(...dept.keywords);
|
|
68
|
+
}
|
|
69
|
+
this.addHints(hints);
|
|
70
|
+
// Register tools after all fields are initialized
|
|
71
|
+
this.defineTools();
|
|
72
|
+
}
|
|
73
|
+
// ── Department helpers ────────────────────────────────────────────────
|
|
74
|
+
findDepartment(name) {
|
|
75
|
+
const normalized = name.toLowerCase().trim();
|
|
76
|
+
return this.departments.find((d) => d.name.toLowerCase() === normalized ||
|
|
77
|
+
d.keywords?.some((k) => k.toLowerCase() === normalized));
|
|
78
|
+
}
|
|
79
|
+
// ── Tool registration ─────────────────────────────────────────────────
|
|
80
|
+
/** Register the list_departments, get_department_info, and transfer_to_department SWAIG tools. */
|
|
81
|
+
defineTools() {
|
|
82
|
+
// Tool: list_departments
|
|
83
|
+
this.defineTool({
|
|
84
|
+
name: 'list_departments',
|
|
85
|
+
description: `List all available departments at ${this.companyName} with their descriptions and hours of operation.`,
|
|
86
|
+
parameters: {
|
|
87
|
+
type: 'object',
|
|
88
|
+
properties: {},
|
|
89
|
+
},
|
|
90
|
+
handler: () => {
|
|
91
|
+
if (this.departments.length === 0) {
|
|
92
|
+
return new SwaigFunctionResult('No departments are currently configured.');
|
|
93
|
+
}
|
|
94
|
+
const lines = this.departments.map((dept) => {
|
|
95
|
+
let line = `${dept.name}: ${dept.description}`;
|
|
96
|
+
if (dept.hoursOfOperation)
|
|
97
|
+
line += ` | Hours: ${dept.hoursOfOperation}`;
|
|
98
|
+
if (!dept.transferNumber)
|
|
99
|
+
line += ' | (no direct transfer available)';
|
|
100
|
+
return line;
|
|
101
|
+
});
|
|
102
|
+
return new SwaigFunctionResult(`Available departments at ${this.companyName}:\n${lines.join('\n')}`);
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
// Tool: get_department_info
|
|
106
|
+
this.defineTool({
|
|
107
|
+
name: 'get_department_info',
|
|
108
|
+
description: 'Get detailed information about a specific department including description, hours of operation, and transfer availability.',
|
|
109
|
+
parameters: {
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
department_name: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
description: 'The name of the department to look up.',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
required: ['department_name'],
|
|
118
|
+
},
|
|
119
|
+
handler: (_args) => {
|
|
120
|
+
const deptName = _args['department_name'];
|
|
121
|
+
if (!deptName) {
|
|
122
|
+
return new SwaigFunctionResult('Please provide a department name.');
|
|
123
|
+
}
|
|
124
|
+
const dept = this.findDepartment(deptName);
|
|
125
|
+
if (!dept) {
|
|
126
|
+
const available = this.departments.map((d) => d.name).join(', ');
|
|
127
|
+
return new SwaigFunctionResult(`Department "${deptName}" not found. Available departments: ${available}`);
|
|
128
|
+
}
|
|
129
|
+
let info = `Department: ${dept.name}\nDescription: ${dept.description}`;
|
|
130
|
+
if (dept.hoursOfOperation)
|
|
131
|
+
info += `\nHours: ${dept.hoursOfOperation}`;
|
|
132
|
+
if (dept.transferNumber) {
|
|
133
|
+
info += '\nTransfer: available';
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
info += '\nTransfer: not available (no phone number configured)';
|
|
137
|
+
}
|
|
138
|
+
if (dept.keywords && dept.keywords.length > 0) {
|
|
139
|
+
info += `\nRelated topics: ${dept.keywords.join(', ')}`;
|
|
140
|
+
}
|
|
141
|
+
return new SwaigFunctionResult(info);
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
// Tool: transfer_to_department
|
|
145
|
+
this.defineTool({
|
|
146
|
+
name: 'transfer_to_department',
|
|
147
|
+
description: 'Transfer the caller to a specific department. Only works if the department has a transfer number configured.',
|
|
148
|
+
parameters: {
|
|
149
|
+
type: 'object',
|
|
150
|
+
properties: {
|
|
151
|
+
department_name: {
|
|
152
|
+
type: 'string',
|
|
153
|
+
description: 'The name of the department to transfer to.',
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
required: ['department_name'],
|
|
157
|
+
},
|
|
158
|
+
handler: (_args) => {
|
|
159
|
+
const deptName = _args['department_name'];
|
|
160
|
+
if (!deptName) {
|
|
161
|
+
return new SwaigFunctionResult('Please provide a department name.');
|
|
162
|
+
}
|
|
163
|
+
const dept = this.findDepartment(deptName);
|
|
164
|
+
if (!dept) {
|
|
165
|
+
const available = this.departments.map((d) => d.name).join(', ');
|
|
166
|
+
return new SwaigFunctionResult(`Department "${deptName}" not found. Available departments: ${available}`);
|
|
167
|
+
}
|
|
168
|
+
if (!dept.transferNumber) {
|
|
169
|
+
return new SwaigFunctionResult(`The ${dept.name} department does not have a direct transfer number. ${this.afterHoursMessage}`);
|
|
170
|
+
}
|
|
171
|
+
const result = new SwaigFunctionResult(`Transferring you to the ${dept.name} department now.`);
|
|
172
|
+
result.connect(dept.transferNumber);
|
|
173
|
+
return result;
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// ── Factory function ────────────────────────────────────────────────────────
|
|
179
|
+
/**
|
|
180
|
+
* Factory function that creates and returns a new ConciergeAgent.
|
|
181
|
+
* @param config - Configuration for the concierge agent.
|
|
182
|
+
* @returns A configured ConciergeAgent instance.
|
|
183
|
+
*/
|
|
184
|
+
export function createConciergeAgent(config) {
|
|
185
|
+
return new ConciergeAgent(config);
|
|
186
|
+
}
|
|
187
|
+
export default ConciergeAgent;
|
|
188
|
+
//# sourceMappingURL=ConciergeAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConciergeAgent.js","sourceRoot":"","sources":["../../src/prefabs/ConciergeAgent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FAQBotAgent - A prefab agent that answers frequently asked questions using
|
|
3
|
+
* keyword/word-overlap matching with configurable similarity thresholds
|
|
4
|
+
* and optional escalation to a live agent.
|
|
5
|
+
*/
|
|
6
|
+
import { AgentBase } from '../AgentBase.js';
|
|
7
|
+
import type { AgentOptions } from '../types.js';
|
|
8
|
+
export interface FAQEntry {
|
|
9
|
+
/** The representative question text. */
|
|
10
|
+
question: string;
|
|
11
|
+
/** The answer to provide when this FAQ matches. */
|
|
12
|
+
answer: string;
|
|
13
|
+
/** Additional keywords to boost matching accuracy. */
|
|
14
|
+
keywords?: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface FAQBotConfig {
|
|
17
|
+
/** Agent display name. */
|
|
18
|
+
name?: string;
|
|
19
|
+
/** List of FAQ entries for the knowledge base. */
|
|
20
|
+
faqs: FAQEntry[];
|
|
21
|
+
/** Minimum match score (0-1) for an FAQ to be considered a match. Default 0.5. */
|
|
22
|
+
threshold?: number;
|
|
23
|
+
/** Message spoken when no FAQ matches the query. */
|
|
24
|
+
escalationMessage?: string;
|
|
25
|
+
/** Phone number to transfer to on escalation. If not set, escalate tool is not registered. */
|
|
26
|
+
escalationNumber?: string;
|
|
27
|
+
/** Additional AgentBase options forwarded to super(). */
|
|
28
|
+
agentOptions?: Partial<AgentOptions>;
|
|
29
|
+
}
|
|
30
|
+
/** Prefab agent that answers frequently asked questions using keyword matching with optional escalation to a live agent. */
|
|
31
|
+
export declare class FAQBotAgent extends AgentBase {
|
|
32
|
+
private faqs;
|
|
33
|
+
private threshold;
|
|
34
|
+
private escalationMessage;
|
|
35
|
+
private escalationNumber;
|
|
36
|
+
/** Declarative prompt sections merged by AgentBase constructor. */
|
|
37
|
+
static PROMPT_SECTIONS: ({
|
|
38
|
+
title: string;
|
|
39
|
+
body: string;
|
|
40
|
+
bullets?: undefined;
|
|
41
|
+
} | {
|
|
42
|
+
title: string;
|
|
43
|
+
bullets: string[];
|
|
44
|
+
body?: undefined;
|
|
45
|
+
})[];
|
|
46
|
+
/**
|
|
47
|
+
* Create a FAQBotAgent with the specified FAQ entries and matching threshold.
|
|
48
|
+
* @param config - Configuration including FAQ entries, threshold, and escalation settings.
|
|
49
|
+
*/
|
|
50
|
+
constructor(config: FAQBotConfig);
|
|
51
|
+
/**
|
|
52
|
+
* Compute a word-overlap similarity score between a query and an FAQ entry.
|
|
53
|
+
* Combines question text similarity and keyword overlap.
|
|
54
|
+
* Returns a value between 0 and 1.
|
|
55
|
+
*/
|
|
56
|
+
private computeMatchScore;
|
|
57
|
+
private tokenize;
|
|
58
|
+
private wordOverlap;
|
|
59
|
+
/** Register the search_faq and optional escalate SWAIG tools. */
|
|
60
|
+
protected defineTools(): void;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Factory function that creates and returns a new FAQBotAgent.
|
|
64
|
+
* @param config - Configuration for the FAQ bot agent.
|
|
65
|
+
* @returns A configured FAQBotAgent instance.
|
|
66
|
+
*/
|
|
67
|
+
export declare function createFAQBotAgent(config: FAQBotConfig): FAQBotAgent;
|
|
68
|
+
export default FAQBotAgent;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FAQBotAgent - A prefab agent that answers frequently asked questions using
|
|
3
|
+
* keyword/word-overlap matching with configurable similarity thresholds
|
|
4
|
+
* and optional escalation to a live agent.
|
|
5
|
+
*/
|
|
6
|
+
import { AgentBase } from '../AgentBase.js';
|
|
7
|
+
import { SwaigFunctionResult } from '../SwaigFunctionResult.js';
|
|
8
|
+
// ── Agent ───────────────────────────────────────────────────────────────────
|
|
9
|
+
/** Prefab agent that answers frequently asked questions using keyword matching with optional escalation to a live agent. */
|
|
10
|
+
export class FAQBotAgent extends AgentBase {
|
|
11
|
+
faqs;
|
|
12
|
+
threshold;
|
|
13
|
+
escalationMessage;
|
|
14
|
+
escalationNumber;
|
|
15
|
+
/** Declarative prompt sections merged by AgentBase constructor. */
|
|
16
|
+
static PROMPT_SECTIONS = [
|
|
17
|
+
{
|
|
18
|
+
title: 'Role',
|
|
19
|
+
body: 'You are a helpful FAQ assistant. Answer the caller\'s questions by searching the knowledge base. If you cannot find a satisfactory answer, offer to escalate to a human agent.',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
title: 'Rules',
|
|
23
|
+
bullets: [
|
|
24
|
+
'Always use the search_faq tool to find answers. Do not make up answers.',
|
|
25
|
+
'If the search returns a good match, relay the answer naturally to the caller.',
|
|
26
|
+
'If the match score is low or no match is found, let the caller know and offer to escalate.',
|
|
27
|
+
'Be concise and helpful in your responses.',
|
|
28
|
+
'If the caller asks a follow-up, search again with the new query.',
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Create a FAQBotAgent with the specified FAQ entries and matching threshold.
|
|
34
|
+
* @param config - Configuration including FAQ entries, threshold, and escalation settings.
|
|
35
|
+
*/
|
|
36
|
+
constructor(config) {
|
|
37
|
+
const agentName = config.name ?? 'FAQBot';
|
|
38
|
+
super({
|
|
39
|
+
name: agentName,
|
|
40
|
+
...config.agentOptions,
|
|
41
|
+
});
|
|
42
|
+
this.faqs = config.faqs;
|
|
43
|
+
this.threshold = config.threshold ?? 0.5;
|
|
44
|
+
this.escalationMessage = config.escalationMessage ?? 'I\'m sorry, I couldn\'t find an answer to your question. Let me transfer you to someone who can help.';
|
|
45
|
+
this.escalationNumber = config.escalationNumber ?? null;
|
|
46
|
+
// Build FAQ topics section for the prompt
|
|
47
|
+
const topicBullets = this.faqs.map((faq) => {
|
|
48
|
+
const kw = faq.keywords ? ` (keywords: ${faq.keywords.join(', ')})` : '';
|
|
49
|
+
return `${faq.question}${kw}`;
|
|
50
|
+
});
|
|
51
|
+
this.promptAddSection('Available FAQ Topics', { bullets: topicBullets });
|
|
52
|
+
// Add hints from FAQ keywords for speech recognition
|
|
53
|
+
const allKeywords = [];
|
|
54
|
+
for (const faq of this.faqs) {
|
|
55
|
+
if (faq.keywords)
|
|
56
|
+
allKeywords.push(...faq.keywords);
|
|
57
|
+
}
|
|
58
|
+
if (allKeywords.length > 0) {
|
|
59
|
+
this.addHints(allKeywords);
|
|
60
|
+
}
|
|
61
|
+
// Register tools after all fields are initialized
|
|
62
|
+
this.defineTools();
|
|
63
|
+
}
|
|
64
|
+
// ── Matching engine ───────────────────────────────────────────────────
|
|
65
|
+
/**
|
|
66
|
+
* Compute a word-overlap similarity score between a query and an FAQ entry.
|
|
67
|
+
* Combines question text similarity and keyword overlap.
|
|
68
|
+
* Returns a value between 0 and 1.
|
|
69
|
+
*/
|
|
70
|
+
computeMatchScore(query, faq) {
|
|
71
|
+
const queryWords = this.tokenize(query);
|
|
72
|
+
if (queryWords.length === 0)
|
|
73
|
+
return 0;
|
|
74
|
+
// Score against the question text
|
|
75
|
+
const questionWords = this.tokenize(faq.question);
|
|
76
|
+
const questionOverlap = this.wordOverlap(queryWords, questionWords);
|
|
77
|
+
// Score against keywords
|
|
78
|
+
let keywordScore = 0;
|
|
79
|
+
if (faq.keywords && faq.keywords.length > 0) {
|
|
80
|
+
const keywordTokens = faq.keywords.map((k) => k.toLowerCase().trim());
|
|
81
|
+
const queryLower = query.toLowerCase();
|
|
82
|
+
let keywordHits = 0;
|
|
83
|
+
for (const kw of keywordTokens) {
|
|
84
|
+
if (queryLower.includes(kw)) {
|
|
85
|
+
keywordHits++;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
keywordScore = keywordTokens.length > 0 ? keywordHits / keywordTokens.length : 0;
|
|
89
|
+
}
|
|
90
|
+
// Weighted combination: 60% question overlap, 40% keyword score
|
|
91
|
+
return faq.keywords && faq.keywords.length > 0
|
|
92
|
+
? questionOverlap * 0.6 + keywordScore * 0.4
|
|
93
|
+
: questionOverlap;
|
|
94
|
+
}
|
|
95
|
+
tokenize(text) {
|
|
96
|
+
return text
|
|
97
|
+
.toLowerCase()
|
|
98
|
+
.replace(/[^a-z0-9\s]/g, ' ')
|
|
99
|
+
.split(/\s+/)
|
|
100
|
+
.filter((w) => w.length > 1 && !STOP_WORDS.has(w));
|
|
101
|
+
}
|
|
102
|
+
wordOverlap(queryWords, targetWords) {
|
|
103
|
+
if (queryWords.length === 0 || targetWords.length === 0)
|
|
104
|
+
return 0;
|
|
105
|
+
const targetSet = new Set(targetWords);
|
|
106
|
+
let matches = 0;
|
|
107
|
+
for (const word of queryWords) {
|
|
108
|
+
if (targetSet.has(word))
|
|
109
|
+
matches++;
|
|
110
|
+
}
|
|
111
|
+
// Normalize by the smaller set to be lenient
|
|
112
|
+
const divisor = Math.min(queryWords.length, targetWords.length);
|
|
113
|
+
return divisor > 0 ? matches / divisor : 0;
|
|
114
|
+
}
|
|
115
|
+
// ── Tool registration ─────────────────────────────────────────────────
|
|
116
|
+
/** Register the search_faq and optional escalate SWAIG tools. */
|
|
117
|
+
defineTools() {
|
|
118
|
+
// Tool: search_faq
|
|
119
|
+
this.defineTool({
|
|
120
|
+
name: 'search_faq',
|
|
121
|
+
description: 'Search the FAQ knowledge base for an answer to the caller\'s question. Returns the best matching FAQ entry with a confidence score.',
|
|
122
|
+
parameters: {
|
|
123
|
+
type: 'object',
|
|
124
|
+
properties: {
|
|
125
|
+
query: {
|
|
126
|
+
type: 'string',
|
|
127
|
+
description: 'The caller\'s question or search query.',
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
required: ['query'],
|
|
131
|
+
},
|
|
132
|
+
handler: (_args) => {
|
|
133
|
+
const query = _args['query'];
|
|
134
|
+
if (!query) {
|
|
135
|
+
return new SwaigFunctionResult('A query is required to search the FAQ.');
|
|
136
|
+
}
|
|
137
|
+
// Score all FAQs
|
|
138
|
+
const scored = this.faqs.map((faq) => ({
|
|
139
|
+
faq,
|
|
140
|
+
score: this.computeMatchScore(query, faq),
|
|
141
|
+
}));
|
|
142
|
+
// Sort by score descending
|
|
143
|
+
scored.sort((a, b) => b.score - a.score);
|
|
144
|
+
const best = scored[0];
|
|
145
|
+
if (!best || best.score < this.threshold) {
|
|
146
|
+
return new SwaigFunctionResult(`No FAQ matched the query "${query}" with sufficient confidence (best score: ${best ? best.score.toFixed(2) : '0.00'}, threshold: ${this.threshold.toFixed(2)}). ${this.escalationMessage}`);
|
|
147
|
+
}
|
|
148
|
+
// Return the best match
|
|
149
|
+
let response = `FAQ Match (confidence: ${best.score.toFixed(2)}): Q: "${best.faq.question}" A: ${best.faq.answer}`;
|
|
150
|
+
// If there are close runner-ups, mention them
|
|
151
|
+
const runnerUps = scored.filter((s, i) => i > 0 && s.score >= this.threshold);
|
|
152
|
+
if (runnerUps.length > 0) {
|
|
153
|
+
const alsoStr = runnerUps
|
|
154
|
+
.slice(0, 2)
|
|
155
|
+
.map((s) => `"${s.faq.question}" (${s.score.toFixed(2)})`)
|
|
156
|
+
.join(', ');
|
|
157
|
+
response += ` Also related: ${alsoStr}`;
|
|
158
|
+
}
|
|
159
|
+
return new SwaigFunctionResult(response);
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
// Tool: escalate (only if escalation number is configured)
|
|
163
|
+
if (this.escalationNumber) {
|
|
164
|
+
this.defineTool({
|
|
165
|
+
name: 'escalate',
|
|
166
|
+
description: 'Transfer the caller to a live agent when the FAQ knowledge base cannot answer their question.',
|
|
167
|
+
parameters: {
|
|
168
|
+
type: 'object',
|
|
169
|
+
properties: {
|
|
170
|
+
reason: {
|
|
171
|
+
type: 'string',
|
|
172
|
+
description: 'The reason for escalation.',
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
handler: (_args) => {
|
|
177
|
+
const reason = _args['reason'] || 'Caller needs assistance beyond FAQ';
|
|
178
|
+
const result = new SwaigFunctionResult(`Transferring caller to a live agent. Reason: ${reason}`);
|
|
179
|
+
result.connect(this.escalationNumber);
|
|
180
|
+
return result;
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// ── Common English stop words filtered from matching ────────────────────────
|
|
187
|
+
const STOP_WORDS = new Set([
|
|
188
|
+
'a', 'an', 'the', 'is', 'it', 'to', 'in', 'of', 'and', 'or', 'for',
|
|
189
|
+
'on', 'at', 'by', 'do', 'if', 'my', 'so', 'up', 'am', 'as', 'be',
|
|
190
|
+
'he', 'me', 'we', 'no', 'not', 'are', 'was', 'has', 'had', 'how',
|
|
191
|
+
'its', 'can', 'did', 'get', 'but', 'you', 'her', 'him', 'his', 'she',
|
|
192
|
+
'our', 'who', 'this', 'that', 'what', 'with', 'have', 'from', 'will',
|
|
193
|
+
'your', 'they', 'them', 'been', 'does', 'just', 'than', 'when', 'which',
|
|
194
|
+
'would', 'could', 'should', 'about', 'their', 'there', 'these', 'those',
|
|
195
|
+
]);
|
|
196
|
+
// ── Factory function ────────────────────────────────────────────────────────
|
|
197
|
+
/**
|
|
198
|
+
* Factory function that creates and returns a new FAQBotAgent.
|
|
199
|
+
* @param config - Configuration for the FAQ bot agent.
|
|
200
|
+
* @returns A configured FAQBotAgent instance.
|
|
201
|
+
*/
|
|
202
|
+
export function createFAQBotAgent(config) {
|
|
203
|
+
return new FAQBotAgent(config);
|
|
204
|
+
}
|
|
205
|
+
export default FAQBotAgent;
|
|
206
|
+
//# sourceMappingURL=FAQBotAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FAQBotAgent.js","sourceRoot":"","sources":["../../src/prefabs/FAQBotAgent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AA6BhE,+EAA+E;AAE/E,4HAA4H;AAC5H,MAAM,OAAO,WAAY,SAAQ,SAAS;IAChC,IAAI,CAAa;IACjB,SAAS,CAAS;IAClB,iBAAiB,CAAS;IAC1B,gBAAgB,CAAgB;IAExC,mEAAmE;IACnE,MAAM,CAAU,eAAe,GAAG;QAChC;YACE,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,gLAAgL;SACvL;QACD;YACE,KAAK,EAAE,OAAO;YACd,OAAO,EAAE;gBACP,yEAAyE;gBACzE,+EAA+E;gBAC/E,4FAA4F;gBAC5F,2CAA2C;gBAC3C,kEAAkE;aACnE;SACF;KACF,CAAC;IAEF;;;OAGG;IACH,YAAY,MAAoB;QAC9B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,IAAI,QAAQ,CAAC;QAC1C,KAAK,CAAC;YACJ,IAAI,EAAE,SAAS;YACf,GAAG,MAAM,CAAC,YAAY;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC;QACzC,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,IAAI,uGAAuG,CAAC;QAC7J,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,IAAI,CAAC;QAExD,0CAA0C;QAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACzC,MAAM,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,OAAO,GAAG,GAAG,CAAC,QAAQ,GAAG,EAAE,EAAE,CAAC;QAChC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;QAEzE,qDAAqD;QACrD,MAAM,WAAW,GAAa,EAAE,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,GAAG,CAAC,QAAQ;gBAAE,WAAW,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC7B,CAAC;QAED,kDAAkD;QAClD,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED,yEAAyE;IAEzE;;;;OAIG;IACK,iBAAiB,CAAC,KAAa,EAAE,GAAa;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAEtC,kCAAkC;QAClC,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAEpE,yBAAyB;QACzB,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,aAAa,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YACtE,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YACvC,IAAI,WAAW,GAAG,CAAC,CAAC;YACpB,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;gBAC/B,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC5B,WAAW,EAAE,CAAC;gBAChB,CAAC;YACH,CAAC;YACD,YAAY,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACnF,CAAC;QAED,gEAAgE;QAChE,OAAO,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;YAC5C,CAAC,CAAC,eAAe,GAAG,GAAG,GAAG,YAAY,GAAG,GAAG;YAC5C,CAAC,CAAC,eAAe,CAAC;IACtB,CAAC;IAEO,QAAQ,CAAC,IAAY;QAC3B,OAAO,IAAI;aACR,WAAW,EAAE;aACb,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;aAC5B,KAAK,CAAC,KAAK,CAAC;aACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IAEO,WAAW,CAAC,UAAoB,EAAE,WAAqB;QAC7D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAClE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;QACvC,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO,EAAE,CAAC;QACrC,CAAC;QACD,6CAA6C;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAChE,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,yEAAyE;IAEzE,iEAAiE;IAC9C,WAAW;QAC5B,mBAAmB;QACnB,IAAI,CAAC,UAAU,CAAC;YACd,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,qIAAqI;YAClJ,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,yCAAyC;qBACvD;iBACF;gBACD,QAAQ,EAAE,CAAC,OAAO,CAAC;aACpB;YACD,OAAO,EAAE,CAAC,KAA8B,EAAE,EAAE;gBAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAW,CAAC;gBACvC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,OAAO,IAAI,mBAAmB,CAAC,wCAAwC,CAAC,CAAC;gBAC3E,CAAC;gBAED,iBAAiB;gBACjB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBACrC,GAAG;oBACH,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC;iBAC1C,CAAC,CAAC,CAAC;gBAEJ,2BAA2B;gBAC3B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;gBAEzC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBAEvB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;oBACzC,OAAO,IAAI,mBAAmB,CAC5B,6BAA6B,KAAK,6CAA6C,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,gBAAgB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAC5L,CAAC;gBACJ,CAAC;gBAED,wBAAwB;gBACxB,IAAI,QAAQ,GAAG,0BAA0B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,GAAG,CAAC,QAAQ,QAAQ,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;gBAEnH,8CAA8C;gBAC9C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC9E,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzB,MAAM,OAAO,GAAG,SAAS;yBACtB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;yBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;yBACzD,IAAI,CAAC,IAAI,CAAC,CAAC;oBACd,QAAQ,IAAI,kBAAkB,OAAO,EAAE,CAAC;gBAC1C,CAAC;gBAED,OAAO,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAC3C,CAAC;SACF,CAAC,CAAC;QAEH,2DAA2D;QAC3D,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,UAAU,CAAC;gBACd,IAAI,EAAE,UAAU;gBAChB,WAAW,EAAE,+FAA+F;gBAC5G,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,MAAM,EAAE;4BACN,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,4BAA4B;yBAC1C;qBACF;iBACF;gBACD,OAAO,EAAE,CAAC,KAA8B,EAAE,EAAE;oBAC1C,MAAM,MAAM,GAAI,KAAK,CAAC,QAAQ,CAAY,IAAI,oCAAoC,CAAC;oBACnF,MAAM,MAAM,GAAG,IAAI,mBAAmB,CACpC,gDAAgD,MAAM,EAAE,CACzD,CAAC;oBACF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAiB,CAAC,CAAC;oBACvC,OAAO,MAAM,CAAC;gBAChB,CAAC;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;;AAGH,+EAA+E;AAE/E,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK;IAClE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAChE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IAChE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IACpE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACpE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IACvE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;CACxE,CAAC,CAAC;AAEH,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAoB;IACpD,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InfoGathererAgent - A prefab agent that sequentially collects information
|
|
3
|
+
* from callers through conversational interaction.
|
|
4
|
+
*
|
|
5
|
+
* Tracks fields per call, validates with optional regex patterns, and fires
|
|
6
|
+
* an onComplete callback once all required fields are gathered.
|
|
7
|
+
*/
|
|
8
|
+
import { AgentBase } from '../AgentBase.js';
|
|
9
|
+
import type { AgentOptions } from '../types.js';
|
|
10
|
+
export interface InfoGathererField {
|
|
11
|
+
/** Unique field name (used as key in collected data). */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Human-readable description shown to the AI agent. */
|
|
14
|
+
description: string;
|
|
15
|
+
/** Whether this field must be collected before completion. Default true. */
|
|
16
|
+
required?: boolean;
|
|
17
|
+
/** Optional validation pattern. String is compiled to RegExp. */
|
|
18
|
+
validation?: RegExp | string;
|
|
19
|
+
}
|
|
20
|
+
export interface InfoGathererConfig {
|
|
21
|
+
/** Agent display name. */
|
|
22
|
+
name?: string;
|
|
23
|
+
/** Fields to collect from the caller. */
|
|
24
|
+
fields: InfoGathererField[];
|
|
25
|
+
/** Opening message the agent speaks when call starts. */
|
|
26
|
+
introMessage?: string;
|
|
27
|
+
/** Message spoken after all required fields are gathered. */
|
|
28
|
+
confirmationMessage?: string;
|
|
29
|
+
/** Callback fired when all required fields have been collected. */
|
|
30
|
+
onComplete?: (data: Record<string, string>) => void | Promise<void>;
|
|
31
|
+
/** Additional AgentBase options forwarded to super(). */
|
|
32
|
+
agentOptions?: Partial<AgentOptions>;
|
|
33
|
+
}
|
|
34
|
+
/** Prefab agent that sequentially collects named fields from a caller with optional validation and completion callback. */
|
|
35
|
+
export declare class InfoGathererAgent extends AgentBase {
|
|
36
|
+
private fields;
|
|
37
|
+
private introMessage;
|
|
38
|
+
private confirmationMessage;
|
|
39
|
+
private onCompleteCallback?;
|
|
40
|
+
private sessions;
|
|
41
|
+
/**
|
|
42
|
+
* Declarative prompt sections merged by AgentBase constructor.
|
|
43
|
+
* Additional dynamic sections are added in the constructor body below.
|
|
44
|
+
*/
|
|
45
|
+
static PROMPT_SECTIONS: ({
|
|
46
|
+
title: string;
|
|
47
|
+
body: string;
|
|
48
|
+
bullets?: undefined;
|
|
49
|
+
} | {
|
|
50
|
+
title: string;
|
|
51
|
+
bullets: string[];
|
|
52
|
+
body?: undefined;
|
|
53
|
+
})[];
|
|
54
|
+
/**
|
|
55
|
+
* Create an InfoGathererAgent with the specified fields and callbacks.
|
|
56
|
+
* @param config - Configuration including fields to collect, messages, and completion callback.
|
|
57
|
+
*/
|
|
58
|
+
constructor(config: InfoGathererConfig);
|
|
59
|
+
private getSession;
|
|
60
|
+
private getFieldByName;
|
|
61
|
+
private validateValue;
|
|
62
|
+
private getRequiredFields;
|
|
63
|
+
private allRequiredCollected;
|
|
64
|
+
/** Register the save_field and get_status SWAIG tools. */
|
|
65
|
+
protected defineTools(): void;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Factory function that creates and returns a new InfoGathererAgent.
|
|
69
|
+
* @param config - Configuration for the info gatherer agent.
|
|
70
|
+
* @returns A configured InfoGathererAgent instance.
|
|
71
|
+
*/
|
|
72
|
+
export declare function createInfoGathererAgent(config: InfoGathererConfig): InfoGathererAgent;
|
|
73
|
+
export default InfoGathererAgent;
|