@fonoster/amd 0.26.0 → 0.30.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 -37
- package/dist/amd/AmdModel.d.ts +5 -0
- package/dist/amd/AmdModel.js +19 -0
- package/dist/envs.js +3 -8
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -59,10 +59,15 @@ as a channel variable.
|
|
|
59
59
|
|
|
60
60
|
Set it from the dialplan by giving `AMD_MODE` a value before the `AGI()`
|
|
61
61
|
call — apiserver already does this for API-originated calls via
|
|
62
|
-
`
|
|
62
|
+
`amd.mode` in `fonoster.yaml` (see below).
|
|
63
63
|
|
|
64
64
|
## Configuration
|
|
65
65
|
|
|
66
|
+
The sidecar reads these from its container environment only; it never loads a
|
|
67
|
+
`.env` file, in development either. Set them in the container's environment
|
|
68
|
+
(Compose `environment:`, a Kubernetes `env:`), or export them before
|
|
69
|
+
`npm run start:dev`.
|
|
70
|
+
|
|
66
71
|
| env | default | meaning |
|
|
67
72
|
|---|---|---|
|
|
68
73
|
| `AMD_AGI_PORT` | `4573` | FastAGI listener port |
|
|
@@ -76,11 +81,11 @@ call — apiserver already does this for API-originated calls via
|
|
|
76
81
|
|
|
77
82
|
## Enabling it end-to-end
|
|
78
83
|
|
|
79
|
-
Set `
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
Set `amd.enabled: true` and `amd.engine: ml` in the API server's
|
|
85
|
+
`config/fonoster.yaml`. With the engine unset or set to anything but `ml`,
|
|
86
|
+
behavior is unchanged from Asterisk's native `AMD()`. Additionally set
|
|
87
|
+
`amd.mode: full` to opt into the richer variable set — omit it (or leave it
|
|
88
|
+
`compact`) to stay native-AMD-compatible.
|
|
84
89
|
|
|
85
90
|
## Regression corpus
|
|
86
91
|
|
|
@@ -118,38 +123,11 @@ AGI+AudioSocket mechanism and the mode flag work end-to-end; run it with:
|
|
|
118
123
|
npm run integration
|
|
119
124
|
```
|
|
120
125
|
|
|
121
|
-
##
|
|
122
|
-
|
|
123
|
-
This service can also be exercised without `apiserver`, `autopilot`, NATS, or
|
|
124
|
-
Postgres — just this container and a bare Asterisk instance. Unlike the
|
|
125
|
-
integration test above, this path has not been run against a real Asterisk
|
|
126
|
-
box in this repo's CI; treat it as a documented starting point to validate by
|
|
127
|
-
hand:
|
|
128
|
-
|
|
129
|
-
```sh
|
|
130
|
-
docker compose -f mods/amd/docker-compose.smoke.yaml up --build
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
That starts `amd` alongside a `fonoster/asterisk` container using
|
|
134
|
-
`mods/amd/smoke/extensions.conf`, a minimal dialplan with one test
|
|
135
|
-
extension:
|
|
126
|
+
## Status after the rebuild
|
|
136
127
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
same => n,AGI(agi://amd:4573)
|
|
141
|
-
same => n,Verbose(1,AMDSTATUS=${AMDSTATUS} AMDCAUSE=${AMDCAUSE})
|
|
142
|
-
same => n,Hangup()
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Originate a call into extension `7000` playing a known recorded sample (a
|
|
146
|
-
human greeting vs. a voicemail greeting) and check the Asterisk console log
|
|
147
|
-
for the `AMDSTATUS`/`AMDCAUSE` line the `Verbose()` step prints, e.g.:
|
|
148
|
-
|
|
149
|
-
```sh
|
|
150
|
-
docker compose -f mods/amd/docker-compose.smoke.yaml exec asterisk \
|
|
151
|
-
asterisk -rx "channel originate Local/7000@smoke-test application Playback /path/to/sample"
|
|
152
|
-
```
|
|
128
|
+
Asterisk is retired (cleanbreak CB-B6), so the AGI and AudioSocket front end has no caller and its
|
|
129
|
+
Asterisk smoke test is gone. The classifier stays: it moves behind a voice-worker listener in
|
|
130
|
+
`add-media-node` task 4.3.
|
|
153
131
|
|
|
154
132
|
## Development
|
|
155
133
|
|
package/dist/amd/AmdModel.d.ts
CHANGED
|
@@ -10,6 +10,11 @@ declare function softmaxTop(logits: ArrayLike<number>): {
|
|
|
10
10
|
index: number;
|
|
11
11
|
confidence: number;
|
|
12
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Releases the loaded ONNX session. Call it before the process exits on purpose (tests): ONNX
|
|
15
|
+
* Runtime's threads abort the process ("mutex lock failed") if they are still alive at exit.
|
|
16
|
+
*/
|
|
17
|
+
export declare function releaseAmdModel(): Promise<void>;
|
|
13
18
|
/**
|
|
14
19
|
* Classify a buffer of raw slin16 PCM (16 kHz mono) as human / voicemail / IVR /
|
|
15
20
|
* machine. Loads and caches the ONNX session on first call. Throws on model or
|
package/dist/amd/AmdModel.js
CHANGED
|
@@ -43,6 +43,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
43
43
|
};
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
45
|
exports.DEFAULT_MODEL_DIR = void 0;
|
|
46
|
+
exports.releaseAmdModel = releaseAmdModel;
|
|
46
47
|
exports.classifyPcm = classifyPcm;
|
|
47
48
|
exports.mapLabelToStatus = mapLabelToStatus;
|
|
48
49
|
exports.softmaxTop = softmaxTop;
|
|
@@ -114,6 +115,24 @@ function softmaxTop(logits) {
|
|
|
114
115
|
return { index, confidence: sum > 0 ? exps[index] / sum : 0 };
|
|
115
116
|
}
|
|
116
117
|
let loaded = null;
|
|
118
|
+
/**
|
|
119
|
+
* Releases the loaded ONNX session. Call it before the process exits on purpose (tests): ONNX
|
|
120
|
+
* Runtime's threads abort the process ("mutex lock failed") if they are still alive at exit.
|
|
121
|
+
*/
|
|
122
|
+
function releaseAmdModel() {
|
|
123
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
124
|
+
const entry = loaded;
|
|
125
|
+
loaded = null;
|
|
126
|
+
if (!entry)
|
|
127
|
+
return;
|
|
128
|
+
try {
|
|
129
|
+
yield (yield entry.session).release();
|
|
130
|
+
}
|
|
131
|
+
catch (_a) {
|
|
132
|
+
// never loaded, nothing to release
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
117
136
|
function load(modelDir) {
|
|
118
137
|
var _a;
|
|
119
138
|
if (loaded && loaded.dir === modelDir)
|
package/dist/envs.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.MODEL_PATH = exports.MIN_CONFIDENCE = exports.TIMEOUT_MS = exports.PROBE_MS = exports.AUDIOSOCKET_ADVERTISE_HOST = exports.AUDIOSOCKET_BIND_ADDR = exports.AUDIOSOCKET_PORT = exports.AGI_PORT = void 0;
|
|
7
4
|
/**
|
|
@@ -22,11 +19,9 @@ exports.MODEL_PATH = exports.MIN_CONFIDENCE = exports.TIMEOUT_MS = exports.PROBE
|
|
|
22
19
|
* See the License for the specific language governing permissions and
|
|
23
20
|
* limitations under the License.
|
|
24
21
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
dotenv_1.default.config({ path: (0, path_1.join)(__dirname, "..", "..", "..", ".env") });
|
|
29
|
-
}
|
|
22
|
+
// The sidecar's settings come from its container environment (AMD_*), which
|
|
23
|
+
// the deployment sets. It never loads a .env file, not even in development
|
|
24
|
+
// (fix-config-and-placement-gaps).
|
|
30
25
|
const e = process.env;
|
|
31
26
|
// A malformed AMD_* number must not silently break the probe (NaN
|
|
32
27
|
// thresholds disable the deadline / confidence gate), so fall back to the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fonoster/amd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "Standalone answering-machine-detection sidecar for the Fonoster platform",
|
|
5
5
|
"author": "Pedro Sanders <psanders@fonoster.com>",
|
|
6
6
|
"homepage": "https://github.com/fonoster/fonoster#readme",
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
"start:dev": "nodemon --exec tsx --watch src src/server.ts"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@fonoster/common": "^0.
|
|
23
|
-
"@fonoster/logger": "^0.
|
|
24
|
-
"@fonoster/streams": "^0.
|
|
25
|
-
"@fonoster/types": "^0.
|
|
22
|
+
"@fonoster/common": "^0.30.0",
|
|
23
|
+
"@fonoster/logger": "^0.30.0",
|
|
24
|
+
"@fonoster/streams": "^0.30.0",
|
|
25
|
+
"@fonoster/types": "^0.30.0",
|
|
26
26
|
"onnxruntime-node": "1.21.1",
|
|
27
27
|
"uuid": "^11.0.3"
|
|
28
28
|
},
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"bugs": {
|
|
44
44
|
"url": "https://github.com/fonoster/fonoster/issues"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "b59b06a3ef325abe3f188c0fb87cc22d50ed5471"
|
|
47
47
|
}
|