@fonoster/autopilot 0.7.4 → 0.7.5

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 (102) hide show
  1. package/README.md +156 -2
  2. package/dist/Autopilot.d.ts +3 -7
  3. package/dist/Autopilot.js +19 -36
  4. package/dist/assistants/AssistantSchema.d.ts +575 -30
  5. package/dist/assistants/AssistantSchema.js +41 -13
  6. package/dist/assistants/index.d.ts +1 -3
  7. package/dist/assistants/index.js +1 -6
  8. package/dist/assistants/loadAndValidateAssistant.d.ts +2 -2
  9. package/dist/assistants/loadAndValidateAssistant.js +3 -3
  10. package/dist/assistants/types.d.ts +6 -24
  11. package/dist/assistants/types.js +0 -25
  12. package/dist/createLanguageModel.d.ts +3 -0
  13. package/dist/createLanguageModel.js +40 -0
  14. package/dist/envs.d.ts +1 -0
  15. package/dist/envs.js +2 -1
  16. package/dist/handleVoiceRequest.d.ts +3 -0
  17. package/dist/handleVoiceRequest.js +66 -0
  18. package/dist/index.d.ts +9 -1
  19. package/dist/index.js +23 -3
  20. package/dist/knowledge/AbstractKnowledgeBase.d.ts +13 -0
  21. package/dist/knowledge/AbstractKnowledgeBase.js +18 -0
  22. package/dist/knowledge/FilesKnowledgeBase.d.ts +12 -0
  23. package/dist/knowledge/FilesKnowledgeBase.js +50 -0
  24. package/dist/knowledge/index.d.ts +3 -0
  25. package/dist/knowledge/index.js +37 -0
  26. package/dist/knowledge/types.d.ts +4 -0
  27. package/dist/knowledge/types.js +2 -0
  28. package/dist/loadAssistantConfig.d.ts +3 -0
  29. package/dist/loadAssistantConfig.js +26 -0
  30. package/dist/loadKnowledgeBase.d.ts +3 -0
  31. package/dist/loadKnowledgeBase.js +29 -0
  32. package/dist/machine/machine.d.ts +27 -28
  33. package/dist/machine/machine.js +44 -30
  34. package/dist/models/AbstractLanguageModel.d.ts +11 -0
  35. package/dist/models/AbstractLanguageModel.js +78 -0
  36. package/dist/models/LanguageModelFactory.d.ts +16 -0
  37. package/dist/models/LanguageModelFactory.js +44 -0
  38. package/dist/models/chatHistory.d.ts +6 -0
  39. package/dist/models/chatHistory.js +32 -0
  40. package/dist/models/createChain.d.ts +7 -0
  41. package/dist/models/createChain.js +15 -0
  42. package/dist/models/createPromptTemplate.d.ts +2 -0
  43. package/dist/{assistants/assistants.js → models/createPromptTemplate.js} +7 -16
  44. package/dist/models/groq/Groq.d.ts +7 -0
  45. package/dist/models/groq/Groq.js +22 -0
  46. package/dist/models/groq/index.d.ts +2 -0
  47. package/dist/models/groq/index.js +36 -0
  48. package/dist/models/groq/types.d.ts +13 -0
  49. package/dist/models/groq/types.js +9 -0
  50. package/dist/models/index.d.ts +2 -0
  51. package/dist/models/index.js +36 -0
  52. package/dist/models/openai/OpenAI.d.ts +7 -0
  53. package/dist/models/openai/OpenAI.js +22 -0
  54. package/dist/models/openai/index.d.ts +2 -0
  55. package/dist/models/openai/index.js +36 -0
  56. package/dist/models/openai/types.d.ts +12 -0
  57. package/dist/models/openai/types.js +8 -0
  58. package/dist/models/types.d.ts +19 -0
  59. package/dist/models/types.js +2 -0
  60. package/dist/server.js +23 -0
  61. package/dist/tools/ToolSchema.d.ts +107 -0
  62. package/dist/tools/ToolSchema.js +64 -0
  63. package/dist/tools/ToolsCatalog.d.ts +11 -0
  64. package/dist/tools/ToolsCatalog.js +52 -0
  65. package/dist/tools/builtin/hangupToolDefinition.d.ts +3 -0
  66. package/dist/tools/builtin/hangupToolDefinition.js +35 -0
  67. package/dist/tools/builtin/transferToolDefinition.d.ts +3 -0
  68. package/dist/tools/builtin/transferToolDefinition.js +35 -0
  69. package/dist/tools/convertToolToOpenAITool.d.ts +3 -0
  70. package/dist/tools/convertToolToOpenAITool.js +11 -0
  71. package/dist/tools/index.d.ts +4 -0
  72. package/dist/tools/index.js +38 -0
  73. package/dist/tools/sendRequest.d.ts +11 -0
  74. package/dist/tools/sendRequest.js +43 -0
  75. package/dist/tools/type.d.ts +8 -0
  76. package/dist/tools/type.js +2 -0
  77. package/dist/types.d.ts +14 -6
  78. package/dist/types.js +6 -0
  79. package/dist/vad/SileroVad.d.ts +8 -0
  80. package/dist/vad/SileroVad.js +39 -0
  81. package/dist/vad/index.d.ts +1 -2
  82. package/dist/vad/index.js +1 -2
  83. package/dist/vad/makeVad.d.ts +1 -1
  84. package/dist/vad/makeVad.js +2 -2
  85. package/dist/vad/types.d.ts +4 -2
  86. package/dist/voice/Voice.d.ts +25 -0
  87. package/dist/voice/Voice.js +81 -0
  88. package/dist/voice/index.d.ts +2 -0
  89. package/dist/voice/index.js +36 -0
  90. package/dist/voice/types.d.ts +23 -0
  91. package/dist/voice/types.js +2 -0
  92. package/dist/voiceServerSetup.d.ts +2 -0
  93. package/dist/{runner.js → voiceServerSetup.js} +5 -22
  94. package/package.json +15 -7
  95. package/dist/assistants/assistants.d.ts +0 -4
  96. package/dist/machine/machinev0.d.ts +0 -163
  97. package/dist/machine/machinev0.js +0 -142
  98. package/dist/machine/types.d.ts +0 -29
  99. package/dist/machine/types.js +0 -9
  100. package/dist/runner.d.ts +0 -2
  101. package/dist/vad/micVadTest.js +0 -48
  102. /package/dist/{vad/micVadTest.d.ts → server.d.ts} +0 -0
