@guava-ai/guava-sdk 0.5.0 → 0.7.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 (44) hide show
  1. package/bin/example-runner.ts +28 -0
  2. package/dist/bin/example-runner.d.ts +2 -0
  3. package/dist/bin/example-runner.js +60 -0
  4. package/dist/bin/example-runner.js.map +1 -0
  5. package/dist/examples/credit-card-activation.d.ts +1 -1
  6. package/dist/examples/credit-card-activation.js +40 -7
  7. package/dist/examples/credit-card-activation.js.map +1 -1
  8. package/dist/examples/property-insurance.d.ts +1 -1
  9. package/dist/examples/property-insurance.js +41 -8
  10. package/dist/examples/property-insurance.js.map +1 -1
  11. package/dist/examples/scheduling-outbound.d.ts +1 -1
  12. package/dist/examples/scheduling-outbound.js +54 -21
  13. package/dist/examples/scheduling-outbound.js.map +1 -1
  14. package/dist/examples/thai-palace.d.ts +1 -1
  15. package/dist/examples/thai-palace.js +42 -9
  16. package/dist/examples/thai-palace.js.map +1 -1
  17. package/dist/package.json +6 -6
  18. package/dist/src/action_item.js +51 -13
  19. package/dist/src/action_item.js.map +1 -1
  20. package/dist/src/call-controller.js +22 -19
  21. package/dist/src/call-controller.js.map +1 -1
  22. package/dist/src/commands.js +66 -30
  23. package/dist/src/commands.js.map +1 -1
  24. package/dist/src/events.js +72 -35
  25. package/dist/src/events.js.map +1 -1
  26. package/dist/src/example-data.js +6 -2
  27. package/dist/src/example-data.js.map +1 -1
  28. package/dist/src/helpers/openai.js +52 -16
  29. package/dist/src/helpers/openai.js.map +1 -1
  30. package/dist/src/index.js +71 -29
  31. package/dist/src/index.js.map +1 -1
  32. package/dist/src/logging.js +6 -2
  33. package/dist/src/logging.js.map +1 -1
  34. package/dist/src/telemetry.js +18 -12
  35. package/dist/src/telemetry.js.map +1 -1
  36. package/dist/src/utils.js +9 -4
  37. package/dist/src/utils.js.map +1 -1
  38. package/examples/credit-card-activation.ts +1 -5
  39. package/examples/property-insurance.ts +1 -5
  40. package/examples/scheduling-outbound.ts +13 -17
  41. package/examples/thai-palace.ts +1 -5
  42. package/package.json +6 -6
  43. package/src/index.ts +1 -1
  44. package/bin/example-runner.js +0 -33
@@ -17,7 +17,7 @@ class SchedulingController extends guava.CallController {
17
17
  sourceList: mockAppointmentsForFuture(),
18
18
  });
19
19
 
