@guava-ai/guava-sdk 0.18.0 → 0.19.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.
Files changed (98) hide show
  1. package/dist/examples/example.test.d.ts +5 -0
  2. package/dist/examples/example.test.js +46 -0
  3. package/dist/examples/example.test.js.map +1 -0
  4. package/dist/examples/help-desk.d.ts +3 -1
  5. package/dist/examples/help-desk.js +25 -9
  6. package/dist/examples/help-desk.js.map +1 -1
  7. package/dist/examples/property-insurance.js +4 -1
  8. package/dist/examples/property-insurance.js.map +1 -1
  9. package/dist/examples/restaurant-waitlist.js +4 -1
  10. package/dist/examples/restaurant-waitlist.js.map +1 -1
  11. package/dist/examples/scheduling-outbound.js +6 -0
  12. package/dist/examples/scheduling-outbound.js.map +1 -1
  13. package/dist/src/action-item.d.ts +4 -4
  14. package/dist/src/agent.d.ts +81 -16
  15. package/dist/src/agent.js +394 -127
  16. package/dist/src/agent.js.map +1 -1
  17. package/dist/src/auth.d.ts +27 -0
  18. package/dist/src/auth.js +127 -0
  19. package/dist/src/auth.js.map +1 -0
  20. package/dist/src/call.d.ts +1 -1
  21. package/dist/src/call.js +2 -2
  22. package/dist/src/call.js.map +1 -1
  23. package/dist/src/client.d.ts +4 -11
  24. package/dist/src/client.js +22 -14
  25. package/dist/src/client.js.map +1 -1
  26. package/dist/src/commands.d.ts +3 -3
  27. package/dist/src/events.d.ts +22 -0
  28. package/dist/src/events.js +19 -5
  29. package/dist/src/events.js.map +1 -1
  30. package/dist/src/helpers/llm.d.ts +2 -0
  31. package/dist/src/helpers/llm.js +17 -0
  32. package/dist/src/helpers/llm.js.map +1 -0
  33. package/dist/src/index.d.ts +2 -0
  34. package/dist/src/index.js +5 -1
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/logging.js +16 -11
  37. package/dist/src/logging.js.map +1 -1
  38. package/dist/src/socket/call-info.d.ts +35 -0
  39. package/dist/src/socket/call-info.js +59 -0
  40. package/dist/src/socket/call-info.js.map +1 -0
  41. package/dist/src/socket/client.d.ts +51 -0
  42. package/dist/src/socket/client.js +455 -0
  43. package/dist/src/socket/client.js.map +1 -0
  44. package/dist/src/socket/listen-inbound.d.ts +83 -0
  45. package/dist/src/socket/listen-inbound.js +82 -0
  46. package/dist/src/socket/listen-inbound.js.map +1 -0
  47. package/dist/src/socket/protocol.d.ts +127 -0
  48. package/dist/src/socket/protocol.js +69 -0
  49. package/dist/src/socket/protocol.js.map +1 -0
  50. package/dist/src/socket/utils.d.ts +8 -0
  51. package/dist/src/socket/utils.js +26 -0
  52. package/dist/src/socket/utils.js.map +1 -0
  53. package/dist/src/telemetry.d.ts +3 -3
  54. package/dist/src/telemetry.js +9 -7
  55. package/dist/src/telemetry.js.map +1 -1
  56. package/dist/src/testing/chat.d.ts +2 -0
  57. package/dist/src/testing/chat.js +181 -0
  58. package/dist/src/testing/chat.js.map +1 -0
  59. package/dist/src/testing/mocks.d.ts +6 -0
  60. package/dist/src/testing/mocks.js +14 -0
  61. package/dist/src/testing/mocks.js.map +1 -0
  62. package/dist/src/testing/protocol.d.ts +46 -0
  63. package/dist/src/testing/protocol.js +61 -0
  64. package/dist/src/testing/protocol.js.map +1 -0
  65. package/dist/src/testing/session.d.ts +26 -0
  66. package/dist/src/testing/session.js +219 -0
  67. package/dist/src/testing/session.js.map +1 -0
  68. package/dist/src/utils.d.ts +1 -0
  69. package/dist/src/utils.js +15 -1
  70. package/dist/src/utils.js.map +1 -1
  71. package/dist/src/version.d.ts +1 -1
  72. package/dist/src/version.js +1 -1
  73. package/examples/example.test.ts +58 -0
  74. package/examples/help-desk.ts +14 -3
  75. package/examples/property-insurance.ts +3 -1
  76. package/examples/restaurant-waitlist.ts +3 -1
  77. package/examples/scheduling-outbound.ts +7 -0
  78. package/package.json +9 -1
  79. package/src/agent.ts +372 -162
  80. package/src/auth.ts +109 -0
  81. package/src/call.ts +3 -3
  82. package/src/client.ts +32 -15
  83. package/src/events.ts +24 -10
  84. package/src/helpers/llm.ts +20 -0
  85. package/src/index.ts +2 -0
  86. package/src/logging.ts +21 -13
  87. package/src/socket/call-info.ts +30 -0
  88. package/src/socket/client.ts +433 -0
  89. package/src/socket/listen-inbound.ts +62 -0
  90. package/src/socket/protocol.ts +89 -0
  91. package/src/socket/utils.ts +25 -0
  92. package/src/telemetry.ts +11 -8
  93. package/src/testing/chat.ts +196 -0
  94. package/src/testing/mocks.ts +12 -0
  95. package/src/testing/protocol.ts +40 -0
  96. package/src/testing/session.ts +218 -0
  97. package/src/utils.ts +15 -1
  98. package/src/version.ts +1 -1
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.TestingEvent = exports.SessionStarted = exports.TurnStarted = exports.BotTTS = exports.WaitForTurn = exports.InjectASR = exports.Pong = exports.Ping = void 0;
37
+ const z = __importStar(require("zod"));
38
+ exports.Ping = z.object({ message_type: z.literal("ping") });
39
+ exports.Pong = z.object({ message_type: z.literal("pong") });
40
+ exports.InjectASR = z.object({
41
+ message_type: z.literal("inject-asr"),
42
+ utterance: z.string(),
43
+ });
44
+ exports.WaitForTurn = z.object({
45
+ message_type: z.literal("wait-for-caller-turn"),
46
+ request_id: z.string(),
47
+ });
48
+ exports.BotTTS = z.object({
49
+ message_type: z.literal("bot-tts"),
50
+ transcript: z.string(),
51
+ });
52
+ exports.TurnStarted = z.object({
53
+ message_type: z.literal("caller-turn-started"),
54
+ request_id: z.string(),
55
+ });
56
+ exports.SessionStarted = z.object({
57
+ message_type: z.literal("session-started"),
58
+ session_id: z.string(),
59
+ });
60
+ exports.TestingEvent = z.discriminatedUnion("message_type", [exports.Ping, exports.Pong, exports.BotTTS, exports.TurnStarted]);
61
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/testing/protocol.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AAEZ,QAAA,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAGrD,QAAA,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAGrD,QAAA,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;IACrC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AAGU,QAAA,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC;IAC/C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;CACvB,CAAC,CAAC;AAGU,QAAA,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IAClC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;CACvB,CAAC,CAAC;AAGU,QAAA,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC;IAC9C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;CACvB,CAAC,CAAC;AAGU,QAAA,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC;IAC1C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;CACvB,CAAC,CAAC;AAGU,QAAA,YAAY,GAAG,CAAC,CAAC,kBAAkB,CAAC,cAAc,EAAE,CAAC,YAAI,EAAE,YAAI,EAAE,cAAM,EAAE,mBAAW,CAAC,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type WebSocket from "ws";
2
+ import { type BotTTS, type InjectASR, TestingEvent } from "./protocol.ts";
3
+ import type { Client } from "../client.ts";
4
+ export declare class TestSession {
5
+ private readonly _ws;
6
+ private readonly _client;
7
+ private _sessionEvents;
8
+ private _recvBuffer;
9
+ private _recvWaiters;
10
+ private _closed;
11
+ executedActions: string[];
12
+ terminationReason: string | null;
13
+ /** @internal */
14
+ get _events(): ReadonlyArray<InjectASR | BotTTS>;
15
+ constructor(ws: WebSocket, client: Client);
16
+ private _rawSend;
17
+ say(utterance: string): void;
18
+ recv(): Promise<TestingEvent>;
19
+ getTranscript(): string;
20
+ waitForTurn(): Promise<void>;
21
+ waitForEnd(): Promise<void>;
22
+ evaluate({ passCriteria, failCriteria, }?: {
23
+ passCriteria?: string[];
24
+ failCriteria?: string[];
25
+ }): Promise<void>;
26
+ }
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.TestSession = void 0;
37
+ const node_crypto_1 = require("node:crypto");
38
+ const z = __importStar(require("zod"));
39
+ const protocol_ts_1 = require("./protocol.js");
40
+ const llm_ts_1 = require("../helpers/llm.js");
41
+ const _evalResponseSchema = z.object({
42
+ results: z.array(z.object({
43
+ passed: z.boolean(),
44
+ reasoning: z.string().optional(),
45
+ })),
46
+ });
47
+ class TestSession {
48
+ _ws;
49
+ _client;
50
+ _sessionEvents = [];
51
+ _recvBuffer = [];
52
+ _recvWaiters = [];
53
+ _closed = false;
54
+ executedActions = [];
55
+ terminationReason = null;
56
+ /** @internal */
57
+ get _events() {
58
+ return this._sessionEvents;
59
+ }
60
+ constructor(ws, client) {
61
+ this._ws = ws;
62
+ this._client = client;
63
+ ws.on("message", (data) => {
64
+ let event;
65
+ try {
66
+ event = protocol_ts_1.TestingEvent.parse(JSON.parse(data.toString()));
67
+ }
68
+ catch {
69
+ return;
70
+ }
71
+ const waiter = this._recvWaiters.shift();
72
+ if (waiter) {
73
+ waiter.resolve(event);
74
+ }
75
+ else {
76
+ this._recvBuffer.push(event);
77
+ }
78
+ });
79
+ const onClose = () => {
80
+ this._closed = true;
81
+ const err = new Error("Test session WebSocket closed");
82
+ for (const waiter of this._recvWaiters) {
83
+ waiter.reject(err);
84
+ }
85
+ this._recvWaiters = [];
86
+ };
87
+ ws.once("close", onClose);
88
+ ws.once("error", onClose);
89
+ }
90
+ _rawSend(msg) {
91
+ this._ws.send(JSON.stringify(msg));
92
+ }
93
+ say(utterance) {
94
+ const msg = { message_type: "inject-asr", utterance };
95
+ this._sessionEvents.push(msg);
96
+ this._rawSend(msg);
97
+ }
98
+ async recv() {
99
+ while (true) {
100
+ let event;
101
+ const buffered = this._recvBuffer.shift();
102
+ if (buffered !== undefined) {
103
+ event = buffered;
104
+ }
105
+ else {
106
+ event = await new Promise((resolve, reject) => {
107
+ if (this._closed) {
108
+ reject(new Error("Test session WebSocket closed"));
109
+ return;
110
+ }
111
+ this._recvWaiters.push({ resolve, reject });
112
+ });
113
+ }
114
+ if (event.message_type === "ping") {
115
+ this._rawSend({ message_type: "pong" });
116
+ continue;
117
+ }
118
+ if (event.message_type === "bot-tts") {
119
+ this._sessionEvents.push(event);
120
+ }
121
+ return event;
122
+ }
123
+ }
124
+ getTranscript() {
125
+ const lines = [];
126
+ for (const event of this._sessionEvents) {
127
+ if (event.message_type === "inject-asr") {
128
+ lines.push(`[caller]: ${event.utterance}`);
129
+ }
130
+ else {
131
+ lines.push(`[agent]: ${event.transcript}`);
132
+ }
133
+ }
134
+ return lines.join("\n");
135
+ }
136
+ async waitForTurn() {
137
+ const requestId = (0, node_crypto_1.randomBytes)(8).toString("hex");
138
+ this._rawSend({ message_type: "wait-for-caller-turn", request_id: requestId });
139
+ while (true) {
140
+ const event = await this.recv();
141
+ if (event.message_type === "caller-turn-started" && event.request_id === requestId) {
142
+ return;
143
+ }
144
+ }
145
+ }
146
+ async waitForEnd() {
147
+ try {
148
+ while (true) {
149
+ await this.recv();
150
+ }
151
+ }
152
+ catch {
153
+ // Connection closed — session has ended.
154
+ }
155
+ }
156
+ async evaluate({ passCriteria = [], failCriteria = [], } = {}) {
157
+ const allCriteria = [
158
+ ...passCriteria.map((c) => ({ kind: "pass", criterion: c })),
159
+ ...failCriteria.map((c) => ({ kind: "fail", criterion: c })),
160
+ ];
161
+ if (allCriteria.length === 0)
162
+ return;
163
+ const transcript = this.getTranscript();
164
+ const criteriaList = allCriteria.map((c, i) => `${i + 1}. ${c.criterion}`).join("\n");
165
+ const prompt = `Evaluate whether the following criteria are met based on the conversation transcript below.
166
+ Return one result object per criterion in the same order as listed.
167
+
168
+ Transcript:
169
+ ${transcript || "(empty — no conversation occurred)"}
170
+
171
+ Criteria:
172
+ ${criteriaList}`;
173
+ const evalSchema = {
174
+ type: "object",
175
+ properties: {
176
+ results: {
177
+ type: "array",
178
+ items: {
179
+ type: "object",
180
+ properties: {
181
+ passed: { type: "boolean" },
182
+ reasoning: { type: "string" },
183
+ },
184
+ required: ["passed"],
185
+ additionalProperties: false,
186
+ },
187
+ },
188
+ },
189
+ required: ["results"],
190
+ additionalProperties: false,
191
+ };
192
+ const evalResponse = _evalResponseSchema.parse(JSON.parse(await (0, llm_ts_1._generate)(this._client, prompt, evalSchema)));
193
+ if (evalResponse.results.length !== allCriteria.length) {
194
+ throw new Error(`Evaluation returned ${evalResponse.results.length} results for ${allCriteria.length} criteria.`);
195
+ }
196
+ const failures = [];
197
+ for (let i = 0; i < allCriteria.length; i++) {
198
+ const { kind, criterion } = allCriteria[i];
199
+ const result = evalResponse.results[i];
200
+ if (kind === "pass" && !result.passed) {
201
+ let msg = `Pass criterion not met: ${JSON.stringify(criterion)}`;
202
+ if (result.reasoning)
203
+ msg += ` — ${result.reasoning}`;
204
+ failures.push(msg);
205
+ }
206
+ else if (kind === "fail" && result.passed) {
207
+ let msg = `Fail criterion triggered: ${JSON.stringify(criterion)}`;
208
+ if (result.reasoning)
209
+ msg += ` — ${result.reasoning}`;
210
+ failures.push(msg);
211
+ }
212
+ }
213
+ if (failures.length > 0) {
214
+ throw new Error(`Session evaluation failed:\n${failures.map((f) => ` • ${f}`).join("\n")}`);
215
+ }
216
+ }
217
+ }
218
+ exports.TestSession = TestSession;
219
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/testing/session.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export declare const DEFAULT_BASE_URL = "https://app.goguava.ai/";
2
2
  export declare function getPlatformConfigDir(): string;
