@guava-ai/guava-sdk 0.26.0 → 0.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +1 -1
  2. package/bin/example-runner.ts +67 -26
  3. package/dist/bin/example-runner.d.ts +1 -25
  4. package/dist/bin/example-runner.js +64 -24
  5. package/dist/bin/example-runner.js.map +1 -1
  6. package/dist/examples/help-desk.d.ts +1 -1
  7. package/dist/examples/help-desk.js +34 -23
  8. package/dist/examples/help-desk.js.map +1 -1
  9. package/dist/examples/multiple-agents.d.ts +1 -1
  10. package/dist/examples/multiple-agents.js +1 -1
  11. package/dist/examples/multiple-agents.js.map +1 -1
  12. package/dist/examples/polling-campaign.d.ts +1 -1
  13. package/dist/examples/polling-campaign.js +9 -7
  14. package/dist/examples/polling-campaign.js.map +1 -1
  15. package/dist/examples/property-insurance.d.ts +1 -1
  16. package/dist/examples/property-insurance.js +34 -23
  17. package/dist/examples/property-insurance.js.map +1 -1
  18. package/dist/examples/restaurant-waitlist.d.ts +1 -1
  19. package/dist/examples/restaurant-waitlist.js +34 -23
  20. package/dist/examples/restaurant-waitlist.js.map +1 -1
  21. package/dist/examples/scheduling-outbound.d.ts +1 -1
  22. package/dist/examples/scheduling-outbound.js +24 -14
  23. package/dist/examples/scheduling-outbound.js.map +1 -1
  24. package/dist/src/agent.d.ts +2 -2
  25. package/dist/src/agent.js +4 -4
  26. package/dist/src/agent.js.map +1 -1
  27. package/dist/src/call.d.ts +2 -0
  28. package/dist/src/call.js +18 -0
  29. package/dist/src/call.js.map +1 -1
  30. package/dist/src/client.d.ts +0 -22
  31. package/dist/src/client.js +0 -155
  32. package/dist/src/client.js.map +1 -1
  33. package/dist/src/commands.d.ts +62 -0
  34. package/dist/src/commands.js +7 -1
  35. package/dist/src/commands.js.map +1 -1
  36. package/dist/src/events.d.ts +2 -1
  37. package/dist/src/events.js +20 -2
  38. package/dist/src/events.js.map +1 -1
  39. package/dist/src/index.d.ts +0 -1
  40. package/dist/src/index.js +1 -3
  41. package/dist/src/index.js.map +1 -1
  42. package/dist/src/socket/client.js +10 -0
  43. package/dist/src/socket/client.js.map +1 -1
  44. package/dist/src/telemetry.js +1 -1
  45. package/dist/src/telemetry.js.map +1 -1
  46. package/dist/src/version.d.ts +1 -1
  47. package/dist/src/version.js +1 -1
  48. package/examples/help-desk.ts +42 -20
  49. package/examples/multiple-agents.ts +1 -1
  50. package/examples/polling-campaign.ts +12 -7
  51. package/examples/property-insurance.ts +42 -22
  52. package/examples/restaurant-waitlist.ts +42 -22
  53. package/examples/scheduling-outbound.ts +26 -15
  54. package/package.json +2 -1
  55. package/src/agent.ts +16 -8
  56. package/src/call.ts +25 -0
  57. package/src/client.ts +0 -197
  58. package/src/commands.ts +8 -0
  59. package/src/events.ts +20 -18
  60. package/src/index.ts +0 -1
  61. package/src/socket/client.ts +22 -0
  62. package/src/telemetry.ts +1 -1
  63. package/src/version.ts +1 -1
  64. package/dist/src/call-controller.d.ts +0 -137
  65. package/dist/src/call-controller.js +0 -436
  66. package/dist/src/call-controller.js.map +0 -1
  67. package/src/call-controller.ts +0 -451
package/src/commands.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as z from "zod";
2
2
  import { ActionItem } from "./action-item.ts";
3
+ import { DTMF_DIGITS } from "./events.ts";
3
4
 