20
- // Use setPersona to set basic information about the agent, as well as it's high-level purpose.
20
+ // Use setPersona to set basic information about the agent, as well as its high-level purpose.
21
21
  this.setPersona({
22
22
  organizationName: "Bright Smile Dental",
23
23
  agentName: "Grace",
@@ -32,32 +32,32 @@ class SchedulingController extends guava.CallController {
32
32
  }
33
33
 
34
34
  private scheduleRecipient() {
35
- // In the branch where we reached the intended participant,
36
- // set a task to collect the desired appointment time.
35
+ // We have now confirmed that we are talking to the patient.
36
+ // Set the Agent's current task to collect the desired appointment time.
37
37
  this.setTask(
38
38
  {
39
39
  // The check list is an ordered list of items for the agent to go through.
40
+ // It can include short prompts as well as Fields to capture structured information.
40
41
  checklist: [
41
- // guava.Say instructions are verbatim.
42
- guava.Say("Let me look to see what appointment times we have available."),
42
+ "tell them that it's been a while since their regular cleaning with Dr. Teeth, and ask if they would like to schedule an appointment now.",
43
43
  // We have one field to collect, which is the appointment_time.
44
44
  guava.Field({
45
45
  key: "appointment_time",
46
46
  fieldType: "calendar_slot",
47
47
  description: "Find a time that works for the caller",
48
48
 
49
- // This field has a choice generator attached. The agent will invoke this function
50
- // with a natural language query, allowing the caller to select between the different options.
51
- // The agent can potentially invoke the callback multiple times if the caller rejects the options
52
- // or provides a new query.
49
+ // The choiceGenerator will be called when negotiating a calendar slot.
50
+ // We respond with a list of datetime options based on the user's
51
+ // criteria, which is summarized in the query string.
53
52
  choiceGenerator: async (query: string) => {
54
- // Use the simple DatetimeFilter class we instantiated earlier.
53
+ // Query will have some natural language preferences like "early morning" or
54
+ // "next week". The dateTime filter queries our calendar for matching slots.
55
55
  const result = await this.datetimeFilter.filter(query, { maxResults: 3 });
56
- this.logger.info("Choice generator results: %s", JSON.stringify(result));
56
+ this.logger.info("Appointment slot matches: %s", JSON.stringify(result));
57
57
  return result;
58
58
  },
59
59
  }),
60
- guava.Say("Your appointment has been confirmed! Have a nice day."),
60
+ "tell them their appointment has been confirmed and answer any questions before ending the call.",
61
61
  ],
62
62
  },
63
63
  () => this.hangup("Thank them for their time and hang up the call."),
@@ -77,7 +77,7 @@ class SchedulingController extends guava.CallController {
77
77
  }
78
78
  }
79
79
 
80
- export function run(args: string[]) {
80
+ export async function run(args: string[]) {
81
81
  const [toNumber, patientName = "Benjamin Buttons"] = args;
82
82
 
83
83
  if (!toNumber) {
@@ -91,7 +91,3 @@ export function run(args: string[]) {
91
91
  new SchedulingController(patientName),
92
92
  );
93
93
  }
94
-
95
- if (import.meta.main) {
96
- run(process.argv.slice(2));
97
- }
@@ -59,13 +59,9 @@ class ThaiPalaceCallController extends guava.CallController {
59
59
  }
60
60
  }
61
61
 
62
- export function run(_args: string[]) {
62
+ export async function run(_args: string[]) {
63
63
  new guava.Client().listenInbound(
64
64
  { agent_number: process.env.GUAVA_AGENT_NUMBER! },
65
65
  (logger) => new ThaiPalaceCallController(getConsoleLogger("debug")),
66
66
  );
67
67
  }
68
-
69
- if (import.meta.main) {
70
- run([]);
71
- }
package/package.json CHANGED
@@ -2,22 +2,22 @@
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.5.0",
6
- "type": "module",
5
+ "version": "0.7.0",
6
+ "type": "commonjs",
7
7
  "main": "dist/src/index.js",
8
8
  "types": "dist/src/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./dist/src/index.d.ts",
12
- "import": "./dist/src/index.js"
12
+ "default": "./dist/src/index.js"
13
13
  },
14
14
  "./helpers/openai": {
15
15
  "types": "./dist/src/helpers/openai.d.ts",
16
- "import": "./dist/src/helpers/openai.js"
16
+ "default": "./dist/src/helpers/openai.js"
17
17
  },
18
18
  "./example-data": {
19
19
  "types": "./dist/src/example-data.d.ts",
20
- "import": "./dist/src/example-data.js"
20
+ "default": "./dist/src/example-data.js"
21
21
  }
22
22
  },
23
23
  "devDependencies": {
@@ -28,7 +28,7 @@
28
28
  "typescript": "^5.9.3"
29
29
  },
30
30
  "bin": {
31
- "guava-example": "./bin/example-runner.js"
31
+ "guava-example": "./dist/bin/example-runner.js"
32
32
  },
33
33
  "dependencies": {
34
34
  "openai": "^6.16.0",
package/src/index.ts CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  } from "./commands.ts";
8
8
  import * as z from "zod";
9
9
  import { ErrorEvent, SessionStartedEvent, decodeEvent, InboundTunnelEvent } from "./events.ts";
10
- import pkgdata from "../package.json" with { type: "json" };
10
+ import pkgdata from "../package.json";
11
11
  import os from "node:os";
12
12
  import { getBaseUrl, fetchOrThrow } from "./utils.ts";
13
13
  import { telemetryClient } from "./telemetry.ts";
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { readdirSync } from "node:fs";
4
- import { fileURLToPath } from "node:url";
5
-
6
- const examplesURL = new URL("../dist/examples/", import.meta.url);
7
- const examplesDir = fileURLToPath(examplesURL);
8
- const availableExamples = readdirSync(examplesDir).filter(f => f.endsWith(".js")).map(f => f.replace(/\.js$/, ""));
9
-
10
- const exampleName = process.argv[2];
11
- if (!exampleName) {
12
- console.error("Usage: guava-example <example-name> <example-args>");
13
- console.error("Available examples:", availableExamples.join(", "))
14
- process.exit(1);
15
- }
16
-
17
- if (!availableExamples.includes(exampleName)) {
18
- console.error(`Unknown example "${exampleName}". Available examples: ${availableExamples.join(", ")}`);
19
- process.exit(1);
20
- }
21
-
22
- const run = async () => {
23
- try {
24
- // ESM dynamic import works in both ESM packages and CJS CLI files in modern Node
25
- const exampleModule = await import(new URL(`${exampleName}.js`, examplesURL));
26
- await exampleModule.run(process.argv.slice(3));
27
- } catch (err) {
28
- console.error(err);
29
- process.exit(1);
30
- }
31
- };
32
-
33
- run();