mirror of
https://github.com/jambonz/jambonz-webapp.git
synced 2025-12-19 05:37:43 +00:00
Compare commits
16 Commits
v0.9.5-rc5
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c33eb46ce0 | ||
|
|
f003c158dc | ||
|
|
b1ddaf230d | ||
|
|
0260b1ec8b | ||
|
|
1c1f97f045 | ||
|
|
e6c5a18c87 | ||
|
|
19742ab67e | ||
|
|
53d0c0b510 | ||
|
|
7a0eb71bae | ||
|
|
6aae8d9930 | ||
|
|
a70a1bf614 | ||
|
|
975a787f1e | ||
|
|
46e220f28b | ||
|
|
6836a99635 | ||
|
|
f7f4a2e7b1 | ||
|
|
f1f8a7d808 |
2
.env
2
.env
@@ -1,4 +1,4 @@
|
||||
#VITE_API_BASE_URL=http://127.0.0.1:3000/v1
|
||||
# VITE_API_BASE_URL=http://127.0.0.1:3000/v1
|
||||
#VITE_DEV_BASE_URL=http://127.0.0.1:3000/v1
|
||||
|
||||
## enables choosing units and lisenced account call limits
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:18.15-alpine3.16 as builder
|
||||
FROM node:20-alpine AS builder
|
||||
RUN apk update && apk add --no-cache python3 make g++
|
||||
COPY . /opt/app
|
||||
WORKDIR /opt/app/
|
||||
@@ -6,7 +6,7 @@ RUN npm install
|
||||
RUN npm run build
|
||||
RUN npm prune
|
||||
|
||||
FROM node:18.14.1-alpine as webapp
|
||||
FROM node:20-alpine AS webapp
|
||||
RUN apk add curl
|
||||
WORKDIR /opt/app
|
||||
COPY . /opt/app
|
||||
|
||||
86
package-lock.json
generated
86
package-lock.json
generated
@@ -46,13 +46,13 @@
|
||||
"nanoid": "^5.1.5",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "^1.89.2",
|
||||
"serve": "^14.2.4",
|
||||
"serve": "^14.2.5",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.4",
|
||||
"vite": "^6.0.1"
|
||||
"vite": "^6.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.18"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@aashutoshrathi/word-wrap": {
|
||||
@@ -2196,19 +2196,6 @@
|
||||
"integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.34",
|
||||
"negotiator": "0.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.11.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||
@@ -3265,6 +3252,7 @@
|
||||
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
|
||||
"integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": ">= 1.43.0 < 2"
|
||||
},
|
||||
@@ -3273,37 +3261,30 @@
|
||||
}
|
||||
},
|
||||
"node_modules/compression": {
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
|
||||
"integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz",
|
||||
"integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.5",
|
||||
"bytes": "3.0.0",
|
||||
"compressible": "~2.0.16",
|
||||
"bytes": "3.1.2",
|
||||
"compressible": "~2.0.18",
|
||||
"debug": "2.6.9",
|
||||
"on-headers": "~1.0.2",
|
||||
"safe-buffer": "5.1.2",
|
||||
"negotiator": "~0.6.4",
|
||||
"on-headers": "~1.1.0",
|
||||
"safe-buffer": "5.2.1",
|
||||
"vary": "~1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/compression/node_modules/bytes": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
||||
"integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/compression/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
@@ -3312,13 +3293,8 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/compression/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
@@ -6911,10 +6887,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
|
||||
"integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -7071,10 +7048,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/on-headers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
|
||||
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
|
||||
"integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
@@ -8047,10 +8025,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/serve": {
|
||||
"version": "14.2.4",
|
||||
"resolved": "https://registry.npmjs.org/serve/-/serve-14.2.4.tgz",
|
||||
"integrity": "sha512-qy1S34PJ/fcY8gjVGszDB3EXiPSk5FKhUa7tQe0UPRddxRidc2V6cNHPNewbE1D7MAkgLuWEt3Vw56vYy73tzQ==",
|
||||
"version": "14.2.5",
|
||||
"resolved": "https://registry.npmjs.org/serve/-/serve-14.2.5.tgz",
|
||||
"integrity": "sha512-Qn/qMkzCcMFVPb60E/hQy+iRLpiU8PamOfOSYoAHmmF+fFFmpPpqa6Oci2iWYpTdOUM3VF+TINud7CfbQnsZbA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@zeit/schemas": "2.36.0",
|
||||
"ajv": "8.12.0",
|
||||
@@ -8059,7 +8038,7 @@
|
||||
"chalk": "5.0.1",
|
||||
"chalk-template": "0.4.0",
|
||||
"clipboardy": "3.0.0",
|
||||
"compression": "1.7.4",
|
||||
"compression": "1.8.1",
|
||||
"is-port-reachable": "4.0.0",
|
||||
"serve-handler": "6.1.6",
|
||||
"update-check": "1.5.4"
|
||||
@@ -9104,10 +9083,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.3.5",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
|
||||
"integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
|
||||
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.4.4",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=14.18"
|
||||
"node": ">=18"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
@@ -77,10 +77,10 @@
|
||||
"nanoid": "^5.1.5",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "^1.89.2",
|
||||
"serve": "^14.2.4",
|
||||
"serve": "^14.2.5",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.4",
|
||||
"vite": "^6.0.1"
|
||||
"vite": "^6.4.1"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx}": "eslint --max-warnings=0",
|
||||
|
||||
@@ -131,7 +131,7 @@ export const DEFAULT_WEBHOOK: WebHook = {
|
||||
};
|
||||
|
||||
/** Default SIP/SMPP Gateways */
|
||||
export const DEFAULT_SIP_GATEWAY: SipGateway = {
|
||||
export const DEFAULT_SIP_INBOUND_GATEWAY: SipGateway = {
|
||||
voip_carrier_sid: "",
|
||||
ipv4: "",
|
||||
port: 5060,
|
||||
@@ -348,6 +348,12 @@ export const DTMF_TYPE_SELECTION: SelectorOptions[] = [
|
||||
{ name: "Tones", value: "tones" },
|
||||
];
|
||||
|
||||
export const TRUNK_TYPE_SELECTION: SelectorOptions[] = [
|
||||
{ name: "IP Trunk", value: "static_ip" },
|
||||
{ name: "Auth Trunk", value: "auth" },
|
||||
{ name: "Registration Trunk", value: "reg" },
|
||||
];
|
||||
|
||||
/** Available webhook methods */
|
||||
export const WEBHOOK_METHODS: WebhookOption[] = [
|
||||
{
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import type { Language, Model, Vendor, VoiceLanguage } from "src/vendor/types";
|
||||
import type {
|
||||
JambonzResourceOptions,
|
||||
Language,
|
||||
Model,
|
||||
Vendor,
|
||||
VoiceLanguage,
|
||||
} from "src/vendor/types";
|
||||
|
||||
/** Simple types */
|
||||
|
||||
@@ -413,6 +419,7 @@ export interface SpeechCredential {
|
||||
custom_stt_endpoint: null | string;
|
||||
client_id: null | string;
|
||||
client_secret: null | string;
|
||||
client_key: null | string;
|
||||
secret: null | string;
|
||||
nuance_tts_uri: null | string;
|
||||
nuance_stt_uri: null | string;
|
||||
@@ -440,6 +447,10 @@ export interface SpeechCredential {
|
||||
deepgram_stt_use_tls: number;
|
||||
speechmatics_stt_uri: null | string;
|
||||
playht_tts_uri: null | string;
|
||||
resemble_tts_uri: null | string;
|
||||
resemble_tts_use_tls: number;
|
||||
api_uri: null | string;
|
||||
houndify_server_uri: null | string;
|
||||
}
|
||||
|
||||
export interface Alert {
|
||||
@@ -459,6 +470,8 @@ export interface CarrierRegisterStatus {
|
||||
|
||||
export type DtmfType = "rfc2833" | "tones" | "info";
|
||||
|
||||
export type TrunkType = "static_ip" | "auth" | "reg";
|
||||
|
||||
export interface Carrier {
|
||||
voip_carrier_sid: string;
|
||||
name: string;
|
||||
@@ -487,6 +500,7 @@ export interface Carrier {
|
||||
register_status: CarrierRegisterStatus;
|
||||
dtmf_type: DtmfType;
|
||||
outbound_sip_proxy: string | null;
|
||||
trunk_type: TrunkType;
|
||||
}
|
||||
|
||||
export interface PredefinedCarrier extends Carrier {
|
||||
@@ -823,6 +837,8 @@ export interface AppEnvProperty {
|
||||
obscure?: boolean;
|
||||
uiHint?: "input" | "textarea" | "filepicker";
|
||||
enum?: string[];
|
||||
jambonzResource?: "carriers";
|
||||
jambonzResourceOptions?: JambonzResourceOptions[];
|
||||
}
|
||||
|
||||
export interface AppEnv {
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
useServiceProviderData,
|
||||
useApiData,
|
||||
getAppEnvSchema,
|
||||
getSPVoipCarriers,
|
||||
} from "src/api";
|
||||
import {
|
||||
ROUTE_INTERNAL_ACCOUNTS,
|
||||
@@ -588,6 +589,51 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
setFallbackSpeechRecognizerLabel(tmp);
|
||||
};
|
||||
|
||||
const fetchAppEnvJambonzResources = async (appEnv: AppEnv) => {
|
||||
if (appEnv) {
|
||||
const promises = Object.entries(appEnv).map(async ([key, value]) => {
|
||||
const { jambonzResource } = value;
|
||||
switch (jambonzResource) {
|
||||
case "carriers":
|
||||
const carriers = await getSPVoipCarriers(
|
||||
currentServiceProvider?.service_provider_sid || "",
|
||||
{
|
||||
page: 1,
|
||||
page_size: 10000,
|
||||
...(user?.account_sid && {
|
||||
account_sid: user.account_sid,
|
||||
}),
|
||||
},
|
||||
);
|
||||
if (carriers.json.total) {
|
||||
return {
|
||||
key,
|
||||
jambonzResourceOptions: carriers.json.data.map((carrier) => ({
|
||||
name: carrier.name,
|
||||
value: carrier.name,
|
||||
})),
|
||||
};
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return { key, jambonzResourceOptions: null };
|
||||
});
|
||||
|
||||
const results = await Promise.all(promises);
|
||||
|
||||
// Merge the results back into appEnv
|
||||
results.forEach(({ key, jambonzResourceOptions }) => {
|
||||
if (jambonzResourceOptions) {
|
||||
appEnv[key].jambonzResourceOptions = jambonzResourceOptions;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return appEnv;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (callWebhook && callWebhook.url) {
|
||||
// Clear any existing timeout to prevent multiple requests
|
||||
@@ -599,19 +645,26 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
appEnvTimeoutRef.current = setTimeout(() => {
|
||||
getAppEnvSchema(callWebhook.url)
|
||||
.then(({ json }) => {
|
||||
setAppEnv(json);
|
||||
const defaultEnvVars = Object.keys(json).reduce((acc, key) => {
|
||||
const value = json[key];
|
||||
if (value?.default) {
|
||||
return { ...acc, [key]: value.default };
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
// fetch app env jambonz_resource
|
||||
fetchAppEnvJambonzResources(json).then((updatedEnv) => {
|
||||
setAppEnv(updatedEnv);
|
||||
const defaultEnvVars = Object.keys(updatedEnv).reduce(
|
||||
(acc, key) => {
|
||||
const value = updatedEnv[key];
|
||||
if (value?.default) {
|
||||
return { ...acc, [key]: value.default };
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
setEnvVars((prev) => ({
|
||||
...defaultEnvVars,
|
||||
...(prev || {}),
|
||||
}));
|
||||
setEnvVars((prev) => ({
|
||||
...defaultEnvVars,
|
||||
...(prev || {}),
|
||||
}));
|
||||
});
|
||||
// Default value
|
||||
})
|
||||
.catch((error) => {
|
||||
setMessage(error.msg);
|
||||
@@ -873,9 +926,13 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
};
|
||||
|
||||
const isDropdown =
|
||||
webhook.webhookEnv![key].type === "string" &&
|
||||
(webhook.webhookEnv![key].enum?.length || 0) >
|
||||
0;
|
||||
(webhook.webhookEnv![key].type === "string" &&
|
||||
(webhook.webhookEnv![key].enum?.length ||
|
||||
0) > 0) ||
|
||||
hasLength(
|
||||
webhook.webhookEnv![key]
|
||||
.jambonzResourceOptions,
|
||||
);
|
||||
|
||||
const textAreaSpecificProps = {
|
||||
rows: 6,
|
||||
@@ -888,15 +945,19 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
? ObscureInput
|
||||
: webhook.webhookEnv![key].uiHint || "input";
|
||||
if (isDropdown) {
|
||||
const options =
|
||||
webhook.webhookEnv![key]
|
||||
.jambonzResourceOptions ||
|
||||
webhook.webhookEnv![key].enum!.map(
|
||||
(option) => ({
|
||||
name: option,
|
||||
value: option,
|
||||
}),
|
||||
);
|
||||
return (
|
||||
<Selector
|
||||
{...commonProps}
|
||||
options={webhook.webhookEnv![
|
||||
key
|
||||
].enum!.map((option) => ({
|
||||
name: option,
|
||||
value: option,
|
||||
}))}
|
||||
options={options}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,9 @@ import {
|
||||
VENDOR_RIMELABS,
|
||||
VENDOR_OPENAI,
|
||||
VENDOR_INWORLD,
|
||||
VENDOR_DEEPGRAM_RIVER,
|
||||
VENDOR_DEEPGRAM_FLUX,
|
||||
VENDOR_RESEMBLE,
|
||||
VENDOR_HOUNDIFY,
|
||||
} from "src/vendor";
|
||||
import {
|
||||
LabelOptions,
|
||||
@@ -369,7 +371,7 @@ export const SpeechProviderSelection = ({
|
||||
};
|
||||
|
||||
const configRecognizer = () => {
|
||||
if (recogVendor === VENDOR_DEEPGRAM_RIVER) {
|
||||
if (recogVendor === VENDOR_DEEPGRAM_FLUX) {
|
||||
return;
|
||||
}
|
||||
getSpeechSupportedLanguagesAndVoices(
|
||||
@@ -432,7 +434,8 @@ export const SpeechProviderSelection = ({
|
||||
vendor.value !== VENDOR_SPEECHMATICS &&
|
||||
vendor.value !== VENDOR_CUSTOM &&
|
||||
vendor.value !== VENDOR_OPENAI &&
|
||||
vendor.value !== VENDOR_DEEPGRAM_RIVER &&
|
||||
vendor.value !== VENDOR_DEEPGRAM_FLUX &&
|
||||
vendor.value !== VENDOR_HOUNDIFY &&
|
||||
vendor.value !== VENDOR_COBALT,
|
||||
)}
|
||||
onChange={(e) => {
|
||||
@@ -587,6 +590,7 @@ export const SpeechProviderSelection = ({
|
||||
vendor.value != VENDOR_WELLSAID &&
|
||||
vendor.value != VENDOR_ELEVENLABS &&
|
||||
vendor.value != VENDOR_WHISPER &&
|
||||
vendor.value !== VENDOR_RESEMBLE &&
|
||||
vendor.value !== VENDOR_CUSTOM,
|
||||
)}
|
||||
onChange={(e) => {
|
||||
@@ -614,7 +618,7 @@ export const SpeechProviderSelection = ({
|
||||
)}
|
||||
{recogVendor &&
|
||||
!recogVendor.toString().startsWith(VENDOR_CUSTOM) &&
|
||||
recogVendor !== VENDOR_DEEPGRAM_RIVER &&
|
||||
recogVendor !== VENDOR_DEEPGRAM_FLUX &&
|
||||
recogLang && (
|
||||
<>
|
||||
<label htmlFor="recognizer_lang">Language</label>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { P } from "@jambonz/ui-kit";
|
||||
import { Modal, ModalClose } from "src/components";
|
||||
import { getFetch, getLcrRoutes, getLcrs } from "src/api";
|
||||
import { API_PHONE_NUMBERS } from "src/api/constants";
|
||||
import { formatPhoneNumber, hasLength } from "src/utils";
|
||||
import { formatPhoneNumber, hasLength, hasValue } from "src/utils";
|
||||
|
||||
import type { Carrier, Lcr, PhoneNumber } from "src/api/types";
|
||||
|
||||
@@ -63,7 +63,8 @@ export const DeleteCarrier = ({
|
||||
),
|
||||
);
|
||||
|
||||
setLcrs(fetchedLcrs);
|
||||
// Only set LCRs if they are not empty
|
||||
setLcrs(fetchedLcrs.filter((p) => hasValue(p)));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -67,9 +67,6 @@ export const LcrForm = ({ lcrDataMap, lcrRouteDataMap }: LcrFormProps) => {
|
||||
const [accountSid, setAccountSid] = useState("");
|
||||
const [isActive, setIsActive] = useState(true);
|
||||
const [lcrRoutes, setLcrRoutes] = useState<LcrRoute[]>([LCR_ROUTE_TEMPLATE]);
|
||||
const [previousLcrRoutes, setPreviousLcrRoutes] = useState<LcrRoute[]>([
|
||||
LCR_ROUTE_TEMPLATE,
|
||||
]);
|
||||
const [previouseLcr, setPreviousLcr] = useState<Lcr | null>();
|
||||
const [accounts] = useServiceProviderData<Account[]>("Accounts");
|
||||
const [lcrForDelete, setLcrForDelete] = useState<Lcr | null>();
|
||||
@@ -127,38 +124,35 @@ export const LcrForm = ({ lcrDataMap, lcrRouteDataMap }: LcrFormProps) => {
|
||||
}, [lcrDataMap?.data, previouseLcr]);
|
||||
|
||||
useMemo(() => {
|
||||
let default_lcr_route_sid = "";
|
||||
if (
|
||||
lcrRouteDataMap &&
|
||||
lcrRouteDataMap.data &&
|
||||
lcrRouteDataMap.data !== previousLcrRoutes
|
||||
) {
|
||||
setPreviousLcrRoutes(lcrRouteDataMap.data);
|
||||
// Find default carrier
|
||||
lcrRouteDataMap.data.forEach((lr) => {
|
||||
lr.lcr_carrier_set_entries?.forEach((entry) => {
|
||||
if (
|
||||
entry.lcr_carrier_set_entry_sid ===
|
||||
lcrDataMap?.data?.default_carrier_set_entry_sid
|
||||
) {
|
||||
// Only process when both lcrDataMap and lcrRouteDataMap are available
|
||||
if (lcrRouteDataMap && lcrRouteDataMap.data && lcrDataMap?.data) {
|
||||
const defaultCarrierSetEntrySid =
|
||||
lcrDataMap.data.default_carrier_set_entry_sid;
|
||||
|
||||
// Find and store default route information
|
||||
lcrRouteDataMap.data.forEach((route) => {
|
||||
route.lcr_carrier_set_entries?.forEach((entry) => {
|
||||
if (entry.lcr_carrier_set_entry_sid === defaultCarrierSetEntrySid) {
|
||||
setDefaultLcrCarrier(entry.voip_carrier_sid || defaultCarrier);
|
||||
setDefaultLcrCarrierSetEntrySid(
|
||||
entry.lcr_carrier_set_entry_sid || null,
|
||||
);
|
||||
default_lcr_route_sid = entry.lcr_route_sid || "";
|
||||
setDefaultLcrRoute(lr);
|
||||
setDefaultLcrRoute(route);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (lcrRouteDataMap && lcrRouteDataMap.data)
|
||||
setLcrRoutes(
|
||||
lcrRouteDataMap.data.filter(
|
||||
(route) => route.lcr_route_sid !== default_lcr_route_sid,
|
||||
),
|
||||
);
|
||||
}, [lcrRouteDataMap?.data]);
|
||||
// Filter out routes that contain the default carrier set entry
|
||||
const filteredRoutes = lcrRouteDataMap.data.filter((route) => {
|
||||
return !route.lcr_carrier_set_entries?.some(
|
||||
(entry) =>
|
||||
entry.lcr_carrier_set_entry_sid === defaultCarrierSetEntrySid,
|
||||
);
|
||||
});
|
||||
|
||||
setLcrRoutes(filteredRoutes);
|
||||
}
|
||||
}, [lcrRouteDataMap?.data, lcrDataMap?.data]);
|
||||
|
||||
const addLcrRoutes = () => {
|
||||
const newLcrRoute = LCR_ROUTE_TEMPLATE;
|
||||
|
||||
@@ -53,7 +53,10 @@ import {
|
||||
VENDOR_VOXIST,
|
||||
VENDOR_OPENAI,
|
||||
VENDOR_INWORLD,
|
||||
VENDOR_DEEPGRAM_RIVER,
|
||||
VENDOR_DEEPGRAM_FLUX,
|
||||
VENDOR_RESEMBLE,
|
||||
VENDOR_HOUNDIFY,
|
||||
VENDOR_GLADIA,
|
||||
} from "src/vendor";
|
||||
import { MSG_REQUIRED_FIELDS } from "src/constants";
|
||||
import {
|
||||
@@ -107,6 +110,13 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
const { toastError, toastSuccess } = useToast();
|
||||
const navigate = useNavigate();
|
||||
const user = useSelectState("user");
|
||||
|
||||
// ElevenLabs API URI options
|
||||
const ELEVENLABS_API_URI_OPTIONS = [
|
||||
{ name: "US", value: "api.elevenlabs.io" },
|
||||
{ name: "EU", value: "api.eu.residency.elevenlabs.io" },
|
||||
{ name: "IN", value: "api.in.residency.elevenlabs.io" },
|
||||
];
|
||||
const currentServiceProvider = useSelectState("currentServiceProvider");
|
||||
const regions = useRegionVendors();
|
||||
const [accounts] = useServiceProviderData<Account[]>("Accounts");
|
||||
@@ -120,11 +130,13 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
);
|
||||
const [region, setRegion] = useState("");
|
||||
const [apiKey, setApiKey] = useState("");
|
||||
const [apiUri, setApiUri] = useState("api.elevenlabs.io");
|
||||
const [userId, setUserId] = useState("");
|
||||
const [accessKeyId, setAccessKeyId] = useState("");
|
||||
const [secretAccessKey, setSecretAccessKey] = useState("");
|
||||
const [clientId, setClientId] = useState("");
|
||||
const [secretKey, setSecretKey] = useState("");
|
||||
const [clientKey, setClientKey] = useState("");
|
||||
const [clientSecret, setClientSecret] = useState("");
|
||||
const [googleServiceKey, setGoogleServiceKey] =
|
||||
useState<GoogleServiceKey | null>(null);
|
||||
@@ -207,6 +219,13 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
const [tmpPlayhtTtsUri, setTmpPlayhtTtsUri] = useState("");
|
||||
const [initialPlayhtOnpremCheck, setInitialPlayhtOnpremCheck] =
|
||||
useState(false);
|
||||
const [resembleTtsUri, setResembleTtsUri] = useState("");
|
||||
const [tmpResembleTtsUri, setTmpResembleTtsUri] = useState("");
|
||||
const [initialResembleOnpremCheck, setInitialResembleOnpremCheck] =
|
||||
useState(false);
|
||||
const [resembleTtsUseTls, setResembleTtsUseTls] = useState(false);
|
||||
const [tmpResembleTtsUseTls, setTmpResembleTtsUseTls] = useState(false);
|
||||
const [houndifyServerUri, setHoundifyServerUri] = useState("");
|
||||
const handleFile = (file: File) => {
|
||||
const handleError = () => {
|
||||
setGoogleServiceKey(null);
|
||||
@@ -440,6 +459,12 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
nuance_tts_uri: onPremNuanceTtsUrl || null,
|
||||
nuance_stt_uri: onPremNuanceSttUrl || null,
|
||||
}),
|
||||
...(vendor === VENDOR_HOUNDIFY && {
|
||||
client_id: clientId || null,
|
||||
client_key: clientKey || null,
|
||||
user_id: userId || null,
|
||||
houndify_server_uri: houndifyServerUri || null,
|
||||
}),
|
||||
...(vendor === VENDOR_COBALT && {
|
||||
cobalt_server_uri: cobaltServerUri || null,
|
||||
}),
|
||||
@@ -449,6 +474,9 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
vendor === VENDOR_RIMELABS) && {
|
||||
model_id: ttsModelId || null,
|
||||
}),
|
||||
...(vendor === VENDOR_ELEVENLABS && {
|
||||
api_uri: apiUri || null,
|
||||
}),
|
||||
...((vendor === VENDOR_ELEVENLABS ||
|
||||
vendor === VENDOR_PLAYHT ||
|
||||
vendor === VENDOR_INWORLD ||
|
||||
@@ -481,6 +509,14 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
...(vendor === VENDOR_PLAYHT && {
|
||||
playht_tts_uri: playhtTtsUri || null,
|
||||
}),
|
||||
...(vendor === VENDOR_RESEMBLE && {
|
||||
resemble_tts_uri: resembleTtsUri || null,
|
||||
resemble_tts_use_tls: resembleTtsUseTls ? 1 : 0,
|
||||
}),
|
||||
...(vendor === VENDOR_GLADIA && {
|
||||
api_key: apiKey || null,
|
||||
region: region || null,
|
||||
}),
|
||||
};
|
||||
|
||||
if (credential && credential.data) {
|
||||
@@ -531,7 +567,9 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
vendor === VENDOR_WHISPER ||
|
||||
vendor === VENDOR_CARTESIA ||
|
||||
vendor === VENDOR_OPENAI ||
|
||||
vendor === VENDOR_DEEPGRAM_RIVER
|
||||
vendor === VENDOR_RESEMBLE ||
|
||||
vendor === VENDOR_DEEPGRAM_FLUX ||
|
||||
vendor === VENDOR_GLADIA
|
||||
? apiKey
|
||||
: null,
|
||||
}),
|
||||
@@ -685,6 +723,10 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
setApiKey(credential.data.api_key);
|
||||
}
|
||||
|
||||
if (credential.data.api_uri) {
|
||||
setApiUri(credential.data.api_uri);
|
||||
}
|
||||
|
||||
if (credential.data.region) {
|
||||
setRegion(credential.data.region);
|
||||
}
|
||||
@@ -696,6 +738,9 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
if (credential.data.client_id) {
|
||||
setClientId(credential.data.client_id);
|
||||
}
|
||||
if (credential.data.client_key) {
|
||||
setClientKey(credential.data.client_key);
|
||||
}
|
||||
|
||||
if (credential.data.secret) {
|
||||
setSecretKey(credential.data.secret);
|
||||
@@ -798,6 +843,9 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
if (credential?.data?.playht_tts_uri) {
|
||||
setPlayhtTtsUri(credential.data.playht_tts_uri);
|
||||
}
|
||||
if (credential?.data?.resemble_tts_uri) {
|
||||
setResembleTtsUri(credential.data.resemble_tts_uri);
|
||||
}
|
||||
}
|
||||
if (credential?.data?.options) {
|
||||
setOptions(credential.data.options);
|
||||
@@ -832,6 +880,10 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
setUserId(credential.data.user_id);
|
||||
}
|
||||
|
||||
if (credential?.data?.houndify_server_uri) {
|
||||
setHoundifyServerUri(credential.data.houndify_server_uri);
|
||||
}
|
||||
|
||||
if (credential?.data?.voice_engine) {
|
||||
setTtsModelId(credential.data.voice_engine);
|
||||
}
|
||||
@@ -867,6 +919,15 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
setSpeechmaticsEndpoint(credential.data.speechmatics_stt_uri);
|
||||
}
|
||||
setInitialPlayhtOnpremCheck(hasValue(credential?.data?.playht_tts_uri));
|
||||
setInitialResembleOnpremCheck(hasValue(credential?.data?.resemble_tts_uri));
|
||||
if (credential?.data?.resemble_tts_use_tls) {
|
||||
setResembleTtsUseTls(
|
||||
credential?.data?.resemble_tts_use_tls > 0 ? true : false,
|
||||
);
|
||||
setTmpResembleTtsUseTls(
|
||||
credential?.data?.resemble_tts_use_tls > 0 ? true : false,
|
||||
);
|
||||
}
|
||||
}, [credential]);
|
||||
|
||||
const updateCustomVoices = (
|
||||
@@ -930,6 +991,9 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
setVendor(e.target.value as Lowercase<Vendor>);
|
||||
setRegion("");
|
||||
setApiKey("");
|
||||
setApiUri(
|
||||
e.target.value === VENDOR_ELEVENLABS ? "api.elevenlabs.io" : "",
|
||||
);
|
||||
setGoogleServiceKey(null);
|
||||
}}
|
||||
disabled={credential ? true : false}
|
||||
@@ -985,8 +1049,10 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
vendor !== VENDOR_COBALT &&
|
||||
vendor !== VENDOR_SONIOX &&
|
||||
vendor !== VENDOR_SPEECHMATICS &&
|
||||
vendor !== VENDOR_DEEPGRAM_RIVER &&
|
||||
vendor !== VENDOR_DEEPGRAM_FLUX &&
|
||||
vendor !== VENDOR_HOUNDIFY &&
|
||||
vendor !== VENDOR_OPENAI &&
|
||||
vendor !== VENDOR_GLADIA &&
|
||||
vendor != VENDOR_CUSTOM && (
|
||||
<label htmlFor="use_for_tts" className="chk">
|
||||
<input
|
||||
@@ -1005,6 +1071,7 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
vendor !== VENDOR_PLAYHT &&
|
||||
vendor !== VENDOR_RIMELABS &&
|
||||
vendor !== VENDOR_INWORLD &&
|
||||
vendor !== VENDOR_RESEMBLE &&
|
||||
vendor !== VENDOR_ELEVENLABS && (
|
||||
<label htmlFor="use_for_stt" className="chk">
|
||||
<input
|
||||
@@ -1384,6 +1451,56 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{vendor === VENDOR_HOUNDIFY && (
|
||||
<fieldset>
|
||||
<label htmlFor="houndify_client_id">
|
||||
Client ID
|
||||
{!onPremNuanceSttCheck && !onPremNuanceTtsCheck && <span>*</span>}
|
||||
</label>
|
||||
<input
|
||||
id="houndify_client_id"
|
||||
required={!onPremNuanceSttCheck && !onPremNuanceTtsCheck}
|
||||
type="text"
|
||||
name="houndify_client_id"
|
||||
placeholder="Client ID"
|
||||
value={clientId}
|
||||
onChange={(e) => setClientId(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
<label htmlFor="houndify_secret">
|
||||
Client Key
|
||||
{!onPremNuanceSttCheck && !onPremNuanceTtsCheck && <span>*</span>}
|
||||
</label>
|
||||
<Passwd
|
||||
id="houndify_secret"
|
||||
required={!onPremNuanceSttCheck && !onPremNuanceTtsCheck}
|
||||
name="houndify_secret"
|
||||
placeholder="Client Key"
|
||||
value={clientKey ? getObscuredSecret(clientKey) : clientKey}
|
||||
onChange={(e) => setClientKey(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
<label htmlFor="houndify_user_id">User ID</label>
|
||||
<input
|
||||
id="houndify_user_id"
|
||||
type="text"
|
||||
name="houndify_user_id"
|
||||
placeholder="User ID"
|
||||
value={userId}
|
||||
onChange={(e) => setUserId(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
<label htmlFor="houndify_server_uri">Audio Endpoint</label>
|
||||
<input
|
||||
id="houndify_server_uri"
|
||||
type="text"
|
||||
name="houndify_server_uri"
|
||||
placeholder="Audio Endpoint (optional)"
|
||||
value={houndifyServerUri}
|
||||
onChange={(e) => setHoundifyServerUri(e.target.value)}
|
||||
/>
|
||||
</fieldset>
|
||||
)}
|
||||
{vendor === VENDOR_NUANCE && (
|
||||
<>
|
||||
<fieldset>
|
||||
@@ -1744,18 +1861,98 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
</fieldset>
|
||||
)}
|
||||
|
||||
{vendor === VENDOR_RESEMBLE && (
|
||||
<fieldset>
|
||||
<Checkzone
|
||||
disabled={hasValue(credential)}
|
||||
hidden
|
||||
name="use_on-prem_resemble_container"
|
||||
label="Use on-prem Resemble container"
|
||||
initialCheck={initialResembleOnpremCheck}
|
||||
handleChecked={(e) => {
|
||||
setInitialResembleOnpremCheck(e.target.checked);
|
||||
if (e.target.checked) {
|
||||
if (tmpResembleTtsUri) {
|
||||
setResembleTtsUri(tmpResembleTtsUri);
|
||||
}
|
||||
if (tmpResembleTtsUseTls) {
|
||||
setResembleTtsUseTls(tmpResembleTtsUseTls);
|
||||
}
|
||||
} else {
|
||||
setTmpResembleTtsUri(resembleTtsUri);
|
||||
setResembleTtsUri("");
|
||||
setTmpResembleTtsUseTls(resembleTtsUseTls);
|
||||
setResembleTtsUseTls(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<label htmlFor="resemble_uri_for_tts">
|
||||
TTS Container URI<span>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="resemble_uri_for_tts"
|
||||
required
|
||||
type="text"
|
||||
name="resemble_uri_for_tts"
|
||||
placeholder=""
|
||||
value={resembleTtsUri}
|
||||
onChange={(e) => setResembleTtsUri(e.target.value)}
|
||||
/>
|
||||
<label htmlFor="resemble_stt_use_tls" className="chk">
|
||||
<input
|
||||
id="resemble_stt_use_tls"
|
||||
name="resemble_stt_use_tls"
|
||||
type="checkbox"
|
||||
onChange={(e) => setResembleTtsUseTls(e.target.checked)}
|
||||
defaultChecked={resembleTtsUseTls}
|
||||
/>
|
||||
<div>Use TLS</div>
|
||||
</label>
|
||||
</Checkzone>
|
||||
</fieldset>
|
||||
)}
|
||||
|
||||
{vendor === VENDOR_ELEVENLABS && (
|
||||
<fieldset>
|
||||
<label htmlFor="elevenlabs_api_uri">
|
||||
Data residency<span>*</span>
|
||||
</label>
|
||||
<Selector
|
||||
id="elevenlabs_api_uri"
|
||||
name="elevenlabs_api_uri"
|
||||
value={apiUri}
|
||||
options={ELEVENLABS_API_URI_OPTIONS}
|
||||
onChange={(e) => setApiUri(e.target.value)}
|
||||
required
|
||||
/>
|
||||
<label htmlFor={`${vendor}_apikey`}>
|
||||
API key<span>*</span>
|
||||
</label>
|
||||
<Passwd
|
||||
id={`${vendor}_apikey`}
|
||||
required
|
||||
name={`${vendor}_apikey`}
|
||||
placeholder="API key"
|
||||
value={apiKey ? getObscuredSecret(apiKey) : apiKey}
|
||||
onChange={(e) => setApiKey(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
</fieldset>
|
||||
)}
|
||||
|
||||
{(vendor === VENDOR_WELLSAID ||
|
||||
vendor === VENDOR_ASSEMBLYAI ||
|
||||
vendor === VENDOR_VOXIST ||
|
||||
vendor == VENDOR_ELEVENLABS ||
|
||||
vendor === VENDOR_WHISPER ||
|
||||
vendor === VENDOR_RIMELABS ||
|
||||
vendor === VENDOR_INWORLD ||
|
||||
vendor === VENDOR_SONIOX ||
|
||||
vendor === VENDOR_CARTESIA ||
|
||||
vendor === VENDOR_OPENAI ||
|
||||
vendor === VENDOR_DEEPGRAM_RIVER ||
|
||||
vendor === VENDOR_SPEECHMATICS) && (
|
||||
vendor === VENDOR_DEEPGRAM_FLUX ||
|
||||
vendor === VENDOR_RESEMBLE ||
|
||||
vendor === VENDOR_SPEECHMATICS ||
|
||||
vendor === VENDOR_GLADIA) && (
|
||||
<fieldset>
|
||||
<label htmlFor={`${vendor}_apikey`}>
|
||||
API key<span>*</span>
|
||||
|
||||
@@ -218,7 +218,8 @@ fieldset {
|
||||
}
|
||||
}
|
||||
|
||||
.gateway {
|
||||
.gateway,
|
||||
.gateway-inbound {
|
||||
padding: ui-vars.$px02;
|
||||
border-radius: ui-vars.$px01;
|
||||
border: 2px solid ui-vars.$grey;
|
||||
@@ -284,6 +285,18 @@ fieldset {
|
||||
}
|
||||
}
|
||||
|
||||
.gateway-inbound {
|
||||
> div {
|
||||
&:nth-child(1) {
|
||||
grid-template-columns: [col] calc(70% - #{ui-vars.$px02 * 2}) [col] 30%;
|
||||
|
||||
@include mixins.small() {
|
||||
grid-template-columns: [col] 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lcr {
|
||||
@extend .gateway;
|
||||
|
||||
|
||||
24
src/vendor/index.tsx
vendored
24
src/vendor/index.tsx
vendored
@@ -12,7 +12,7 @@ export const VENDOR_MICROSOFT = "microsoft";
|
||||
export const VENDOR_WELLSAID = "wellsaid";
|
||||
export const VENDOR_NUANCE = "nuance";
|
||||
export const VENDOR_DEEPGRAM = "deepgram";
|
||||
export const VENDOR_DEEPGRAM_RIVER = "deepgramriver";
|
||||
export const VENDOR_DEEPGRAM_FLUX = "deepgramflux";
|
||||
export const VENDOR_IBM = "ibm";
|
||||
export const VENDOR_NVIDIA = "nvidia";
|
||||
export const VENDOR_SONIOX = "soniox";
|
||||
@@ -29,6 +29,9 @@ export const VENDOR_INWORLD = "inworld";
|
||||
export const VENDOR_VERBIO = "verbio";
|
||||
export const VENDOR_CARTESIA = "cartesia";
|
||||
export const VENDOR_OPENAI = "openai";
|
||||
export const VENDOR_RESEMBLE = "resemble";
|
||||
export const VENDOR_HOUNDIFY = "houndify";
|
||||
export const VENDOR_GLADIA = "gladia";
|
||||
|
||||
export const vendors: VendorOptions[] = [
|
||||
{
|
||||
@@ -44,8 +47,8 @@ export const vendors: VendorOptions[] = [
|
||||
value: VENDOR_DEEPGRAM,
|
||||
},
|
||||
{
|
||||
name: "Deepgram River Preview",
|
||||
value: VENDOR_DEEPGRAM_RIVER,
|
||||
name: "Deepgram Flux",
|
||||
value: VENDOR_DEEPGRAM_FLUX,
|
||||
},
|
||||
{
|
||||
name: "IBM",
|
||||
@@ -123,6 +126,18 @@ export const vendors: VendorOptions[] = [
|
||||
name: "OpenAI",
|
||||
value: VENDOR_OPENAI,
|
||||
},
|
||||
{
|
||||
name: "Resemble",
|
||||
value: VENDOR_RESEMBLE,
|
||||
},
|
||||
{
|
||||
name: "SoundHound",
|
||||
value: VENDOR_HOUNDIFY,
|
||||
},
|
||||
{
|
||||
name: "Gladia",
|
||||
value: VENDOR_GLADIA,
|
||||
},
|
||||
].sort((a, b) => a.name.localeCompare(b.name)) as VendorOptions[];
|
||||
|
||||
export const AWS_CREDENTIAL_ACCESS_KEY = "access_key";
|
||||
@@ -155,12 +170,14 @@ export const useRegionVendors = () => {
|
||||
import("./regions/ms-azure-regions"),
|
||||
import("./regions/ibm-regions"),
|
||||
import("./regions/speechmatics-regions"),
|
||||
import("./regions/gladia-regions"),
|
||||
]).then(
|
||||
([
|
||||
{ default: awsRegions },
|
||||
{ default: msRegions },
|
||||
{ default: ibmRegions },
|
||||
{ default: speechmaticsRegions },
|
||||
{ default: gladiaRegions },
|
||||
]) => {
|
||||
if (!ignore) {
|
||||
setRegions({
|
||||
@@ -168,6 +185,7 @@ export const useRegionVendors = () => {
|
||||
microsoft: msRegions,
|
||||
ibm: ibmRegions,
|
||||
speechmatics: speechmaticsRegions,
|
||||
gladia: gladiaRegions,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
14
src/vendor/regions/gladia-regions.ts
vendored
Normal file
14
src/vendor/regions/gladia-regions.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { Region } from "../types";
|
||||
|
||||
export const regions: Region[] = [
|
||||
{
|
||||
name: "US West",
|
||||
value: "us-west",
|
||||
},
|
||||
{
|
||||
name: "EU West",
|
||||
value: "eu-west",
|
||||
},
|
||||
];
|
||||
|
||||
export default regions;
|
||||
15
src/vendor/types.ts
vendored
15
src/vendor/types.ts
vendored
@@ -5,7 +5,7 @@ export type Vendor =
|
||||
| "WellSaid"
|
||||
| "Nuance"
|
||||
| "Deepgram"
|
||||
| "DeepgramRiver"
|
||||
| "DeepgramFlux"
|
||||
| "IBM"
|
||||
| "Nvidia"
|
||||
| "Soniox"
|
||||
@@ -21,7 +21,10 @@ export type Vendor =
|
||||
| "inworld"
|
||||
| "verbio"
|
||||
| "openai"
|
||||
| "Cartesia";
|
||||
| "Cartesia"
|
||||
| "Resemble"
|
||||
| "Houndify"
|
||||
| "gladia";
|
||||
|
||||
export interface VendorOptions {
|
||||
name: Vendor;
|
||||
@@ -33,6 +36,11 @@ export interface LabelOptions {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface JambonzResourceOptions {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface Region {
|
||||
name: string;
|
||||
value: string;
|
||||
@@ -78,6 +86,7 @@ export interface RegionVendors {
|
||||
microsoft: Region[];
|
||||
ibm: Region[];
|
||||
speechmatics: Region[];
|
||||
gladia: Region[];
|
||||
}
|
||||
|
||||
export interface TtsModels {
|
||||
@@ -98,7 +107,7 @@ export interface RecognizerVendors {
|
||||
speechmatics: Language[];
|
||||
cobalt: Language[];
|
||||
assemblyai: Language[];
|
||||
deepgramriver: Language[];
|
||||
deepgramflux: Language[];
|
||||
}
|
||||
|
||||
export interface SynthesisVendors {
|
||||
|
||||
Reference in New Issue
Block a user