4
5
  export const StartOutboundCallCommand = z.strictObject({
5
6
  command_type: z.literal("start-outbound"),
@@ -133,6 +134,12 @@ export const SetAgentDTMFCommand = z.strictObject({
133
134
  });
134
135
  export type SetAgentDTMFCommand = z.input<typeof SetAgentDTMFCommand>;
135
136
 
137
+ export const SendAgentDTMFCommand = z.strictObject({
138
+ command_type: z.literal("send-agent-dtmf"),
139
+ digits: z.array(z.enum(DTMF_DIGITS)),
140
+ });
141
+ export type SendAgentDTMFCommand = z.input<typeof SendAgentDTMFCommand>;
142
+
136
143
  export const ExpertErrorCommand = z.strictObject({
137
144
  command_type: z.literal("expert-error"),
138
145
  message: z.string(),
@@ -156,6 +163,7 @@ export const AnyCommand = z.union([
156
163
  ActionSuggestionCommand,
157
164
  RetryTaskCommand,
158
165
  SetAgentDTMFCommand,
166
+ SendAgentDTMFCommand,
159
167
  ExpertErrorCommand,
160
168
  ]);
161
169
  export type Command = z.input<typeof AnyCommand>;
package/src/events.ts CHANGED
@@ -126,27 +126,29 @@ export const ExecuteActionEvent = z.object({
126
126
  });
127
127
  export type ExecuteActionEvent = z.infer<typeof ExecuteActionEvent>;
128
128
 
129
- export type DTMFDigit =
130
- | "0"
131
- | "1"
132
- | "2"
133
- | "3"
134
- | "4"
135
- | "5"
136
- | "6"
137
- | "7"
138
- | "8"
139
- | "9"
140
- | "*"
141
- | "#"
142
- | "A"
143
- | "B"
144
- | "C"
145
- | "D";
129
+ export const DTMF_DIGITS = [
130
+ "0",
131
+ "1",
132
+ "2",
133
+ "3",
134
+ "4",
135
+ "5",
136
+ "6",
137
+ "7",
138
+ "8",
139
+ "9",
140
+ "*",
141
+ "#",
142
+ "A",
143
+ "B",
144
+ "C",
145
+ "D",
146
+ ] as const;
147
+ export type DTMFDigit = (typeof DTMF_DIGITS)[number];
146
148
 
147
149
  export const DTMFPressedEvent = z.object({
148
150
  event_type: z.literal("dtmf"),
149
- digit: z.enum(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "#", "A", "B", "C", "D"]),
151
+ digit: z.enum(DTMF_DIGITS),
150
152
  recent_digits: z.string().default(""),
151
153
  });
152
154
  export type DTMFPressedEvent = z.infer<typeof DTMFPressedEvent>;
package/src/index.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export { Client, type InboundConnection } from "./client.ts";
2
2
  export { Runner } from "./runner.ts";
3
3
  export type { SmsMessage } from "./sms.ts";
4
- export { CallController, type TaskObjective } from "./call-controller.ts";
5
4
  export { Say, Field } from "./action-item.ts";
6
5
  export { Logger, getConsoleLogger, getDefaultLogger } from "./logging.ts";
7
6
  export { Agent, CallInfo } from "./agent.ts";
@@ -1,4 +1,5 @@
1
1
  import WebSocket from "ws";
2
+ import type { IncomingMessage } from "node:http";
2
3
  import { randomBytes } from "node:crypto";
3
4
  import * as z from "zod";
4
5
  import type { Client } from "../client.ts";
@@ -134,6 +135,12 @@ export class GuavaSocket<SendT, RecvT> {
134
135
  const headers = await this._client.headers();
135
136
 
136
137
  try {
138
+ this._logger.debug(
139
+ "Connecting to %s (attempt %d/%d)...",
140
+ this._connectionUrl,
141
+ attempt,
142
+ MAX_RECONNECT_ATTEMPTS,
143
+ );
137
144
  const ws = await new Promise<WebSocket>((resolve, reject) => {
138
145
  const socket = new WebSocket(this._connectionUrl, { headers });
139
146
  let settled = false;
@@ -147,6 +154,21 @@ export class GuavaSocket<SendT, RecvT> {
147
154
  };
148
155
 
149
156
  socket.once("error", (err) => settle(() => reject(err)));
157
+ socket.once("unexpected-response", (_req, res: IncomingMessage) => {
158
+ let body = "";
159
+ res.on("data", (chunk: Buffer) => {
160
+ body += chunk.toString();
161
+ });
162
+ res.on("end", () => {
163
+ settle(() =>
164
+ reject(
165
+ new Error(
166
+ `Unexpected server response: ${res.statusCode}. Body: ${body || "<empty>"}`,
167
+ ),
168
+ ),
169
+ );
170
+ });
171
+ });
150
172
  socket.once("close", () =>
151
173
  settle(() => reject(new Error("Connection closed before open-ack"))),
152
174
  );
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.26.0";
1
+ export const SDK_VERSION = "0.27.1";
@@ -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 {};