@guava-ai/guava-sdk 0.25.0 → 0.27.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/dist/src/agent.d.ts +4 -1
- package/dist/src/agent.js +97 -27
- package/dist/src/agent.js.map +1 -1
- package/dist/src/call.d.ts +2 -0
- package/dist/src/call.js +18 -0
- package/dist/src/call.js.map +1 -1
- package/dist/src/client.d.ts +0 -22
- package/dist/src/client.js +0 -155
- package/dist/src/client.js.map +1 -1
- package/dist/src/commands.d.ts +73 -0
- package/dist/src/commands.js +12 -1
- package/dist/src/commands.js.map +1 -1
- package/dist/src/events.d.ts +2 -1
- package/dist/src/events.js +20 -2
- package/dist/src/events.js.map +1 -1
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +1 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/socket/client.js +10 -0
- package/dist/src/socket/client.js.map +1 -1
- package/dist/src/telemetry.js +1 -1
- package/dist/src/telemetry.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/examples/README.md +7 -6
- package/package.json +1 -1
- package/src/agent.ts +117 -26
- package/src/call.ts +25 -0
- package/src/client.ts +0 -197
- package/src/commands.ts +15 -0
- package/src/events.ts +20 -18
- package/src/index.ts +0 -1
- package/src/socket/client.ts +22 -0
- package/src/telemetry.ts +1 -1
- package/src/version.ts +1 -1
- package/dist/src/call-controller.d.ts +0 -137
- package/dist/src/call-controller.js +0 -436
- package/dist/src/call-controller.js.map +0 -1
- package/src/call-controller.ts +0 -451
package/src/telemetry.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { Client } from "./client.ts";
|
|
|
5
5
|
const QUEUE_MAX_SIZE = 100;
|
|
6
6
|
const UPLOAD_INTERVAL_MS = 10_000;
|
|
7
7
|
|
|
8
|
-
const debugEnabled = ["yes", "true"].includes(
|
|
8
|
+
const debugEnabled = ["yes", "true", "on"].includes(
|
|
9
9
|
(process.env.GUAVA_DEBUG_TELEMETRY ?? "false").toLowerCase().trim(),
|
|
10
10
|
);
|
|
11
11
|
const logger: Logger = debugEnabled
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "0.
|
|
1
|
+
export const SDK_VERSION = "0.27.0";
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { type Logger } from "./logging.ts";
|
|
2
|
-
import { type Command } from "./commands.ts";
|
|
3
|
-
import type { GuavaEvent, CallerSpeechEvent, AgentSpeechEvent } from "./events.ts";
|
|
4
|
-
import { type FieldItem, type SayItem } from "./action-item.ts";
|
|
5
|
-
export type TaskObjective = {
|
|
6
|
-
objective: string;
|
|
7
|
-
} | {
|
|
8
|
-
objective?: string;
|
|
9
|
-
checklist: (FieldItem | SayItem | string)[];
|
|
10
|
-
};
|
|
11
|
-
export type ReachPersonOutcome = {
|
|
12
|
-
key: string;
|
|
13
|
-
onOutcome: () => void;
|
|
14
|
-
description?: string;
|
|
15
|
-
nextActionPreview?: string;
|
|
16
|
-
};
|
|
17
|
-
type ReachPersonOptions = {
|
|
18
|
-
onSuccess: () => void;
|
|
19
|
-
onFailure: () => void;
|
|
20
|
-
greeting?: string;
|
|
21
|
-
} | {
|
|
22
|
-
outcomes: ReachPersonOutcome[];
|
|
23
|
-
greeting?: string;
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Interface between Guava services and user-supplied code
|
|
27
|
-
*/
|
|
28
|
-
export declare class CallController {
|
|
29
|
-
private _commandQueue;
|
|
30
|
-
private _on_complete_current_task?;
|
|
31
|
-
private _current_task_id?;
|
|
32
|
-
/**
|
|
33
|
-
* @protected
|
|
34
|
-
* @description logger used to emit diagnostics
|
|
35
|
-
*/
|
|
36
|
-
protected logger: Logger;
|
|
37
|
-
private _drain?;
|
|
38
|
-
private _fieldValues;
|
|
39
|
-
private _searchFunctionsByKey;
|
|
40
|
-
constructor(logger?: Logger);
|
|
41
|
-
/**
|
|
42
|
-
* @description Supply a function used to consume commands from the internal command queue.
|
|
43
|
-
*
|
|
44
|
-
* The function is expected to remove from the argument array commands that it has handled (iterating
|
|
45
|
-
* through the result of `Array.splice(0)` is sufficient)
|
|
46
|
-
*/
|
|
47
|
-
setDrain(newDrain: (_: Command[]) => Promise<void>): void;
|
|
48
|
-
/**
|
|
49
|
-
* @description [inbound] receive a call, and process further.
|
|
50
|
-
*/
|
|
51
|
-
protected acceptCall(): Promise<void>;
|
|
52
|
-
/**
|
|
53
|
-
* @description read a span of text verbatim
|
|
54
|
-
*/
|
|
55
|
-
protected readScript(script: string): Promise<void>;
|
|
56
|
-
/**
|
|
57
|
-
* @description [inbound] reject a call
|
|
58
|
-
*/
|
|
59
|
-
protected rejectCall(): Promise<void>;
|
|
60
|
-
protected addInfo(_info: string): Promise<void>;
|
|
61
|
-
/**
|
|
62
|
-
* @description read a span of text non-verbatim
|
|
63
|
-
*/
|
|
64
|
-
protected sendInstruction(instruction: string): Promise<void>;
|
|
65
|
-
/**
|
|
66
|
-
* @description provide identifiers the agent will use to identify the virtual agent
|
|
67
|
-
*/
|
|
68
|
-
protected setPersona(args: {
|
|
69
|
-
organizationName?: string;
|
|
70
|
-
agentName?: string;
|
|
71
|
-
agentPurpose?: string;
|
|
72
|
-
voice?: string;
|
|
73
|
-
}): Promise<void>;
|
|
74
|
-
/**
|
|
75
|
-
* @description direct the agent to collect information
|
|
76
|
-
* @param goal {} an objective string and/or a checklist of information to collect
|
|
77
|
-
* @param on_complete {} a callback to call once the information is available from the agent
|
|
78
|
-
* @param args {} arguments to pass through to the `on_complete` callback
|
|
79
|
-
*/
|
|
80
|
-
protected setTask(goal: TaskObjective, on_complete?: (...c: any[]) => void, ...args: any[]): void;
|
|
81
|
-
/**
|
|
82
|
-
* @description direct the agent to collect information, continuing execution once the agent has collected the information
|
|
83
|
-
* @param goal {} an objective string and/or a checklist of information to collect
|
|
84
|
-
*/
|
|
85
|
-
protected awaitTask(goal: TaskObjective): Promise<void>;
|
|
86
|
-
/**
|
|
87
|
-
* @description retrieve a piece of information that the agent has collected
|
|
88
|
-
* @param key {string} key of the field checklist item
|
|
89
|
-
*/
|
|
90
|
-
protected getField(key: string): unknown;
|
|
91
|
-
/**
|
|
92
|
-
* @description [inbound] hang up an accepted call
|
|
93
|
-
*/
|
|
94
|
-
protected hangup(final_instructions?: string): Promise<void>;
|
|
95
|
-
/**
|
|
96
|
-
* @description helper for reaching a specific contact on an outbound call and recording their availability.
|
|
97
|
-
*/
|
|
98
|
-
protected reachPerson(contactFullName: string, options: ReachPersonOptions): void;
|
|
99
|
-
/**
|
|
100
|
-
* @description transfer an accepted call
|
|
101
|
-
*/
|
|
102
|
-
protected transfer(to_number: string, transfer_message?: string): void;
|
|
103
|
-
private sendCommand;
|
|
104
|
-
private flush;
|
|
105
|
-
onEvent(event: GuavaEvent): Promise<void>;
|
|
106
|
-
/**
|
|
107
|
-
* @description called when an inbound call is received. The overriding function must start
|
|
108
|
-
* with `await super.onIncomingCall(from_number)`
|
|
109
|
-
*/
|
|
110
|
-
onIncomingCall(from_number?: string): Promise<void>;
|
|
111
|
-
/**
|
|
112
|
-
* @description called when a call is connected by the API, whether inbound or outbound
|
|
113
|
-
*/
|
|
114
|
-
onCallStart(): Promise<void>;
|
|
115
|
-
/**
|
|
116
|
-
* @description called when the caller speaks to the agent.
|
|
117
|
-
*/
|
|
118
|
-
onCallerSpeech(event: CallerSpeechEvent): Promise<void>;
|
|
119
|
-
/**
|
|
120
|
-
* @description called when the agent speaks to the caller.
|
|
121
|
-
*/
|
|
122
|
-
onAgentSpeech(event: AgentSpeechEvent): Promise<void>;
|
|
123
|
-
/**
|
|
124
|
-
* @description called when the caller expresses a task they wish to execute
|
|
125
|
-
*/
|
|
126
|
-
onIntent(intent: string): Promise<string | null>;
|
|
127
|
-
/**
|
|
128
|
-
* @description called when the agent needs to respond to a question that it doesn't know
|
|
129
|
-
* the answer to.
|
|
130
|
-
*/
|
|
131
|
-
onQuestion(question: string): Promise<string>;
|
|
132
|
-
/**
|
|
133
|
-
* @description called when the bot session has ended.
|
|
134
|
-
*/
|
|
135
|
-
onSessionDone(): void;
|
|
136
|
-
}
|
|
137
|
-
export {};
|
|
@@ -1,436 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
-
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
-
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
-
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
-
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
-
var _, done = false;
|
|
8
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
-
var context = {};
|
|
10
|
-
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
-
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
-
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
-
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
-
if (kind === "accessor") {
|
|
15
|
-
if (result === void 0) continue;
|
|
16
|
-
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
-
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
-
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
-
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
-
}
|
|
21
|
-
else if (_ = accept(result)) {
|
|
22
|
-
if (kind === "field") initializers.unshift(_);
|
|
23
|
-
else descriptor[key] = _;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
-
done = true;
|
|
28
|
-
};
|
|
29
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
-
var useValue = arguments.length > 2;
|
|
31
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
-
}
|
|
34
|
-
return useValue ? value : void 0;
|
|
35
|
-
};
|
|
36
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
-
exports.CallController = void 0;
|
|
38
|
-
const logging_ts_1 = require("./logging.js");
|
|
39
|
-
const commands_ts_1 = require("./commands.js");
|
|
40
|
-
const action_item_ts_1 = require("./action-item.js");
|
|
41
|
-
const telemetry_ts_1 = require("./telemetry.js");
|
|
42
|
-
/**
|
|
43
|
-
* Interface between Guava services and user-supplied code
|
|
44
|
-
*/
|
|
45
|
-
let CallController = (() => {
|
|
46
|
-
let _classDecorators = [telemetry_ts_1.telemetryClient.trackClass()];
|
|
47
|
-
let _classDescriptor;
|
|
48
|
-
let _classExtraInitializers = [];
|
|
49
|
-
let _classThis;
|
|
50
|
-
var CallController = class {
|
|
51
|
-
static { _classThis = this; }
|
|
52
|
-
static {
|
|
53
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
54
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
55
|
-
CallController = _classThis = _classDescriptor.value;
|
|
56
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
57
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
58
|
-
}
|
|
59
|
-
_commandQueue = [];
|
|
60
|
-
_on_complete_current_task;
|
|
61
|
-
// private _field_values: Record<string, any>;
|
|
62
|
-
_current_task_id;
|
|
63
|
-
/**
|
|
64
|
-
* @protected
|
|
65
|
-
* @description logger used to emit diagnostics
|
|
66
|
-
*/
|
|
67
|
-
logger;
|
|
68
|
-
// drain functions are expected to cleanup
|
|
69
|
-
// the part of the queue that is successfully sent from its
|
|
70
|
-
// input (mutating it) (i.e. _drain should use Array.splice)
|
|
71
|
-
_drain;
|
|
72
|
-
_fieldValues = {};
|
|
73
|
-
_searchFunctionsByKey = {};
|
|
74
|
-
constructor(logger = (0, logging_ts_1.getDefaultLogger)()) {
|
|
75
|
-
// Set up the default logger.
|
|
76
|
-
this.logger = logger;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* @description Supply a function used to consume commands from the internal command queue.
|
|
80
|
-
*
|
|
81
|
-
* The function is expected to remove from the argument array commands that it has handled (iterating
|
|
82
|
-
* through the result of `Array.splice(0)` is sufficient)
|
|
83
|
-
*/
|
|
84
|
-
setDrain(newDrain) {
|
|
85
|
-
this._drain = newDrain;
|
|
86
|
-
this.flush();
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* @description [inbound] receive a call, and process further.
|
|
90
|
-
*/
|
|
91
|
-
async acceptCall() {
|
|
92
|
-
await this.sendCommand(commands_ts_1.AcceptInboundCallCommand, {
|
|
93
|
-
command_type: "accept-inbound",
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* @description read a span of text verbatim
|
|
98
|
-
*/
|
|
99
|
-
async readScript(script) {
|
|
100
|
-
await this.sendCommand(commands_ts_1.ReadScriptCommand, {
|
|
101
|
-
command_type: "read-script",
|
|
102
|
-
script: script,
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* @description [inbound] reject a call
|
|
107
|
-
*/
|
|
108
|
-
async rejectCall() {
|
|
109
|
-
await this.sendCommand(commands_ts_1.RejectInboundCallCommand, {
|
|
110
|
-
command_type: "reject-inbound",
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
async addInfo(_info) {
|
|
114
|
-
throw new Error("not implemeneted");
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* @description read a span of text non-verbatim
|
|
118
|
-
*/
|
|
119
|
-
async sendInstruction(instruction) {
|
|
120
|
-
await this.sendCommand(commands_ts_1.SendInstructionCommand, {
|
|
121
|
-
command_type: "send-instruction",
|
|
122
|
-
instruction: instruction,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* @description provide identifiers the agent will use to identify the virtual agent
|
|
127
|
-
*/
|
|
128
|
-
async setPersona(args) {
|
|
129
|
-
await this.sendCommand(commands_ts_1.SetPersona, {
|
|
130
|
-
command_type: "set-persona",
|
|
131
|
-
organization_name: args.organizationName,
|
|
132
|
-
agent_name: args.agentName,
|
|
133
|
-
agent_purpose: args.agentPurpose,
|
|
134
|
-
voice: args.voice,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* @description direct the agent to collect information
|
|
139
|
-
* @param goal {} an objective string and/or a checklist of information to collect
|
|
140
|
-
* @param on_complete {} a callback to call once the information is available from the agent
|
|
141
|
-
* @param args {} arguments to pass through to the `on_complete` callback
|
|
142
|
-
*/
|
|
143
|
-
setTask(goal, on_complete = () => { }, ...args) {
|
|
144
|
-
this._current_task_id = Math.random().toString(16).substring(2, 8);
|
|
145
|
-
this._on_complete_current_task = on_complete.bind(this, ...args);
|
|
146
|
-
if (!("checklist" in goal)) {
|
|
147
|
-
this.sendCommand(commands_ts_1.SetTaskCommand, {
|
|
148
|
-
command_type: "set-task",
|
|
149
|
-
task_id: this._current_task_id,
|
|
150
|
-
objective: goal.objective,
|
|
151
|
-
action_items: [],
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
const action_items = goal.checklist.map((item) => {
|
|
156
|
-
if (typeof item === "string") {
|
|
157
|
-
return { item_type: "todo", description: item };
|
|
158
|
-
}
|
|
159
|
-
if (item.item_type === "field" && item.choiceGenerator) {
|
|
160
|
-
this._searchFunctionsByKey[item.key] = item.choiceGenerator;
|
|
161
|
-
const { choiceGenerator: _, ...fieldData } = item;
|
|
162
|
-
return {
|
|
163
|
-
...fieldData,
|
|
164
|
-
is_search_field: true,
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
return item;
|
|
168
|
-
});
|
|
169
|
-
this.sendCommand(commands_ts_1.SetTaskCommand, {
|
|
170
|
-
command_type: "set-task",
|
|
171
|
-
task_id: this._current_task_id,
|
|
172
|
-
objective: goal.objective ?? "",
|
|
173
|
-
action_items,
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* @description direct the agent to collect information, continuing execution once the agent has collected the information
|
|
179
|
-
* @param goal {} an objective string and/or a checklist of information to collect
|
|
180
|
-
*/
|
|
181
|
-
async awaitTask(goal) {
|
|
182
|
-
return new Promise((resolve) => {
|
|
183
|
-
this.setTask(goal, (_args) => {
|
|
184
|
-
resolve();
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* @description retrieve a piece of information that the agent has collected
|
|
190
|
-
* @param key {string} key of the field checklist item
|
|
191
|
-
*/
|
|
192
|
-
getField(key) {
|
|
193
|
-
if (key in this._fieldValues) {
|
|
194
|
-
return this._fieldValues[key];
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
return null;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* @description [inbound] hang up an accepted call
|
|
202
|
-
*/
|
|
203
|
-
async hangup(final_instructions = "") {
|
|
204
|
-
let instructions;
|
|
205
|
-
if (final_instructions) {
|
|
206
|
-
instructions = `Start ending the conversation. Here are your final instructions: ${final_instructions} Once you've completed the final instructions, naturally end the conversation and hang up the call.`;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
instructions = "Naturally end the conversation and hang up the call.";
|
|
210
|
-
}
|
|
211
|
-
this.sendInstruction(instructions);
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* @description helper for reaching a specific contact on an outbound call and recording their availability.
|
|
215
|
-
*/
|
|
216
|
-
reachPerson(contactFullName, options) {
|
|
217
|
-
let outcomes;
|
|
218
|
-
if ("outcomes" in options) {
|
|
219
|
-
outcomes = options.outcomes;
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
outcomes = [
|
|
223
|
-
{
|
|
224
|
-
key: "contact_available",
|
|
225
|
-
onOutcome: options.onSuccess,
|
|
226
|
-
description: "The contact is available to speak.",
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
key: "contact_unavailable",
|
|
230
|
-
onOutcome: options.onFailure,
|
|
231
|
-
description: "The contact is not available to speak. This includes reaching a wrong number.",
|
|
232
|
-
},
|
|
233
|
-
];
|
|
234
|
-
}
|
|
235
|
-
const outcomeHandlers = Object.fromEntries(outcomes.map((o) => [o.key, o.onOutcome]));
|
|
236
|
-
const initialGreeting = options.greeting !== undefined
|
|
237
|
-
? (0, action_item_ts_1.Say)(options.greeting)
|
|
238
|
-
: `Greet the person who answered the phone. Notify them who you are calling on behalf of and the purpose of the call. Ask to speak with ${contactFullName}`;
|
|
239
|
-
const availabilityDescription = `The availability of ${contactFullName}` +
|
|
240
|
-
(outcomes.some((o) => o.description)
|
|
241
|
-
? "\nDetailed descriptions of each choice:\n" +
|
|
242
|
-
outcomes
|
|
243
|
-
.filter((o) => o.description)
|
|
244
|
-
.map((o) => ` - ${o.key}: ${o.description}`)
|
|
245
|
-
.join("\n")
|
|
246
|
-
: "");
|
|
247
|
-
const nextActionLines = outcomes
|
|
248
|
-
.filter((o) => o.nextActionPreview)
|
|
249
|
-
.map((o) => `- ${o.key} → ${o.nextActionPreview}`);
|
|
250
|
-
const checklist = [
|
|
251
|
-
initialGreeting,
|
|
252
|
-
{
|
|
253
|
-
item_type: "field",
|
|
254
|
-
key: "contact_availability",
|
|
255
|
-
field_type: "multiple_choice",
|
|
256
|
-
description: availabilityDescription,
|
|
257
|
-
choices: outcomes.map((o) => o.key),
|
|
258
|
-
},
|
|
259
|
-
];
|
|
260
|
-
if (nextActionLines.length > 0) {
|
|
261
|
-
checklist.push("If a next action is defined below for the value of `contact_availability`, briefly ask the contact to wait just a second while you perform it.\n" +
|
|
262
|
-
nextActionLines.join("\n"));
|
|
263
|
-
}
|
|
264
|
-
const objective = `\
|
|
265
|
-
OBJECTIVE:
|
|
266
|
-
Your goal is to reach ${contactFullName} and determine their availability to proceed with this call.
|
|
267
|
-
|
|
268
|
-
RULES:
|
|
269
|
-
1. If the initial respondent is NOT ${contactFullName}:
|
|
270
|
-
- Politely ask to speak with ${contactFullName}
|
|
271
|
-
- Wait to be transferred or for ${contactFullName} to come to the phone
|
|
272
|
-
2. Once you have ${contactFullName} on the line:
|
|
273
|
-
- Briefly restate who you are and the purpose of your call
|
|
274
|
-
- Determine and record their current availability status
|
|
275
|
-
3. DO NOT hang up the call under any circumstances, unless it's a wrong number.
|
|
276
|
-
|
|
277
|
-
TASK COMPLETION REQUIREMENTS:
|
|
278
|
-
- The availability of ${contactFullName} must be recorded in \`contact_availability\`.`;
|
|
279
|
-
this.setTask({ objective, checklist }, () => {
|
|
280
|
-
const availability = this.getField("contact_availability");
|
|
281
|
-
const handler = outcomeHandlers[availability];
|
|
282
|
-
if (!handler) {
|
|
283
|
-
this.logger.error(`Unhandled contact_availability value: ${availability}`);
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
this.logger.info(`Contact availability recorded: ${availability}`);
|
|
287
|
-
handler();
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* @description transfer an accepted call
|
|
292
|
-
*/
|
|
293
|
-
transfer(to_number, transfer_message) {
|
|
294
|
-
const message = transfer_message ?? "I'm transferring you now";
|
|
295
|
-
this.sendCommand(commands_ts_1.TransferCommand, {
|
|
296
|
-
command_type: "transfer-call",
|
|
297
|
-
transfer_message: message,
|
|
298
|
-
to_number: to_number,
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
async sendCommand(schema, data) {
|
|
302
|
-
const command = schema.parse(data);
|
|
303
|
-
this._commandQueue.push(command);
|
|
304
|
-
await this.flush();
|
|
305
|
-
}
|
|
306
|
-
async flush() {
|
|
307
|
-
await this._drain?.call(this, this._commandQueue);
|
|
308
|
-
}
|
|
309
|
-
async onEvent(event) {
|
|
310
|
-
this.logger.debug(`Event received: ${JSON.stringify(event)}`);
|
|
311
|
-
if (event.event_type === "caller-speech") {
|
|
312
|
-
this.onCallerSpeech(event);
|
|
313
|
-
}
|
|
314
|
-
else if (event.event_type === "agent-speech") {
|
|
315
|
-
this.onAgentSpeech(event);
|
|
316
|
-
}
|
|
317
|
-
else if (event.event_type === "agent-question") {
|
|
318
|
-
try {
|
|
319
|
-
this.logger.info(`Received question from bot: ${event.question}`);
|
|
320
|
-
const answer = await this.onQuestion(event.question);
|
|
321
|
-
await this.sendCommand(commands_ts_1.AnswerQuestionCommand, {
|
|
322
|
-
command_type: "answer-question",
|
|
323
|
-
question_id: event.question_id,
|
|
324
|
-
answer: answer,
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
catch (e) {
|
|
328
|
-
this.logger.error("Error occured while answering question.");
|
|
329
|
-
await this.sendCommand(commands_ts_1.AnswerQuestionCommand, {
|
|
330
|
-
command_type: "answer-question",
|
|
331
|
-
question_id: event.question_id,
|
|
332
|
-
answer: "An error occured and the question could not be answered.",
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
else if (event.event_type === "intent") {
|
|
337
|
-
this.logger.info(`Received intent ${event.intent_id} from bot: ${event.intent_summary}`);
|
|
338
|
-
const intent_response = await this.onIntent(event.intent_summary);
|
|
339
|
-
if (intent_response) {
|
|
340
|
-
const response_str = `Responding to intent ${event.intent_id}: ${intent_response}`;
|
|
341
|
-
this.logger.info(response_str);
|
|
342
|
-
this.sendInstruction(intent_response);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
else if (event.event_type === "task-done") {
|
|
346
|
-
// ignore obsolete task_completed events
|
|
347
|
-
if (event.task_id === this._current_task_id) {
|
|
348
|
-
// assertion is implied
|
|
349
|
-
const on_complete = this._on_complete_current_task;
|
|
350
|
-
this._on_complete_current_task = undefined;
|
|
351
|
-
if (on_complete) {
|
|
352
|
-
on_complete();
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
else if (event.event_type === "choice-query") {
|
|
357
|
-
this.logger.info(`Received choice query for field ${event.field_key}: ${event.query}`);
|
|
358
|
-
const choiceGenerator = this._searchFunctionsByKey[event.field_key];
|
|
359
|
-
if (!choiceGenerator) {
|
|
360
|
-
this.logger.warn(`Choice query for field '${event.field_key}' arrived but has no choice generator attached.`);
|
|
361
|
-
}
|
|
362
|
-
else {
|
|
363
|
-
const [matchedChoices, otherChoices] = await choiceGenerator(event.query);
|
|
364
|
-
await this.sendCommand(commands_ts_1.ChoiceResultCommand, {
|
|
365
|
-
command_type: "choice-query-result",
|
|
366
|
-
field_key: event.field_key,
|
|
367
|
-
query_id: event.query_id,
|
|
368
|
-
matched_choices: matchedChoices,
|
|
369
|
-
other_choices: otherChoices,
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
else if (event.event_type === "action-item-done") {
|
|
374
|
-
this._fieldValues[event.key] = event.payload;
|
|
375
|
-
if (event.key && event.payload) {
|
|
376
|
-
this.logger.info(`Field ${event.key} updated with value: ${event.payload}`);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
else if (event.event_type === "inbound-call") {
|
|
380
|
-
this.onIncomingCall(event.caller_number || undefined);
|
|
381
|
-
}
|
|
382
|
-
else if (event.event_type === "bot-session-ended") {
|
|
383
|
-
this.onSessionDone();
|
|
384
|
-
}
|
|
385
|
-
else if (event.event_type === "outbound-call-connected") {
|
|
386
|
-
// no-op, don't warn
|
|
387
|
-
}
|
|
388
|
-
else if (event.event_type === "error") {
|
|
389
|
-
this.logger.error(`The Guava agent reported an error: ${event.content}`);
|
|
390
|
-
}
|
|
391
|
-
else {
|
|
392
|
-
this.logger.warn(`Unhandled event: ${JSON.stringify(event)}`);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
// callbacks
|
|
396
|
-
/**
|
|
397
|
-
* @description called when an inbound call is received. The overriding function must start
|
|
398
|
-
* with `await super.onIncomingCall(from_number)`
|
|
399
|
-
*/
|
|
400
|
-
async onIncomingCall(from_number) {
|
|
401
|
-
await this.onCallStart();
|
|
402
|
-
}
|
|
403
|
-
/**
|
|
404
|
-
* @description called when a call is connected by the API, whether inbound or outbound
|
|
405
|
-
*/
|
|
406
|
-
async onCallStart() { }
|
|
407
|
-
/**
|
|
408
|
-
* @description called when the caller speaks to the agent.
|
|
409
|
-
*/
|
|
410
|
-
async onCallerSpeech(event) { }
|
|
411
|
-
/**
|
|
412
|
-
* @description called when the agent speaks to the caller.
|
|
413
|
-
*/
|
|
414
|
-
async onAgentSpeech(event) { }
|
|
415
|
-
/**
|
|
416
|
-
* @description called when the caller expresses a task they wish to execute
|
|
417
|
-
*/
|
|
418
|
-
async onIntent(intent) {
|
|
419
|
-
return "Unfortunately I'm not able to help with that.";
|
|
420
|
-
}
|
|
421
|
-
/**
|
|
422
|
-
* @description called when the agent needs to respond to a question that it doesn't know
|
|
423
|
-
* the answer to.
|
|
424
|
-
*/
|
|
425
|
-
async onQuestion(question) {
|
|
426
|
-
return "I don't have an answer to that question.";
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* @description called when the bot session has ended.
|
|
430
|
-
*/
|
|
431
|
-
onSessionDone() { }
|
|
432
|
-
};
|
|
433
|
-
return CallController = _classThis;
|
|
434
|
-
})();
|
|
435
|
-
exports.CallController = CallController;
|
|
436
|
-
//# sourceMappingURL=call-controller.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"call-controller.js","sourceRoot":"","sources":["../../src/call-controller.ts"],"names":[],"mappings":"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"}
|