@fonoster/autopilot 0.27.0 → 0.31.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/README.md +15 -52
- package/dist/index.d.ts +0 -5
- package/dist/index.js +0 -5
- package/dist/knowledge/AbstractKnowledgeBase.d.ts +3 -2
- package/dist/knowledge/AbstractKnowledgeBase.js +2 -7
- package/dist/knowledge/FilesKnowledgeBase.d.ts +1 -1
- package/dist/knowledge/MeteredEmbeddings.d.ts +47 -0
- package/dist/knowledge/MeteredEmbeddings.js +58 -0
- package/dist/knowledge/types.d.ts +1 -1
- package/dist/models/LanguageModelFactory.d.ts +5 -24
- package/dist/models/LanguageModelFactory.js +0 -1
- package/dist/models/createLanguageModel.d.ts +2 -2
- package/dist/models/createLanguageModel.js +2 -2
- package/dist/models/evaluations/createEvalEffectiveConfig.d.ts +10 -106
- package/dist/models/evaluations/createEvalEffectiveConfig.js +47 -7
- package/dist/models/evaluations/createEvaluateIntelligence.d.ts +21 -20
- package/dist/models/evaluations/createEvaluateIntelligence.js +53 -23
- package/dist/models/evaluations/createTestTextSimilarity.d.ts +7 -1
- package/dist/models/evaluations/createTestTextSimilarity.js +19 -1
- package/dist/models/evaluations/evalTestCases.d.ts +2 -2
- package/dist/models/evaluations/evalTestCases.js +7 -7
- package/dist/models/evaluations/evaluateScenario.js +2 -2
- package/dist/models/evaluations/evaluateStep.d.ts +1 -1
- package/dist/models/evaluations/evaluateStep.js +2 -2
- package/dist/models/evaluations/extractAiResponse.d.ts +2 -3
- package/dist/models/evaluations/extractAiResponse.js +3 -3
- package/dist/models/evaluations/index.d.ts +1 -0
- package/dist/models/evaluations/index.js +1 -0
- package/dist/models/evaluations/runEval.d.ts +2 -20
- package/dist/models/evaluations/runEval.js +7 -7
- package/dist/models/evaluations/session/EvalSession.d.ts +73 -0
- package/dist/models/evaluations/session/EvalSession.js +134 -0
- package/dist/models/evaluations/session/evaluateSessionScenario.d.ts +58 -0
- package/dist/models/evaluations/session/evaluateSessionScenario.js +182 -0
- package/dist/{vad → models/evaluations/session}/index.d.ts +3 -2
- package/dist/{vad → models/evaluations/session}/index.js +3 -2
- package/dist/models/evaluations/session/runSessionEval.d.ts +20 -0
- package/dist/models/evaluations/session/runSessionEval.js +59 -0
- package/dist/models/evaluations/textSimilaryPrompt.d.ts +1 -1
- package/dist/models/evaluations/textSimilaryPrompt.js +1 -1
- package/dist/models/evaluations/types.d.ts +7 -6
- package/dist/models/types.d.ts +19 -1
- package/dist/session/Agent.d.ts +173 -0
- package/dist/session/Agent.js +548 -0
- package/dist/{loadAssistantFromAPI.d.ts → session/AsyncQueue.d.ts} +12 -7
- package/dist/session/AsyncQueue.js +67 -0
- package/dist/{machine/guards/index.d.ts → session/config.d.ts} +2 -2
- package/dist/session/config.js +27 -0
- package/dist/session/createAutopilot.d.ts +48 -0
- package/dist/session/createAutopilot.js +151 -0
- package/dist/session/hosted.d.ts +454 -0
- package/dist/session/hosted.js +501 -0
- package/dist/{assistants → session}/index.d.ts +11 -2
- package/dist/{machine/actors → session}/index.js +11 -3
- package/dist/{machine/actions/appendSpeech.js → session/knowledge.d.ts} +14 -17
- package/dist/session/knowledge.js +10 -0
- package/dist/session/llm.d.ts +113 -0
- package/dist/session/llm.js +127 -0
- package/dist/session/machine.d.ts +206 -0
- package/dist/session/machine.js +126 -0
- package/dist/session/main.js +45 -0
- package/dist/session/meteredThink.d.ts +45 -0
- package/dist/session/meteredThink.js +125 -0
- package/dist/session/sentences.d.ts +5 -0
- package/dist/session/sentences.js +53 -0
- package/dist/session/telemetry.d.ts +34 -0
- package/dist/session/telemetry.js +55 -0
- package/dist/{machine/actors/index.d.ts → session/think.d.ts} +2 -3
- package/dist/{machine/actions/announceSystemError.js → session/think.js} +8 -10
- package/dist/session/tools.d.ts +22 -0
- package/dist/session/tools.js +83 -0
- package/dist/tools/builtin/transferToolDefinition.js +1 -1
- package/dist/voice/index.d.ts +0 -1
- package/dist/voice/index.js +0 -1
- package/dist/voice/types.d.ts +5 -18
- package/package.json +15 -16
- package/dist/Autopilot.d.ts +0 -14
- package/dist/Autopilot.js +0 -133
- package/dist/assistants/index.js +0 -36
- package/dist/assistants/loadAndValidateAssistant.d.ts +0 -3
- package/dist/assistants/loadAndValidateAssistant.js +0 -49
- package/dist/assistants/types.d.ts +0 -24
- package/dist/assistants/types.js +0 -2
- package/dist/envs.d.ts +0 -15
- package/dist/envs.js +0 -78
- package/dist/handleVoiceRequest.d.ts +0 -3
- package/dist/handleVoiceRequest.js +0 -167
- package/dist/loadAssistantConfigFromFile.d.ts +0 -3
- package/dist/loadAssistantConfigFromFile.js +0 -68
- package/dist/loadAssistantFromAPI.js +0 -98
- package/dist/machine/actions/announceSystemError.d.ts +0 -4
- package/dist/machine/actions/appendSpeech.d.ts +0 -1
- package/dist/machine/actions/cleanSpeech.d.ts +0 -1
- package/dist/machine/actions/cleanSpeech.js +0 -23
- package/dist/machine/actions/goodbye.d.ts +0 -4
- package/dist/machine/actions/goodbye.js +0 -31
- package/dist/machine/actions/increaseIdleTimeoutCount.d.ts +0 -1
- package/dist/machine/actions/increaseIdleTimeoutCount.js +0 -31
- package/dist/machine/actions/index.d.ts +0 -26
- package/dist/machine/actions/index.js +0 -37
- package/dist/machine/actions/interruptPlayback.d.ts +0 -4
- package/dist/machine/actions/interruptPlayback.js +0 -43
- package/dist/machine/actions/resetIdleTimeoutCount.d.ts +0 -1
- package/dist/machine/actions/resetIdleTimeoutCount.js +0 -31
- package/dist/machine/actions/resetState.d.ts +0 -1
- package/dist/machine/actions/resetState.js +0 -32
- package/dist/machine/actors/doAnnounceIdleTimeout.d.ts +0 -4
- package/dist/machine/actors/doAnnounceIdleTimeout.js +0 -41
- package/dist/machine/actors/doGreetUser.d.ts +0 -4
- package/dist/machine/actors/doGreetUser.js +0 -45
- package/dist/machine/actors/doProcessUserRequest.d.ts +0 -4
- package/dist/machine/actors/doProcessUserRequest.js +0 -75
- package/dist/machine/context.d.ts +0 -52
- package/dist/machine/context.js +0 -28
- package/dist/machine/delays.d.ts +0 -30
- package/dist/machine/delays.js +0 -37
- package/dist/machine/guards/hasSpeechResult.d.ts +0 -4
- package/dist/machine/guards/hasSpeechResult.js +0 -30
- package/dist/machine/guards/idleTimeoutCountExceedsMax.d.ts +0 -4
- package/dist/machine/guards/idleTimeoutCountExceedsMax.js +0 -31
- package/dist/machine/guards/index.js +0 -25
- package/dist/machine/index.d.ts +0 -19
- package/dist/machine/index.js +0 -23
- package/dist/machine/machine.d.ts +0 -408
- package/dist/machine/machine.js +0 -206
- package/dist/machine/setup.d.ts +0 -328
- package/dist/machine/setup.js +0 -116
- package/dist/machine/types.d.ts +0 -54
- package/dist/machine/types.js +0 -2
- package/dist/sendConversationEndedEvent.d.ts +0 -32
- package/dist/sendConversationEndedEvent.js +0 -66
- package/dist/sendConversationStartedEvent.d.ts +0 -6
- package/dist/sendConversationStartedEvent.js +0 -63
- package/dist/server.d.ts +0 -2
- package/dist/server.js +0 -25
- package/dist/types.d.ts +0 -40
- package/dist/types.js +0 -8
- package/dist/vad/SileroVad.d.ts +0 -18
- package/dist/vad/SileroVad.js +0 -40
- package/dist/vad/SileroVadModel.d.ts +0 -14
- package/dist/vad/SileroVadModel.js +0 -83
- package/dist/vad/chunkToFloat32Array.d.ts +0 -20
- package/dist/vad/chunkToFloat32Array.js +0 -34
- package/dist/vad/createVad.d.ts +0 -3
- package/dist/vad/createVad.js +0 -126
- package/dist/vad/types.d.ts +0 -60
- package/dist/vad/types.js +0 -2
- package/dist/vadWorker.js +0 -36
- package/dist/voice/Voice.d.ts +0 -61
- package/dist/voice/Voice.js +0 -96
- package/dist/voiceServerSetup.d.ts +0 -2
- package/dist/voiceServerSetup.js +0 -29
- /package/dist/{vadWorker.d.ts → session/main.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -12,15 +12,19 @@ The autopilot module provides a way to create Voice AI applications in Fonoster.
|
|
|
12
12
|
* [Example](#example)
|
|
13
13
|
* [Adding Knowledge Base](#configuring-the-knowledge-base)
|
|
14
14
|
* [Adding Tools](#configuring-the-tools)
|
|
15
|
-
* [What's Next](#whats-next)
|
|
16
15
|
|
|
17
16
|
## Installation
|
|
18
17
|
|
|
18
|
+
Autopilot is an ordinary session app that AppBridge dials. Run the
|
|
19
|
+
`fonoster/autopilot` image (built from `mods/autopilot/Dockerfile`), or from the repository:
|
|
20
|
+
|
|
19
21
|
```sh-session
|
|
20
|
-
$
|
|
22
|
+
$ cp config/autopilot-session.example.yaml config/autopilot-session.yaml
|
|
23
|
+
$ node mods/autopilot/dist/session/main.js --config config/autopilot-session.yaml
|
|
21
24
|
```
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
See [docs/autopilot.md](../../docs/autopilot.md) for the engine, pacing and the agent
|
|
27
|
+
schema.
|
|
24
28
|
|
|
25
29
|
## Example
|
|
26
30
|
|
|
@@ -60,7 +64,7 @@ The configuration file has two major sections: `conversationSettings` and `langu
|
|
|
60
64
|
To run the Autopilot, you can use the following command:
|
|
61
65
|
|
|
62
66
|
```sh-session
|
|
63
|
-
$
|
|
67
|
+
$ AGENT=$(pwd)/agents.json OPEN_API_KEY=your-key autopilot
|
|
64
68
|
```
|
|
65
69
|
|
|
66
70
|
You will see a message like this:
|
|
@@ -179,53 +183,12 @@ For example:
|
|
|
179
183
|
{ "result": "The available appointment times are 9:00 AM, 10:00 AM, and 11:00 AM." }
|
|
180
184
|
```
|
|
181
185
|
|
|
182
|
-
##
|
|
183
|
-
|
|
184
|
-
Please use the following environment variables to configure the Autopilot:
|
|
185
|
-
|
|
186
|
-
- `AUTOPILOT_AWS_S3_ACCESS_KEY_ID`: The AWS S3 access key.
|
|
187
|
-
- `AUTOPILOT_AWS_S3_ENDPOINT`: The AWS S3 endpoint.
|
|
188
|
-
- `AUTOPILOT_AWS_S3_REGION`: The AWS S3 region.
|
|
189
|
-
- `AUTOPILOT_AWS_S3_SECRET_ACCESS_KEY`: The AWS S3 secret access key.
|
|
190
|
-
- `AUTOPILOT_CONVERSATION_PROVIDER`: The conversation provider.
|
|
191
|
-
- `AUTOPILOT_KNOWLEDGE_BASE_ENABLED`: Enable knowledge base powered by AWS S3 and Unstructured API.
|
|
192
|
-
- `AUTOPILOT_LOGS_FORMAT`: The logs format.
|
|
193
|
-
- `AUTOPILOT_LOGS_LEVEL`: The logs level.
|
|
194
|
-
- `AUTOPILOT_LOGS_TRANSPORT`: The logs transport.
|
|
195
|
-
- `AUTOPILOT_OPENAI_API_KEY`: The OpenAI API key needed for embeddings support.
|
|
196
|
-
- `AUTOPILOT_UNSTRUCTURED_API_KEY`: The Unstructured API key.
|
|
197
|
-
- `AUTOPILOT_UNSTRUCTURED_API_URL`: The Unstructured API URL. Default is `https://api.unstructured.com`.
|
|
198
|
-
- `AUTOPILOT_RECORDING_BASE_URL`: The recording base URL. Default is `http://localhost:9876/api/recordings`.
|
|
199
|
-
|
|
200
|
-
## What's Next
|
|
201
|
-
|
|
202
|
-
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.
|
|
203
|
-
|
|
204
|
-
## Audio filters
|
|
205
|
-
|
|
206
|
-
Background voices reach speech recognition and the voice activity detector, and the assistant
|
|
207
|
-
answers them. An assistant can ask the Media Server to filter the caller's audio first, by adding
|
|
208
|
-
`audioFilters` to its configuration — the same block whether the assistant comes from a file or
|
|
209
|
-
from an Application:
|
|
210
|
-
|
|
211
|
-
```yaml
|
|
212
|
-
audioFilters:
|
|
213
|
-
- name: aiCoustics
|
|
214
|
-
options:
|
|
215
|
-
enhancementLevel: 0.8 # 0 to 1; higher also suppresses competing voices
|
|
216
|
-
|
|
217
|
-
conversationSettings:
|
|
218
|
-
firstMessage: "Hola, ¿en qué puedo ayudarte?"
|
|
219
|
-
# ...
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
For an Application, the same block goes inside `intelligence.config`, and is applied with:
|
|
186
|
+
## Configuration
|
|
223
187
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
188
|
+
Autopilot reads `autopilot-session.yaml`, found via `--config <path>`, the
|
|
189
|
+
`AUTOPILOT_SESSION_CONFIG` variable or `./config/autopilot-session.yaml`. It names the signing
|
|
190
|
+
secret AppBridge uses for Autopilot apps, where apps and agents come from, the registry
|
|
191
|
+
catalog, platform keys by credential ref and the knowledge settings. See
|
|
192
|
+
`config/autopilot-session.example.yaml` for every key.
|
|
227
193
|
|
|
228
|
-
|
|
229
|
-
and an `AIC_SDK_LICENSE` key on the apiserver; the key never appears in assistant configuration,
|
|
230
|
-
so these files stay safe to commit. If the filter cannot be applied, the call continues with
|
|
231
|
-
unfiltered audio and the reason is logged.
|
|
194
|
+
Audio filters are part of the app's configuration (AppBridge runs them), not the agent's.
|
package/dist/index.d.ts
CHANGED
|
@@ -16,12 +16,7 @@
|
|
|
16
16
|
* See the License for the specific language governing permissions and
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
|
-
import { Autopilot } from "./Autopilot";
|
|
20
|
-
export default Autopilot;
|
|
21
|
-
export * from "./assistants";
|
|
22
19
|
export * from "./knowledge";
|
|
23
20
|
export * from "./models";
|
|
24
21
|
export * from "./tools";
|
|
25
|
-
export * from "./types";
|
|
26
|
-
export * from "./vad";
|
|
27
22
|
export * from "./voice";
|
package/dist/index.js
CHANGED
|
@@ -32,12 +32,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
32
32
|
* See the License for the specific language governing permissions and
|
|
33
33
|
* limitations under the License.
|
|
34
34
|
*/
|
|
35
|
-
const Autopilot_1 = require("./Autopilot");
|
|
36
|
-
exports.default = Autopilot_1.Autopilot;
|
|
37
|
-
__exportStar(require("./assistants"), exports);
|
|
38
35
|
__exportStar(require("./knowledge"), exports);
|
|
39
36
|
__exportStar(require("./models"), exports);
|
|
40
37
|
__exportStar(require("./tools"), exports);
|
|
41
|
-
__exportStar(require("./types"), exports);
|
|
42
|
-
__exportStar(require("./vad"), exports);
|
|
43
38
|
__exportStar(require("./voice"), exports);
|
|
@@ -4,8 +4,9 @@ import { KnowledgeBase } from "./types";
|
|
|
4
4
|
declare abstract class AbstractKnowledgeBase implements KnowledgeBase {
|
|
5
5
|
protected embeddings: Embeddings;
|
|
6
6
|
protected vectorStore: VectorStore;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
/** The embeddings come from the caller (the hosted Autopilot resolves their key by credentialRef). */
|
|
8
|
+
constructor(params: {
|
|
9
|
+
embeddings: Embeddings;
|
|
9
10
|
});
|
|
10
11
|
abstract getLoaders(): Promise<unknown>;
|
|
11
12
|
load(): Promise<void>;
|
|
@@ -21,17 +21,12 @@ exports.AbstractKnowledgeBase = void 0;
|
|
|
21
21
|
*/
|
|
22
22
|
const logger_1 = require("@fonoster/logger");
|
|
23
23
|
const memory_1 = require("@langchain/classic/vectorstores/memory");
|
|
24
|
-
const openai_1 = require("@langchain/openai");
|
|
25
24
|
const textsplitters_1 = require("@langchain/textsplitters");
|
|
26
|
-
const envs_1 = require("../envs");
|
|
27
25
|
const logger = (0, logger_1.getLogger)({ service: "autopilot", filePath: __filename });
|
|
28
26
|
class AbstractKnowledgeBase {
|
|
27
|
+
/** The embeddings come from the caller (the hosted Autopilot resolves their key by credentialRef). */
|
|
29
28
|
constructor(params) {
|
|
30
|
-
this.embeddings =
|
|
31
|
-
params?.embeddings ||
|
|
32
|
-
new openai_1.OpenAIEmbeddings({
|
|
33
|
-
apiKey: envs_1.OPENAI_API_KEY
|
|
34
|
-
});
|
|
29
|
+
this.embeddings = params.embeddings;
|
|
35
30
|
}
|
|
36
31
|
async load() {
|
|
37
32
|
const loaders = (await this.getLoaders());
|
|
@@ -22,7 +22,7 @@ import { AbstractKnowledgeBase } from "./AbstractKnowledgeBase";
|
|
|
22
22
|
declare class FilesKnowledgeBase extends AbstractKnowledgeBase {
|
|
23
23
|
private params;
|
|
24
24
|
constructor(params: {
|
|
25
|
-
embeddings
|
|
25
|
+
embeddings: Embeddings;
|
|
26
26
|
files: string[];
|
|
27
27
|
});
|
|
28
28
|
getLoaders(): Promise<PDFLoader[]>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
3
|
+
* http://github.com/fonoster/fonoster
|
|
4
|
+
*
|
|
5
|
+
* This file is part of Fonoster
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the MIT License (the "License");
|
|
8
|
+
* you may not use this file except in compliance with
|
|
9
|
+
* the License. You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* https://opensource.org/licenses/MIT
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
import { Usage } from "@fonoster/common";
|
|
20
|
+
/** Where embedding usage goes (the session's usage sink). */
|
|
21
|
+
export type EmbeddingUsageSink = {
|
|
22
|
+
usage(lines: Usage.UsageLine[]): void;
|
|
23
|
+
missing(catalogId: string): void;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* OpenAI embeddings that report their token usage (add-usage-metering): the knowledge base's
|
|
27
|
+
* embeddings, called directly so the vendor's `usage.prompt_tokens` is not lost. Same defaults
|
|
28
|
+
* as LangChain's OpenAIEmbeddings (model text-embedding-ada-002, 512 texts per request); it
|
|
29
|
+
* implements the embedDocuments/embedQuery pair LangChain's vector stores use.
|
|
30
|
+
*/
|
|
31
|
+
export declare class MeteredEmbeddings {
|
|
32
|
+
private readonly options;
|
|
33
|
+
private readonly model;
|
|
34
|
+
private readonly baseUrl;
|
|
35
|
+
constructor(options: {
|
|
36
|
+
apiKey: string;
|
|
37
|
+
keySource: Usage.KeySource;
|
|
38
|
+
sink?: EmbeddingUsageSink;
|
|
39
|
+
model?: string;
|
|
40
|
+
baseUrl?: string;
|
|
41
|
+
batchSize?: number;
|
|
42
|
+
});
|
|
43
|
+
get catalogId(): string;
|
|
44
|
+
embedDocuments(texts: string[]): Promise<number[][]>;
|
|
45
|
+
embedQuery(text: string): Promise<number[]>;
|
|
46
|
+
private embed;
|
|
47
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MeteredEmbeddings = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* OpenAI embeddings that report their token usage (add-usage-metering): the knowledge base's
|
|
6
|
+
* embeddings, called directly so the vendor's `usage.prompt_tokens` is not lost. Same defaults
|
|
7
|
+
* as LangChain's OpenAIEmbeddings (model text-embedding-ada-002, 512 texts per request); it
|
|
8
|
+
* implements the embedDocuments/embedQuery pair LangChain's vector stores use.
|
|
9
|
+
*/
|
|
10
|
+
class MeteredEmbeddings {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.options = options;
|
|
13
|
+
this.model = options.model ?? "text-embedding-ada-002";
|
|
14
|
+
this.baseUrl = (options.baseUrl ?? "https://api.openai.com").replace(/\/$/, "");
|
|
15
|
+
}
|
|
16
|
+
get catalogId() {
|
|
17
|
+
return `openai/${this.model}`;
|
|
18
|
+
}
|
|
19
|
+
async embedDocuments(texts) {
|
|
20
|
+
const size = this.options.batchSize ?? 512;
|
|
21
|
+
const batches = Array.from({ length: Math.ceil(texts.length / size) }, (_, i) => texts.slice(i * size, (i + 1) * size));
|
|
22
|
+
const vectors = await Promise.all(batches.map((b) => this.embed(b)));
|
|
23
|
+
return vectors.flat();
|
|
24
|
+
}
|
|
25
|
+
async embedQuery(text) {
|
|
26
|
+
return (await this.embed([text]))[0];
|
|
27
|
+
}
|
|
28
|
+
async embed(input) {
|
|
29
|
+
const res = await fetch(`${this.baseUrl}/v1/embeddings`, {
|
|
30
|
+
method: "POST",
|
|
31
|
+
headers: {
|
|
32
|
+
"content-type": "application/json",
|
|
33
|
+
authorization: `Bearer ${this.options.apiKey}`
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify({ model: this.model, input })
|
|
36
|
+
});
|
|
37
|
+
if (!res.ok)
|
|
38
|
+
throw new Error(`embeddings answered HTTP ${res.status}`);
|
|
39
|
+
const body = (await res.json());
|
|
40
|
+
const tokens = body.usage?.prompt_tokens;
|
|
41
|
+
if (tokens === undefined)
|
|
42
|
+
this.options.sink?.missing(this.catalogId);
|
|
43
|
+
else
|
|
44
|
+
this.options.sink?.usage([
|
|
45
|
+
{
|
|
46
|
+
meter: "embedding.tokens",
|
|
47
|
+
quantity: tokens,
|
|
48
|
+
provider: "openai",
|
|
49
|
+
model: this.catalogId,
|
|
50
|
+
keySource: this.options.keySource
|
|
51
|
+
}
|
|
52
|
+
]);
|
|
53
|
+
return [...body.data]
|
|
54
|
+
.sort((a, b) => a.index - b.index)
|
|
55
|
+
.map((d) => d.embedding);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.MeteredEmbeddings = MeteredEmbeddings;
|
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
3
|
-
* http://github.com/fonoster/fonoster
|
|
4
|
-
*
|
|
5
|
-
* This file is part of Fonoster
|
|
6
|
-
*
|
|
7
|
-
* Licensed under the MIT License (the "License");
|
|
8
|
-
* you may not use this file except in compliance with
|
|
9
|
-
* the License. You may obtain a copy of the License at
|
|
10
|
-
*
|
|
11
|
-
* https://opensource.org/licenses/MIT
|
|
12
|
-
*
|
|
13
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
* See the License for the specific language governing permissions and
|
|
17
|
-
* limitations under the License.
|
|
18
|
-
*/
|
|
19
|
-
import { LanguageModelProvider } from "@fonoster/common";
|
|
20
1
|
import { Voice } from "../voice";
|
|
21
2
|
import { AbstractLanguageModel } from "./AbstractLanguageModel";
|
|
22
3
|
import { AnthropicParams } from "./anthropic";
|
|
@@ -27,11 +8,11 @@ import { OpenAIParams } from "./openai";
|
|
|
27
8
|
import { BaseModelParams, TelephonyContext } from "./types";
|
|
28
9
|
type LanguageModelConstructor<T extends BaseModelParams = BaseModelParams> = new (options: T, voice: Voice, telephonyContext: TelephonyContext) => AbstractLanguageModel;
|
|
29
10
|
type LanguageModelConfigMap = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
11
|
+
openai: OpenAIParams;
|
|
12
|
+
groq: GroqParams;
|
|
13
|
+
ollama: OllamaParams;
|
|
14
|
+
google: GoogleParams;
|
|
15
|
+
anthropic: AnthropicParams;
|
|
35
16
|
};
|
|
36
17
|
declare class LanguageModelFactory {
|
|
37
18
|
private static readonly languageModels;
|
|
@@ -19,7 +19,6 @@ exports.LanguageModelFactory = 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 anthropic_1 = require("./anthropic");
|
|
25
24
|
const google_1 = require("./google");
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
* See the License for the specific language governing permissions and
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
19
|
+
import { EvalAgent, KnowledgeBase, TelephonyContext, Voice } from "..";
|
|
20
20
|
declare function createLanguageModel(params: {
|
|
21
21
|
voice: Voice;
|
|
22
|
-
|
|
22
|
+
agentConfig: EvalAgent;
|
|
23
23
|
knowledgeBase: KnowledgeBase;
|
|
24
24
|
telephonyContext: TelephonyContext;
|
|
25
25
|
}): import("./AbstractLanguageModel").AbstractLanguageModel;
|
|
@@ -21,8 +21,8 @@ exports.createLanguageModel = createLanguageModel;
|
|
|
21
21
|
*/
|
|
22
22
|
const __1 = require("..");
|
|
23
23
|
function createLanguageModel(params) {
|
|
24
|
-
const { voice,
|
|
25
|
-
const { languageModel, conversationSettings } =
|
|
24
|
+
const { voice, agentConfig, knowledgeBase, telephonyContext } = params;
|
|
25
|
+
const { languageModel, conversationSettings } = agentConfig;
|
|
26
26
|
// The transfer tool is only added if the transfer options exist
|
|
27
27
|
const tools = languageModel.tools.concat(conversationSettings.transferOptions
|
|
28
28
|
? [__1.hangupToolDefinition, __1.transferToolDefinition]
|
|
@@ -16,109 +16,13 @@
|
|
|
16
16
|
* See the License for the specific language governing permissions and
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
temperature?: number;
|
|
30
|
-
maxTokens?: number;
|
|
31
|
-
baseUrl?: string;
|
|
32
|
-
knowledgeBase?: {
|
|
33
|
-
type?: "s3";
|
|
34
|
-
title?: string;
|
|
35
|
-
document?: string;
|
|
36
|
-
}[];
|
|
37
|
-
tools?: {
|
|
38
|
-
name?: string;
|
|
39
|
-
description?: string;
|
|
40
|
-
parameters?: {
|
|
41
|
-
type?: "object" | "array";
|
|
42
|
-
properties?: Record<string, {
|
|
43
|
-
type?: string;
|
|
44
|
-
format?: "enum" | "date-time";
|
|
45
|
-
pattern?: string;
|
|
46
|
-
}>;
|
|
47
|
-
required?: string[];
|
|
48
|
-
};
|
|
49
|
-
requestStartMessage?: string;
|
|
50
|
-
operation?: {
|
|
51
|
-
url?: string;
|
|
52
|
-
method?: import("@fonoster/common").AllowedHttpMethod;
|
|
53
|
-
headers?: Record<string, string>;
|
|
54
|
-
waitForResponse?: boolean;
|
|
55
|
-
};
|
|
56
|
-
}[];
|
|
57
|
-
};
|
|
58
|
-
testCases: {
|
|
59
|
-
evalsLanguageModel: {
|
|
60
|
-
apiKey: string;
|
|
61
|
-
provider?: "openai";
|
|
62
|
-
model?: string;
|
|
63
|
-
};
|
|
64
|
-
evalsSystemPrompt?: string;
|
|
65
|
-
scenarios?: {
|
|
66
|
-
description?: string;
|
|
67
|
-
ref?: string;
|
|
68
|
-
telephonyContext?: {
|
|
69
|
-
callDirection?: import("@fonoster/types").CallDirection;
|
|
70
|
-
ingressNumber?: string;
|
|
71
|
-
callerNumber?: string;
|
|
72
|
-
metadata?: Record<string, string>;
|
|
73
|
-
};
|
|
74
|
-
conversation?: {
|
|
75
|
-
expected?: {
|
|
76
|
-
tools?: {
|
|
77
|
-
parameters?: Record<string, any>;
|
|
78
|
-
tool?: string;
|
|
79
|
-
}[];
|
|
80
|
-
text?: {
|
|
81
|
-
type?: "EXACT" | "SIMILAR";
|
|
82
|
-
response?: string;
|
|
83
|
-
};
|
|
84
|
-
};
|
|
85
|
-
userInput?: string;
|
|
86
|
-
}[];
|
|
87
|
-
}[];
|
|
88
|
-
};
|
|
89
|
-
audioFilters?: {
|
|
90
|
-
options?: Record<string, unknown>;
|
|
91
|
-
name?: string;
|
|
92
|
-
}[];
|
|
93
|
-
conversationSettings?: {
|
|
94
|
-
firstMessage?: string;
|
|
95
|
-
systemPrompt?: string;
|
|
96
|
-
goodbyeMessage?: string;
|
|
97
|
-
systemErrorMessage?: string;
|
|
98
|
-
initialDtmf?: string;
|
|
99
|
-
maxSessionDuration?: number;
|
|
100
|
-
maxSpeechWaitTimeout?: number;
|
|
101
|
-
transferOptions?: {
|
|
102
|
-
message?: string;
|
|
103
|
-
phoneNumber?: string;
|
|
104
|
-
timeout?: number;
|
|
105
|
-
};
|
|
106
|
-
idleOptions?: {
|
|
107
|
-
message?: string;
|
|
108
|
-
timeout?: number;
|
|
109
|
-
maxTimeoutCount?: number;
|
|
110
|
-
};
|
|
111
|
-
allowUserBargeIn?: boolean;
|
|
112
|
-
vad?: {
|
|
113
|
-
pathToModel?: string;
|
|
114
|
-
activationThreshold?: number;
|
|
115
|
-
deactivationThreshold?: number;
|
|
116
|
-
debounceFrames?: number;
|
|
117
|
-
};
|
|
118
|
-
};
|
|
119
|
-
eventsHook?: {
|
|
120
|
-
url?: string;
|
|
121
|
-
headers?: Record<string, string>;
|
|
122
|
-
events?: import("@fonoster/common").EventsHookAllowedEvents[];
|
|
123
|
-
};
|
|
124
|
-
};
|
|
19
|
+
import { SessionAgent } from "@fonoster/common";
|
|
20
|
+
import { EvalAgent } from "../types";
|
|
21
|
+
/**
|
|
22
|
+
* The session agent as the evaluations run it: the catalog id split into provider and model,
|
|
23
|
+
* with the keys the caller resolved (never stored in the agent).
|
|
24
|
+
*/
|
|
25
|
+
export declare function createEvalEffectiveConfig(agent: SessionAgent, keys: {
|
|
26
|
+
apiKey?: string;
|
|
27
|
+
evaluationApiKey?: string;
|
|
28
|
+
}): EvalAgent;
|
|
@@ -1,18 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createEvalEffectiveConfig = createEvalEffectiveConfig;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
6
|
+
* http://github.com/fonoster/fonoster
|
|
7
|
+
*
|
|
8
|
+
* This file is part of Fonoster
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the MIT License (the "License");
|
|
11
|
+
* you may not use this file except in compliance with
|
|
12
|
+
* the License. You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* https://opensource.org/licenses/MIT
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
const common_1 = require("@fonoster/common");
|
|
23
|
+
const LLM_PROVIDERS = [
|
|
24
|
+
"openai",
|
|
25
|
+
"groq",
|
|
26
|
+
"ollama",
|
|
27
|
+
"google",
|
|
28
|
+
"anthropic"
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* The session agent as the evaluations run it: the catalog id split into provider and model,
|
|
32
|
+
* with the keys the caller resolved (never stored in the agent).
|
|
33
|
+
*/
|
|
34
|
+
function createEvalEffectiveConfig(agent, keys) {
|
|
35
|
+
const [provider, ...rest] = agent.languageModel.model.split("/");
|
|
36
|
+
if (!LLM_PROVIDERS.includes(provider))
|
|
37
|
+
throw new Error(`evaluations do not support ${provider} models`);
|
|
38
|
+
const testCases = common_1.testCasesSchema.parse(agent.testCases);
|
|
39
|
+
const { provider: _p, apiKey: _k, baseUrl: _b, ...languageModel } = agent.languageModel;
|
|
40
|
+
void _p;
|
|
41
|
+
void _k;
|
|
42
|
+
void _b;
|
|
5
43
|
return {
|
|
6
|
-
|
|
44
|
+
conversationSettings: agent.conversationSettings,
|
|
7
45
|
languageModel: {
|
|
8
|
-
...
|
|
9
|
-
|
|
46
|
+
...languageModel,
|
|
47
|
+
provider: provider,
|
|
48
|
+
model: rest.join("/"),
|
|
49
|
+
apiKey: keys.apiKey
|
|
10
50
|
},
|
|
11
51
|
testCases: {
|
|
12
|
-
...
|
|
52
|
+
...testCases,
|
|
13
53
|
evalsLanguageModel: {
|
|
14
|
-
...
|
|
15
|
-
apiKey: evaluationApiKey
|
|
54
|
+
...testCases.evalsLanguageModel,
|
|
55
|
+
apiKey: keys.evaluationApiKey
|
|
16
56
|
}
|
|
17
57
|
}
|
|
18
58
|
};
|
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
3
|
-
* http://github.com/fonoster/fonoster
|
|
4
|
-
*
|
|
5
|
-
* This file is part of Fonoster
|
|
6
|
-
*
|
|
7
|
-
* Licensed under the MIT License (the "License");
|
|
8
|
-
* you may not use this file except in compliance with
|
|
9
|
-
* the License. You may obtain a copy of the License at
|
|
10
|
-
*
|
|
11
|
-
* https://opensource.org/licenses/MIT
|
|
12
|
-
*
|
|
13
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
* See the License for the specific language governing permissions and
|
|
17
|
-
* limitations under the License.
|
|
18
|
-
*/
|
|
19
|
-
import { IntegrationConfig } from "@fonoster/common";
|
|
1
|
+
import { Usage } from "@fonoster/common";
|
|
20
2
|
import { EvaluateIntelligenceRequest } from "./types";
|
|
21
3
|
type ServerStreamCall = {
|
|
22
4
|
request: EvaluateIntelligenceRequest;
|
|
23
5
|
write: (chunk: Record<string, unknown>) => void;
|
|
24
6
|
end: () => void;
|
|
25
7
|
};
|
|
26
|
-
|
|
8
|
+
/**
|
|
9
|
+
* A model provider's key for a workspace: the workspace's own vendor key, else the platform key
|
|
10
|
+
* by the provider's credentialRef (the control plane decides; integrations.json is gone).
|
|
11
|
+
*/
|
|
12
|
+
export type EvalKeySource = (providerId: string, workspaceRef: string) => Promise<EvalKey | string | undefined>;
|
|
13
|
+
/** A key and whose it is; a bare string is the platform's. */
|
|
14
|
+
export type EvalKey = {
|
|
15
|
+
key: string;
|
|
16
|
+
source: Usage.KeySource;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Where an eval's usage goes (add-usage-metering D5): the workspace, the lines, and a scope that
|
|
20
|
+
* is unique per request within the run, for the lines' ids.
|
|
21
|
+
*/
|
|
22
|
+
export type EvalUsageReporter = (workspaceRef: string, lines: Usage.UsageLine[], scope: string) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Runs an agent's test cases (rework-autopilot 8.2: the agent is a session agent; its
|
|
25
|
+
* catalog id picks the provider, and keys come from `keys`, never from the agent).
|
|
26
|
+
*/
|
|
27
|
+
declare function createEvaluateIntelligence(keys: EvalKeySource, reportUsage?: EvalUsageReporter): (call: ServerStreamCall) => Promise<void>;
|
|
27
28
|
export { createEvaluateIntelligence };
|