mirror of
https://github.com/jambonz/jambonz-webapp.git
synced 2026-02-09 02:29:45 +00:00
Compare commits
5 Commits
v0.9.0-rc7
...
v0.9.1-rc5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c390715d8 | ||
|
|
dcdc2c0808 | ||
|
|
a3c48e7efb | ||
|
|
6b9167e6b8 | ||
|
|
e7889e1ad3 |
4
.env
4
.env
@@ -1,5 +1,5 @@
|
||||
VITE_API_BASE_URL=http://127.0.0.1:3000/v1
|
||||
VITE_DEV_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
|
||||
# VITE_APP_ENABLE_ACCOUNT_LIMITS_ALL=true
|
||||
|
||||
4
LICENSE
4
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Drachtio Communications Services, LLC
|
||||
Copyright (c) 2018-2024 FirstFive8, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { hasValue } from "src/utils";
|
||||
import type {
|
||||
Currency,
|
||||
ElevenLabsOptions,
|
||||
@@ -37,8 +38,11 @@ declare global {
|
||||
}
|
||||
|
||||
/** https://vitejs.dev/guide/env-and-mode.html#env-files */
|
||||
export const API_BASE_URL =
|
||||
const CONFIGURED_API_BASE_URL =
|
||||
window.JAMBONZ?.API_BASE_URL || import.meta.env.VITE_API_BASE_URL;
|
||||
export const API_BASE_URL = hasValue(CONFIGURED_API_BASE_URL)
|
||||
? CONFIGURED_API_BASE_URL
|
||||
: `${window.location.protocol}//${window.location.hostname}/api/v1`;
|
||||
|
||||
/** Serves mock API responses from a local dev API server */
|
||||
export const DEV_BASE_URL = import.meta.env.VITE_DEV_BASE_URL;
|
||||
@@ -205,6 +209,14 @@ export const DEFAULT_ELEVENLABS_MODEL = "eleven_multilingual_v2";
|
||||
|
||||
export const DEFAULT_WHISPER_MODEL = "tts-1";
|
||||
|
||||
// VERBIO
|
||||
export const VERBIO_STT_MODELS = [
|
||||
{ name: "V1", value: "V1" },
|
||||
{ name: "V2", value: "V2" },
|
||||
];
|
||||
|
||||
export const DEFAULT_VERBIO_MODEL = "V1";
|
||||
|
||||
// Google Custom Voice reported usage options
|
||||
|
||||
export const DEFAULT_GOOGLE_CUSTOM_VOICES_REPORTED_USAGE = "REALTIME";
|
||||
|
||||
@@ -390,6 +390,7 @@ export interface SpeechCredential {
|
||||
region: null | string;
|
||||
aws_region: null | string;
|
||||
api_key: null | string;
|
||||
role_arn: null | string;
|
||||
user_id: null | string;
|
||||
access_key_id: null | string;
|
||||
secret_access_key: null | string;
|
||||
@@ -401,6 +402,7 @@ export interface SpeechCredential {
|
||||
custom_stt_endpoint_url: null | string;
|
||||
custom_stt_endpoint: null | string;
|
||||
client_id: null | string;
|
||||
client_secret: null | string;
|
||||
secret: null | string;
|
||||
nuance_tts_uri: null | string;
|
||||
nuance_stt_uri: null | string;
|
||||
@@ -417,6 +419,7 @@ export interface SpeechCredential {
|
||||
cobalt_server_uri: null | string;
|
||||
model_id: null | string;
|
||||
voice_engine: null | string;
|
||||
engine_version: null | string;
|
||||
model: null | string;
|
||||
options: null | string;
|
||||
deepgram_stt_uri: null | string;
|
||||
@@ -486,6 +489,7 @@ export interface SipGateway extends Gateway {
|
||||
port: number | null;
|
||||
pad_crypto?: boolean;
|
||||
send_options_ping?: boolean;
|
||||
use_sips_scheme?: boolean;
|
||||
}
|
||||
|
||||
export interface SmppGateway extends Gateway {
|
||||
|
||||
@@ -1142,6 +1142,30 @@ export const CarrierForm = ({
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
{Boolean(g.outbound) &&
|
||||
(g.protocol === "tls" || g.protocol === "tls/srtp") && (
|
||||
<div>
|
||||
<label
|
||||
htmlFor={`use_sips_scheme_${i}`}
|
||||
className="chk"
|
||||
>
|
||||
<input
|
||||
id={`use_sips_scheme_${i}`}
|
||||
name={`use_sips_scheme_${i}`}
|
||||
type="checkbox"
|
||||
checked={g.use_sips_scheme ? true : false}
|
||||
onChange={(e) => {
|
||||
updateSipGateways(
|
||||
i,
|
||||
"use_sips_scheme",
|
||||
e.target.checked,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<div>Use sips scheme</div>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<button
|
||||
|
||||
@@ -42,6 +42,11 @@ import {
|
||||
VENDOR_WHISPER,
|
||||
VENDOR_PLAYHT,
|
||||
VENDOR_RIMELABS,
|
||||
AWS_CREDENTIAL_TYPES,
|
||||
AWS_CREDENTIAL_IAM_ASSUME_ROLE,
|
||||
AWS_CREDENTIAL_ACCESS_KEY,
|
||||
AWS_INSTANCE_PROFILE,
|
||||
VENDOR_VERBIO,
|
||||
} from "src/vendor";
|
||||
import { MSG_REQUIRED_FIELDS } from "src/constants";
|
||||
import {
|
||||
@@ -73,8 +78,10 @@ import {
|
||||
DEFAULT_GOOGLE_CUSTOM_VOICES_REPORTED_USAGE,
|
||||
DEFAULT_PLAYHT_OPTIONS,
|
||||
DEFAULT_RIMELABS_OPTIONS,
|
||||
DEFAULT_VERBIO_MODEL,
|
||||
DISABLE_CUSTOM_SPEECH,
|
||||
GOOGLE_CUSTOM_VOICES_REPORTED_USAGE,
|
||||
VERBIO_STT_MODELS,
|
||||
} from "src/api/constants";
|
||||
|
||||
type SpeechServiceFormProps = {
|
||||
@@ -102,6 +109,7 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
const [secretAccessKey, setSecretAccessKey] = useState("");
|
||||
const [clientId, setClientId] = useState("");
|
||||
const [secretKey, setSecretKey] = useState("");
|
||||
const [clientSecret, setClientSecret] = useState("");
|
||||
const [googleServiceKey, setGoogleServiceKey] =
|
||||
useState<GoogleServiceKey | null>(null);
|
||||
const [sttRegion, setSttRegion] = useState("");
|
||||
@@ -109,6 +117,7 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
const [ttsRegion, setTtsRegion] = useState("");
|
||||
const [ttsApiKey, setTtsApiKey] = useState("");
|
||||
const [ttsModelId, setTtsModelId] = useState("");
|
||||
const [engineVersion, setEngineVersion] = useState(DEFAULT_VERBIO_MODEL);
|
||||
const [instanceId, setInstanceId] = useState("");
|
||||
const [initialCheckCustomTts, setInitialCheckCustomTts] = useState(false);
|
||||
const [initialCheckCustomStt, setInitialCheckCustomStt] = useState(false);
|
||||
@@ -157,6 +166,10 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
const [initialDeepgramOnpremCheck, setInitialDeepgramOnpremCheck] =
|
||||
useState(false);
|
||||
const [isDeepgramOnpremEnabled, setIsDeepgramOnpremEnabled] = useState(false);
|
||||
const [awsCredentialType, setAwsCredentialType] = useState(
|
||||
AWS_CREDENTIAL_ACCESS_KEY,
|
||||
);
|
||||
const [roleArn, setRoleArn] = useState("");
|
||||
|
||||
const handleFile = (file: File) => {
|
||||
const handleError = () => {
|
||||
@@ -345,6 +358,9 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
deepgram_stt_uri: deepgramSttUri || null,
|
||||
deepgram_stt_use_tls: deepgramSttUseTls ? 1 : 0,
|
||||
}),
|
||||
...(vendor === VENDOR_VERBIO && {
|
||||
engine_version: engineVersion,
|
||||
}),
|
||||
};
|
||||
|
||||
if (credential && credential.data) {
|
||||
@@ -378,6 +394,7 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
vendor === VENDOR_GOOGLE ? JSON.stringify(googleServiceKey) : null,
|
||||
access_key_id: vendor === VENDOR_AWS ? accessKeyId : null,
|
||||
secret_access_key: vendor === VENDOR_AWS ? secretAccessKey : null,
|
||||
role_arn: vendor === VENDOR_AWS ? roleArn : null,
|
||||
...(apiKey && {
|
||||
api_key:
|
||||
vendor === VENDOR_MICROSOFT ||
|
||||
@@ -396,6 +413,10 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
userId && {
|
||||
user_id: userId,
|
||||
}),
|
||||
...(vendor === VENDOR_VERBIO && {
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
}),
|
||||
riva_server_uri: vendor == VENDOR_NVIDIA ? rivaServerUri : null,
|
||||
})
|
||||
.then(({ json }) => {
|
||||
@@ -626,6 +647,27 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
if (credential?.data?.voice_engine) {
|
||||
setTtsModelId(credential.data.voice_engine);
|
||||
}
|
||||
if (credential?.data?.role_arn) {
|
||||
setRoleArn(credential.data.role_arn);
|
||||
}
|
||||
if (credential) {
|
||||
setAwsCredentialType(
|
||||
credential?.data?.access_key_id
|
||||
? AWS_CREDENTIAL_ACCESS_KEY
|
||||
: credential?.data?.role_arn
|
||||
? AWS_CREDENTIAL_IAM_ASSUME_ROLE
|
||||
: AWS_INSTANCE_PROFILE,
|
||||
);
|
||||
}
|
||||
if (credential?.data?.client_id) {
|
||||
setClientId(credential.data.client_id);
|
||||
}
|
||||
if (credential?.data?.client_secret) {
|
||||
setClientSecret(credential.data.client_secret);
|
||||
}
|
||||
if (credential?.data?.engine_version) {
|
||||
setEngineVersion(credential.data.engine_version);
|
||||
}
|
||||
}, [credential]);
|
||||
|
||||
const updateCustomVoices = (
|
||||
@@ -1162,37 +1204,128 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
</fieldset>
|
||||
</>
|
||||
)}
|
||||
{vendor === VENDOR_VERBIO && (
|
||||
<>
|
||||
<fieldset>
|
||||
<label htmlFor="verbio_client_id">
|
||||
Client ID
|
||||
{!onPremNuanceSttCheck && !onPremNuanceTtsCheck && (
|
||||
<span>*</span>
|
||||
)}
|
||||
</label>
|
||||
<input
|
||||
id="verbio_client_id"
|
||||
required
|
||||
type="text"
|
||||
name="verbio_client_id"
|
||||
placeholder="Client ID"
|
||||
value={clientId}
|
||||
onChange={(e) => setClientId(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
<label htmlFor="verbio_client_secret">
|
||||
Client secret
|
||||
{!onPremNuanceSttCheck && !onPremNuanceTtsCheck && (
|
||||
<span>*</span>
|
||||
)}
|
||||
</label>
|
||||
<input
|
||||
id="verbio_client_secret"
|
||||
required
|
||||
type="text"
|
||||
name="verbio_client_secret"
|
||||
placeholder="Client secret"
|
||||
value={clientSecret}
|
||||
onChange={(e) => setClientSecret(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label htmlFor={`${vendor}_tts_model_id`}>
|
||||
Engine version<span>*</span>
|
||||
</label>
|
||||
<Selector
|
||||
id={"verbio_engine_version"}
|
||||
name={"verbio_engine_version"}
|
||||
value={engineVersion}
|
||||
options={VERBIO_STT_MODELS}
|
||||
onChange={(e) => {
|
||||
setEngineVersion(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</fieldset>
|
||||
</>
|
||||
)}
|
||||
{vendor === VENDOR_AWS && (
|
||||
<fieldset>
|
||||
<label htmlFor="aws_access_key">
|
||||
Access key ID<span>*</span>
|
||||
<label htmlFor="vendor">
|
||||
Credential type<span>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="aws_access_key"
|
||||
required
|
||||
type="text"
|
||||
name="aws_access_key"
|
||||
placeholder="Access Key ID"
|
||||
value={accessKeyId}
|
||||
onChange={(e) => setAccessKeyId(e.target.value)}
|
||||
<Selector
|
||||
id="aws_credential_type"
|
||||
name="aws_credential_type"
|
||||
value={awsCredentialType}
|
||||
options={AWS_CREDENTIAL_TYPES}
|
||||
onChange={(e) => {
|
||||
setAccessKeyId("");
|
||||
setSecretAccessKey("");
|
||||
setRoleArn("");
|
||||
setAwsCredentialType(e.target.value);
|
||||
}}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
<label htmlFor="aws_secret_key">
|
||||
Secret access key<span>*</span>
|
||||
</label>
|
||||
<Passwd
|
||||
id="aws_secret_key"
|
||||
required
|
||||
name="aws_secret_key"
|
||||
placeholder="Secret Access Key"
|
||||
value={
|
||||
secretAccessKey
|
||||
? getObscuredSecret(secretAccessKey)
|
||||
: secretAccessKey
|
||||
}
|
||||
onChange={(e) => setSecretAccessKey(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
{awsCredentialType === AWS_CREDENTIAL_ACCESS_KEY ? (
|
||||
<>
|
||||
<label htmlFor="aws_access_key">
|
||||
Access key ID<span>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="aws_access_key"
|
||||
required
|
||||
type="text"
|
||||
name="aws_access_key"
|
||||
placeholder="Access Key ID"
|
||||
value={accessKeyId}
|
||||
onChange={(e) => setAccessKeyId(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
<label htmlFor="aws_secret_key">
|
||||
Secret access key<span>*</span>
|
||||
</label>
|
||||
<Passwd
|
||||
id="aws_secret_key"
|
||||
required
|
||||
name="aws_secret_key"
|
||||
placeholder="Secret Access Key"
|
||||
value={
|
||||
secretAccessKey
|
||||
? getObscuredSecret(secretAccessKey)
|
||||
: secretAccessKey
|
||||
}
|
||||
onChange={(e) => setSecretAccessKey(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
</>
|
||||
) : awsCredentialType === AWS_CREDENTIAL_IAM_ASSUME_ROLE ? (
|
||||
<>
|
||||
<label htmlFor="aws_access_key">
|
||||
RoleArn<span>*</span>
|
||||
</label>
|
||||
<input
|
||||
id="aws_role_arn"
|
||||
required
|
||||
type="text"
|
||||
name="aws_role_arn"
|
||||
placeholder="RoleArn"
|
||||
value={roleArn}
|
||||
onChange={(e) => setRoleArn(e.target.value)}
|
||||
disabled={credential ? true : false}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</fieldset>
|
||||
)}
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ fieldset {
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
margin-top: ui-vars.$px02;
|
||||
|
||||
> div:last-child {
|
||||
|
||||
24
src/vendor/index.tsx
vendored
24
src/vendor/index.tsx
vendored
@@ -22,6 +22,7 @@ export const VENDOR_ASSEMBLYAI = "assemblyai";
|
||||
export const VENDOR_WHISPER = "whisper";
|
||||
export const VENDOR_PLAYHT = "playht";
|
||||
export const VENDOR_RIMELABS = "rimelabs";
|
||||
export const VENDOR_VERBIO = "verbio";
|
||||
|
||||
export const vendors: VendorOptions[] = [
|
||||
{
|
||||
@@ -88,8 +89,31 @@ export const vendors: VendorOptions[] = [
|
||||
name: "RimeLabs",
|
||||
value: VENDOR_RIMELABS,
|
||||
},
|
||||
{
|
||||
name: "Verbio",
|
||||
value: VENDOR_VERBIO,
|
||||
},
|
||||
].sort((a, b) => a.name.localeCompare(b.name)) as VendorOptions[];
|
||||
|
||||
export const AWS_CREDENTIAL_ACCESS_KEY = "access_key";
|
||||
export const AWS_CREDENTIAL_IAM_ASSUME_ROLE = "assume_role";
|
||||
export const AWS_INSTANCE_PROFILE = "instance_profile";
|
||||
|
||||
export const AWS_CREDENTIAL_TYPES = [
|
||||
{
|
||||
name: "AWS access key",
|
||||
value: AWS_CREDENTIAL_ACCESS_KEY,
|
||||
},
|
||||
{
|
||||
name: "AWS assume role",
|
||||
value: AWS_CREDENTIAL_IAM_ASSUME_ROLE,
|
||||
},
|
||||
{
|
||||
name: "AWS instance profile",
|
||||
value: AWS_INSTANCE_PROFILE,
|
||||
},
|
||||
];
|
||||
|
||||
export const useRegionVendors = () => {
|
||||
const [regions, setRegions] = useState<RegionVendors>();
|
||||
|
||||
|
||||
3
src/vendor/types.ts
vendored
3
src/vendor/types.ts
vendored
@@ -14,7 +14,8 @@ export type Vendor =
|
||||
| "assemblyai"
|
||||
| "whisper"
|
||||
| "playht"
|
||||
| "rimelabs";
|
||||
| "rimelabs"
|
||||
| "verbio";
|
||||
|
||||
export interface VendorOptions {
|
||||
name: Vendor;
|
||||
|
||||
Reference in New Issue
Block a user