package/README.md CHANGED
@@ -1,3 +1,157 @@
1
- <a href="https://gitpod.io/#https://github.com/fonoster/fonoster"> <img src="https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod" alt="Contribute with Gitpod" />
1
+ autopilot
2
+ =================
3
+
4
+ [![Autopilot](https://img.shields.io/badge/autopilot-api-brightgreen.svg)](https://fonoster.com)
5
+ [![Version](https://img.shields.io/npm/v/@fonoster/autopilot.svg)](https://npmjs.org/package/@fonoster/autopilot)
6
+ [![Downloads/week](https://img.shields.io/npm/dw/@fonoster/autopilot.svg)](https://npmjs.org/package/@fonoster/autopilot)
7
+ [![License](https://img.shields.io/npm/l/@fonoster/autopilot.svg)](https://github.com/fonoster/fonoster/blob/main/package.json)
8
+
9
+ The autopilot module provides a way to create Voice AI applications in Fonoster. It uses Fonoster internal Voice API and the power of Large Language Models to create a conversational experience with the calling party.
10
+
11
+ * [Installation](#installation)
12
+ * [Example](#example)
13
+ * [Adding Knowledge Base](#configuring-the-knowledge-base)
14
+ * [Adding Tools](#configuring-the-tools)
15
+ * [What's Next](#whats-next)
16
+
17
+ > [!WARNING]
18
+ > This is an overview of Fonoster's Autopilot. This module is still under heavy development, and the API is subject to change. This overview implements OpenAI models, but we are working to bring support for other providers like Groq and others.
19
+
20
+ ## Installation
21
+
22
+ ```sh-session
23
+ $ npm install -g @fonoster/autopilot
24
+ ```
25
+
26
+ The previous command will install the module globally.
27
+
28
+ ## Example
29
+
30
+ To function, Autopilot needs a configuration file, an OpenAI API key, and an active Fonoster account or self-hosted Fonoster instance.
31
+
32
+ The configuration file has two major sections: `conversationSettings` and `languageModel`. The `conversationSettings` section contains the settings for the conversation, like the first message, the system template, and the transfer options. The `languageModel` section contains the settings for the language model, like the provider, the model, and the temperature, among others.
33
+
34
+ ```json
35
+ {
36
+ "conversationSettings": {
37
+ "firstMessage": "Hello, this is Olivia from Dr. Green's Family Medicine. How can I assist you today?",
38
+ "systemTemplate": "You are a Customer Service Representative. You are here to help the caller with their needs.",
39
+ "systemErrorMessage": "I'm sorry, but I seem to be having trouble. Please try again later.",
40
+ "initialDtmf": "6589",
41
+ "transferOptions": {
42
+ "enabled": true,
43
+ "phoneNumber": "+15555555555",
44
+ "message": "Please hold while I transfer you to a live agent."
45
+ },
46
+ "idleOptions": {
47
+ "enabled": true,
48
+ "message": "Are you still there?",
49
+ "timeout": 10000,
50
+ "maxTimeoutCount": 3
51
+ }
52
+ },
53
+ "languageModel": {
54
+ "provider": "openai",
55
+ "model": "gpt-4o-mini",
56
+ "maxTokens": 250,
57
+ "temperature": 0.7,
58
+ "knowledgeBase": [],
59
+ "tools": []
60
+ }
61
+ }
62
+ ```
63
+
64
+ To run the Autopilot, you can use the following command:
65
+
66
+ ```sh-session
67
+ $ ASSISTANTS=$(pwd)/assistants.json OPEN_API_KEY=your-ley autopilot
68
+ ```
69
+
70
+ You will see a message like this:
71
+
72
+ ```sh-session
73
+ 2024-09-06 11:32:16.584 [info]: (voice) started voice server @ 0.0.0.0, port=50061 {}
74
+ ```
75
+
76
+ This means that the Autopilot is running and ready to take calls.
77
+
78
+ Since you are running Autopilot locally, you must expose port 50061 to the Internet. To expose the port, you can use a service like [ngrok](https://ngrok.com/)
79
+
80
+ ```sh-session
81
+ $ ngrok tcp 50061
82
+ ```
83
+
84
+ Take the endpoint provided by ngrok and configure it in your Fonoster account. You can find more information about how to do this in the [Fonoster documentation](https://fonoster.com/docs).
85
+
86
+ ## Language Model Providers
87
+
88
+ The Autopilot supports multiple language model providers. The following is a list of the supported providers:
89
+
90
+ | Provider | Description | Supported models
91
+ |------------|------------------------------------------------------------|------------------------------------------------------------------------------|
92
+ | OpenAI | OpenAI provides various GPT models for conversational AI | `gpt-4o`, `gpt-40-mini` |
93
+ | Groq | Groq offers high-performance AI models optimized for speed | `gemm-7b-it`, `llama3-groq-70b-8192-tool-use-preview`, `llama3-1-8b-instant` |
94
+
95
+ ## Adding Knowledge Base
96
+
97
+ Coming soon...
98
+
99
+ ## Adding Tools
100
+
101
+ A tool in Autopilot is a way to interact with external services to get information or perform actions. For example, you can use a tool to get the weather, the latest news, or an SMS.
102
+
103
+ You can configure a new tool by adding a new entry in the `tools` array in the configuration file. The following is an example tool that gets the available appointment times for a specific date.
104
+
105
+ ```json
106
+ {
107
+ "conversationSettings": { ... },
108
+ "languageModel": {
109
+ "provider": "openai",
110
+ "model": "gpt-4o-mini",
111
+ "maxTokens": 250,
112
+ "temperature": 0.7,
113
+ "knowledgeBase": [],
114
+ "tools": [
115
+ {
116
+ "name": "getAvailableTimes",
117
+ "description": "Get available appointment times for a specific date.",
118
+ "parameters": {
119
+ "type": "object",
120
+ "properties": {
121
+ "date": {
122
+ "type": "string",
123
+ "format": "date"
124
+ }
125
+ },
126
+ "required": [
127
+ "date"
128
+ ]
129
+ },
130
+ "operation": {
131
+ "type": "get",
132
+ "url": "https://api.example.com/appointment-times"
133
+ }
134
+ }
135
+ ]
136
+ }
137
+ }
138
+ ```
139
+
140
+ In addition to the `get` operation type, you can use the `post` operation type. The `post` operation type is used when sending data to the tool. When sending a post, you can optionally set `waitForResponse` to false, which will "fire and forget" the request. The default behavior is to wait for the response.
141
+
142
+ The expected format for the response is a JSON object with the following structure:
143
+
144
+ ```json
145
+ { "result": "text to pass to the language model" }
146
+ ```
147
+
148
+ For example:
149
+
150
+ ```json
151
+ { "result": "The available appointment times are 9:00 AM, 10:00 AM, and 11:00 AM." }
152
+ ```
153
+
154
+ ## What's Next
155
+
156
+ The Autopilot is still under heavy development. The next steps are to add support for Retrieval-Augmented Generation(RAG), improve the language model integration, and improve the Finite State Machine (FSM) that powers the conversations. If you have any suggestions or feedback, please let us know.
2
157
 
3
- This module is part of the [Fonoster](https://fonoster.com) project. By itself, it does not do much. It is intended to be used as a dependency for other modules. For more information about the project, please visit [https://github.com/fonoster/fonoster](https://github.com/fonoster/fonoster).
@@ -1,13 +1,9 @@
1
- import { AutopilotConfig } from "./types";
1
+ import { AutopilotParams } from "./types";
2
2
  declare class Autopilot {
3
- private config;
4
- private assistant;
3
+ private params;
5
4
  private actor;
6
- private voice;
7
- constructor(config: AutopilotConfig);
5
+ constructor(params: AutopilotParams);
8
6
  start(): void;
9
- private createActor;
10
- private subscribeToActorState;
11
7
  private setupVoiceStream;
12
8
  private handleVoicePayload;
13
9
  private setupSpeechGathering;
package/dist/Autopilot.js CHANGED
@@ -19,55 +19,40 @@ exports.Autopilot = void 0;
19
19
  * See the License for the specific language governing permissions and
20
20
  * limitations under the License.
21
21
  */
22
- const common_1 = require("@fonoster/common");
23
22
  const logger_1 = require("@fonoster/logger");
24
23
  const xstate_1 = require("xstate");
25
- const assistants_1 = require("./assistants");
26
24
  const machine_1 = require("./machine/machine");
27
- const vad_1 = require("./vad");
28
25
  const logger = (0, logger_1.getLogger)({ service: "autopilot", filePath: __filename });
29
26
  class Autopilot {
30
- constructor(config) {
31
- this.config = config;
32
- this.assistant = (0, assistants_1.makeAssistant)(config.assistantConfig);
33
- this.actor = this.createActor();
34
- this.voice = config.voice;
35
- }
36
- start() {
37
- this.actor.start();
38
- this.setupSpeechGathering();
39
- this.setupVoiceStream();
40
- this.subscribeToActorState();
41
- }
42
- createActor() {
43
- const { voice } = this.config;
44
- return (0, xstate_1.createActor)(machine_1.machine, {
27
+ constructor(params) {
28
+ this.params = params;
29
+ const { voice, languageModel, conversationSettings } = this.params;
30
+ this.actor = (0, xstate_1.createActor)(machine_1.machine, {
45
31
  input: {
46
- ...this.config.assistantConfig,
47
- assistant: this.assistant,
32
+ conversationSettings,
33
+ languageModel: languageModel,
48
34
  voice
49
35
  }
50
36
  });
51
37
  }
52
- subscribeToActorState() {
38
+ start() {
39
+ this.actor.start();
53
40
  this.actor.subscribe((state) => {
54
41
  logger.verbose("actor's new state is", { state: state.value });
55
42
  });
43
+ this.setupVoiceStream();
44
+ this.setupSpeechGathering();
56
45
  }
57
46
  async setupVoiceStream() {
58
- const stream = await this.config.voice.stream({
59
- direction: common_1.StreamDirection.OUT
60
- });
61
- const vad = await (0, vad_1.makeVad)();
62
- stream.onPayload(this.handleVoicePayload(vad));
47
+ const { voice, vad } = this.params;
48
+ const stream = await voice.stream();
49
+ stream.onData(this.handleVoicePayload(vad));
63
50
  }
64
51
  handleVoicePayload(vad) {
65
- return async (payload) => {
52
+ return (chunk) => {
66
53
  try {
67
- // TODO: Investigate why we need to cast this to Float32Array
68
- const data = payload.data;
69
- await vad(data, (event) => {
70
- if (event === "SPEECH_START" || event === "SPEECH_END") {
54
+ vad.processChunk(chunk, (event) => {
55
+ if (["SPEECH_START", "SPEECH_END"].includes(event)) {
71
56
  logger.verbose("received speech event", { event });
72
57
  this.actor.send({ type: event });
73
58
  }
@@ -79,11 +64,9 @@ class Autopilot {
79
64
  };
80
65
  }
81
66
  async setupSpeechGathering() {
82
- const stream = await this.voice.sgather({
83
- source: common_1.StreamGatherSource.SPEECH
84
- });
85
- stream.onPayload((payload) => {
86
- const { speech } = payload;
67
+ const { voice } = this.params;
68
+ const stream = await voice.sgather();
69
+ stream.onData((speech) => {
87
70
  logger.verbose("received speech result", { speech });
88
71
  if (speech) {
89
72
  this.actor.send({ type: "SPEECH_RESULT", speech });