3
+ export declare function getCliConfigPath(): string;
3
4
  export declare function getBaseUrl(): string;
4
5
  export declare function fetchOrThrow(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
package/dist/src/utils.js CHANGED
@@ -35,8 +35,10 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.DEFAULT_BASE_URL = void 0;
37
37
  exports.getPlatformConfigDir = getPlatformConfigDir;
38
+ exports.getCliConfigPath = getCliConfigPath;
38
39
  exports.getBaseUrl = getBaseUrl;
39
40
  exports.fetchOrThrow = fetchOrThrow;
41
+ const fs = __importStar(require("node:fs"));
40
42
  const os = __importStar(require("node:os"));
41
43
  const path = __importStar(require("node:path"));
42
44
  exports.DEFAULT_BASE_URL = "https://app.goguava.ai/";
@@ -54,8 +56,20 @@ function getPlatformConfigDir() {
54
56
  return path.join(home, "Library", "Application Support");
55
57
  return process.env.XDG_CONFIG_HOME ?? path.join(home, ".config");
56
58
  }
59
+ function getCliConfigPath() {
60
+ return path.join(getPlatformConfigDir(), "guava", "config.json");
61
+ }
57
62
  function getBaseUrl() {
58
- return process.env.GUAVA_BASE_URL ?? exports.DEFAULT_BASE_URL;
63
+ if (process.env.GUAVA_BASE_URL)
64
+ return process.env.GUAVA_BASE_URL;
65
+ // Try reading from the CLI config.
66
+ const configPath = getCliConfigPath();
67
+ if (fs.existsSync(configPath)) {
68
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
69
+ if (config.base_url)
70
+ return config.base_url;
71
+ }
72
+ return exports.DEFAULT_BASE_URL;
59
73
  }
60
74
  class HttpStatusError extends Error {
61
75
  status;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,oDAUC;AAED,gCAEC;AAcD,oCAaC;AA9CD,4CAA8B;AAC9B,gDAAkC;AAErB,QAAA,gBAAgB,GAAG,yBAAyB,CAAC;AAE1D,SAAgB,oBAAoB;IAClC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QACpC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC1F,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IAC9F,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAAC;IAC5F,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AACnE,CAAC;AAED,SAAgB,UAAU;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,wBAAgB,CAAC;AACxD,CAAC;AAED,MAAM,eAAgB,SAAQ,KAAK;IAEf;IACA;IACA;IACA;IAJlB,YACkB,MAAc,EACd,UAAkB,EAClB,IAAY,EACZ,QAAkB;QAElC,KAAK,CAAC,QAAQ,MAAM,IAAI,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QALjD,WAAM,GAAN,MAAM,CAAQ;QACd,eAAU,GAAV,UAAU,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAQ;QACZ,aAAQ,GAAR,QAAQ,CAAU;QAGlC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAEM,KAAK,UAAU,YAAY,CAChC,KAAwB,EACxB,IAAkB;IAElB,kDAAkD;IAClD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAErC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,oDAUC;AAED,4CAEC;AAED,gCAWC;AAcD,oCAaC;AA5DD,4CAA8B;AAC9B,4CAA8B;AAC9B,gDAAkC;AAErB,QAAA,gBAAgB,GAAG,yBAAyB,CAAC;AAE1D,SAAgB,oBAAoB;IAClC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QACpC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC1F,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IAC9F,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAAC;IAC5F,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AACnE,CAAC;AAED,SAAgB,gBAAgB;IAC9B,OAAO,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AACnE,CAAC;AAED,SAAgB,UAAU;IACxB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAElE,mCAAmC;IACnC,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;IACtC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAA0B,CAAC;QACxF,IAAI,MAAM,CAAC,QAAQ;YAAE,OAAO,MAAM,CAAC,QAAQ,CAAC;IAC9C,CAAC;IAED,OAAO,wBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,eAAgB,SAAQ,KAAK;IAEf;IACA;IACA;IACA;IAJlB,YACkB,MAAc,EACd,UAAkB,EAClB,IAAY,EACZ,QAAkB;QAElC,KAAK,CAAC,QAAQ,MAAM,IAAI,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QALjD,WAAM,GAAN,MAAM,CAAQ;QACd,eAAU,GAAV,UAAU,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAQ;QACZ,aAAQ,GAAR,QAAQ,CAAU;QAGlC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAEM,KAAK,UAAU,YAAY,CAChC,KAAwB,EACxB,IAAkB;IAElB,kDAAkD;IAClD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAErC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "0.18.0";
1
+ export declare const SDK_VERSION = "0.19.0";
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDK_VERSION = void 0;
4
- exports.SDK_VERSION = "0.18.0";
4
+ exports.SDK_VERSION = "0.19.0";
5
5
  //# sourceMappingURL=version.js.map
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Agent testing example — demonstrates agent.test(), agent.testRoleplay(),
3
+ * agent.patch(), and session.evaluate().
4
+ */
5
+
6
+ import type { Call } from "@guava-ai/guava-sdk";
7
+ import { MockCall } from "@guava-ai/guava-sdk";
8
+ import { agent } from "@guava-ai/guava-sdk/examples/help-desk";
9
+
10
+ describe("HelpDeskAgent", () => {
11
+ test("handler unit test - new purchase routes to sales", async () => {
12
+ const suggestion = await agent.handlers.onActionRequest(new MockCall(), "make a new purchase");
13
+ expect(suggestion).toHaveProperty("key", "sales");
14
+ });
15
+
16
+ test("new purchase routes to sales", async () => {
17
+ const session = await agent.test(async (session) => {
18
+ // Wait for the agent to finish its opening turn, then inject a caller utterance.
19
+ await session.waitForTurn();
20
+ session.say("Hi, I'm looking to make a new purchase.");
21
+
22
+ // Wait for the bot to complete its transfer.
23
+ await session.waitForEnd();
24
+ });
25
+
26
+ // You can inspect the full transcript with session.getTranscript()
27
+
28
+ expect(session.executedActions).toContain("sales");
29
+ expect(session.terminationReason).toBe("bot-transfer");
30
+ });
31
+
32
+ test("roleplay - caller buys a table", async () => {
33
+ // testRoleplay() drives the conversation automatically using an LLM as the caller.
34
+ const session = await agent.testRoleplay("You are a caller trying to buy a new table.");
35
+
36
+ expect(session.executedActions).toContain("sales");
37
+ expect(session.terminationReason).toBe("bot-transfer");
38
+ });
39
+
40
+ test("patched agent - sales department closed", async () => {
41
+ // patch() returns a shallow clone with independently overridable callbacks.
42
+ const patched = agent.patch();
43
+
44
+ patched.onAction("sales", async (call: Call) => {
45
+ call.hangup(
46
+ "Tell the caller that the sales department is closed and that they should call back tomorrow from 9am to 5pm.",
47
+ );
48
+ });
49
+
50
+ const session = await patched.testRoleplay("You are a caller trying to buy a new table.");
51
+
52
+ // evaluate() uses an LLM to check natural-language pass/fail criteria against the transcript.
53
+ await session.evaluate({
54
+ passCriteria: ["The agent informed the caller of the business hours from 9am to 5pm."],
55
+ failCriteria: ["The agent transferred the caller to the sales department."],
56
+ });
57
+ });
58
+ });
@@ -3,7 +3,7 @@ import { DocumentQA, IntentRecognizer } from "@guava-ai/guava-sdk/helpers/openai
3
3
  import { FURNITURE_RETAILER_QA } from "@guava-ai/guava-sdk/example-data";
4
4
  import { getDefaultLogger } from "@guava-ai/guava-sdk";
5
5
 
6
- const agent = new guava.Agent({
6
+ export const agent = new guava.Agent({
7
7
  name: "Nova",
8
8
  organization: "Clearfield Home & Living",
9
9
  purpose: "Answer questions and route callers to the appropriate department.",
@@ -55,6 +55,17 @@ agent.onAction("other", async (call: guava.Call) => {
55
55
  );
56
56
  });
57
57
 
58
- export async function run(_args: string[]) {
59
- agent.listenPhone(process.env.GUAVA_AGENT_NUMBER!);
58
+ export async function run(args: string[]) {
59
+ if (args.includes("--webrtc")) {
60
+ await agent.listenWebrtc();
61
+ } else if (args.includes("--phone")) {
62
+ agent.listenPhone(process.env.GUAVA_AGENT_NUMBER!);
63
+ } else if (args.includes("--local")) {
64
+ await agent.callLocal();
65
+ } else if (args.includes("--chat")) {
66
+ await agent.chat();
67
+ } else {
68
+ console.error("Usage: guava-example help-desk --phone | --webrtc | --local | --chat");
69
+ process.exit(1);
70
+ }
60
71
  }
@@ -25,8 +25,10 @@ export async function run(args: string[]) {
25
25
  agent.listenPhone(process.env.GUAVA_AGENT_NUMBER!);
26
26
  } else if (args.includes("--local")) {
27
27
  await agent.callLocal();
28
+ } else if (args.includes("--chat")) {
29
+ await agent.chat();
28
30
  } else {
29
- console.error("Usage: guava-example property-insurance --phone | --webrtc | --local");
31
+ console.error("Usage: guava-example property-insurance --phone | --webrtc | --local | --chat");
30
32
  process.exit(1);
31
33
  }
32
34
  }
@@ -49,8 +49,10 @@ export async function run(args: string[]) {
49
49
  agent.listenPhone(process.env.GUAVA_AGENT_NUMBER!);
50
50
  } else if (args.includes("--local")) {
51
51
  await agent.callLocal();
52
+ } else if (args.includes("--chat")) {
53
+ await agent.chat();
52
54
  } else {
53
- console.error("Usage: guava-example restaurant-waitlist --phone | --webrtc | --local");
55
+ console.error("Usage: guava-example restaurant-waitlist --phone | --webrtc | --local | --chat");
54
56
  process.exit(1);
55
57
  }
56
58
  }
@@ -44,10 +44,17 @@ agent.onTaskComplete("schedule_appointment", async (call) => {
44
44
  });
45
45
 
46
46
  export async function run(args: string[]) {
47
+ if (args.includes("--chat")) {
48
+ const patientName = args[args.indexOf("--chat") + 1] ?? "Benjamin Buttons";
49
+ await agent.chat({ patientName });
50
+ return;
51
+ }
52
+
47
53
  const [toNumber, patientName = "Benjamin Buttons"] = args;
48
54
 
49
55
  if (!toNumber) {
50
56
  console.error("Usage: guava-example scheduling-outbound <phone> [name]");
57
+ console.error(" guava-example scheduling-outbound --chat [name]");
51
58
  process.exit(1);
52
59
  }
53
60
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@guava-ai/guava-sdk",
3
3
  "description": "The official TypeScript SDK for building Guava voice agents.",
4
4
  "homepage": "https://docs.goguava.ai/typescript-sdk/",
5
- "version": "0.18.0",
5
+ "version": "0.19.0",
6
6
  "type": "commonjs",
7
7
  "main": "dist/src/index.js",
8
8
  "types": "dist/src/index.d.ts",
@@ -18,12 +18,19 @@
18
18
  "./example-data": {
19
19
  "types": "./dist/src/example-data.d.ts",
20
20
  "default": "./dist/src/example-data.js"
21
+ },
22
+ "./examples/help-desk": {
23
+ "types": "./dist/examples/help-desk.d.ts",
24
+ "default": "./dist/examples/help-desk.js"
21
25
  }
22
26
  },
23
27
  "devDependencies": {
24
28
  "@biomejs/biome": "2.4.9",
29
+ "@types/jest": "^30.0.0",
25
30
  "@types/node": "^25.0.7",
26
31
  "@types/ws": "^8.18.1",
32
+ "jest": "^30.4.2",
33
+ "ts-jest": "^29.4.11",
27
34
  "tsx": "^4.21.0",
28
35
  "typescript": "^5.9.3"
29
36
  },
@@ -42,6 +49,7 @@
42
49
  "autofix": "npm run format && npm run lint-fix",
43
50
  "check-format": "biome format ./src ./examples",
44
51
  "format": "biome format --write ./src ./examples",
52
+ "test": "jest",
45
53
  "check": "npm run typecheck && npm audit && npm run lint && npm run check-format",
46
54
  "clean": "rm -rf ./dist",
47
55
  "build": "tsx scripts/update-version.ts && tsc && chmod +x ./dist/bin/example-runner.js",