server.ts 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. import "whatwg-fetch";
  2. import { fetchEventSource } from '@microsoft/fetch-event-source';
  3. import * as PROTOCOL from "../protocol";
  4. import { v4 as uuidv4 } from 'uuid';
  5. import { getHost, errorHandler, get, post, filePost, put, del } from "./requests";
  6. import { WebsocketClient } from "./websocket";
  7. const SERVER_VERSION = process.env.NEXT_PUBLIC_SERVER_VERSION;
  8. const BASE_PATH = "/adh"
  9. // =========================== ASR APIs ===========================
  10. const ASR_PATH = BASE_PATH + `/asr/${SERVER_VERSION}`
  11. export async function api_asr_get_list(): Promise<PROTOCOL.EngineDesc[]>{
  12. const path = `${ASR_PATH}/engine`;
  13. return get(path, null).then((response: PROTOCOL.EngineListResponse) => {
  14. return response.data
  15. }).catch(() => {
  16. return [] as PROTOCOL.EngineDesc[]
  17. })
  18. }
  19. export async function api_asr_get_default(): Promise<PROTOCOL.EngineDesc>{
  20. const path = `${ASR_PATH}/engine/default`;
  21. return get(path, null).then((response: PROTOCOL.EngineDefaultResponse) => {
  22. return response.data
  23. }).catch(() => {
  24. return {} as PROTOCOL.EngineDesc
  25. })
  26. }
  27. export async function api_asr_get_config(engine: string): Promise<PROTOCOL.EngineParamDesc[]>{
  28. const path = `${ASR_PATH}/engine/${engine}`;
  29. return get(path, null).then((response: PROTOCOL.EngineConfigResponse) => {
  30. return response.data;
  31. }).catch(() => {
  32. return [] as PROTOCOL.EngineParamDesc[];
  33. })
  34. }
  35. export async function api_asr_infer(
  36. engine: string,
  37. config: {},
  38. data: string | Blob,
  39. type: string = PROTOCOL.AUDIO_TYPE.WAV as string,
  40. sampleRate: Number = 16000,
  41. sampleWidth: Number = 2
  42. ): Promise<string> {
  43. const path = `${ASR_PATH}/engine`;
  44. const body = JSON.stringify({
  45. engine: engine,
  46. config: config,
  47. data: data,
  48. type: type,
  49. sampleRate: sampleRate,
  50. sampleWidth: sampleWidth
  51. });
  52. return post(path, body, null).then((response: PROTOCOL.StringResponse) => {
  53. return response.data;
  54. }).catch(() => {
  55. return "";
  56. })
  57. }
  58. export async function api_asr_infer_file(
  59. engine: string,
  60. config: {},
  61. data: Blob,
  62. type: string = PROTOCOL.AUDIO_TYPE.MP3 as string,
  63. sampleRate: Number = 16000,
  64. sampleWidth: Number = 2
  65. ): Promise<string> {
  66. const path = `${ASR_PATH}/engine/file`;
  67. const formData = new FormData();
  68. const mp3File = new File([data], 'file.mp3', { type: 'audio/mp3' })
  69. formData.append('file', mp3File)
  70. formData.append('engine', engine);
  71. formData.append('config', JSON.stringify(config));
  72. formData.append('type', type);
  73. formData.append('sampleRate', String(sampleRate));
  74. formData.append('sampleWidth', String(sampleWidth));
  75. return filePost(path, formData, null).then((response: PROTOCOL.StringResponse) => {
  76. return response.data;
  77. }).catch(() => {
  78. return "";
  79. })
  80. }
  81. // =========================== TTS APIs ===========================
  82. const TTS_PATH = BASE_PATH + `/tts/${SERVER_VERSION}`
  83. export async function api_tts_get_list(): Promise<PROTOCOL.EngineDesc[]>{
  84. const path = `${TTS_PATH}/engine`;
  85. return get(path, null).then((response: PROTOCOL.EngineListResponse) => {
  86. return response.data
  87. }).catch(() => {
  88. return [] as PROTOCOL.EngineDesc[]
  89. })
  90. }
  91. export async function api_tts_get_voice(
  92. engine: string,
  93. config: {}
  94. ): Promise<PROTOCOL.VoiceDesc[]>{
  95. const path = `${TTS_PATH}/engine/${engine}/voice?config=${encodeURIComponent(JSON.stringify(config))}`;
  96. return get(path, null).then((response: PROTOCOL.VoiceListResponse) => {
  97. return response.data
  98. }).catch(() => {
  99. return [] as PROTOCOL.VoiceDesc[]
  100. })
  101. }
  102. export async function api_tts_get_default(): Promise<PROTOCOL.EngineDesc>{
  103. const path = `${TTS_PATH}/engine/default`;
  104. return get(path, null).then((response: PROTOCOL.EngineDefaultResponse) => {
  105. return response.data
  106. }).catch(() => {
  107. return {} as PROTOCOL.EngineDesc
  108. })
  109. }
  110. export async function api_tts_get_config(
  111. engine: string,
  112. ): Promise<PROTOCOL.EngineParamDesc[]>{
  113. const path = `${TTS_PATH}/engine/${engine}`;
  114. return get(path, null).then((response: PROTOCOL.EngineConfigResponse) => {
  115. return response.data;
  116. }).catch(() => {
  117. return [] as PROTOCOL.EngineParamDesc[];
  118. })
  119. }
  120. export async function api_tts_infer(
  121. engine: string,
  122. config: {},
  123. data: string,
  124. signal: AbortSignal,
  125. ): Promise<string> {
  126. const path = `${TTS_PATH}/engine`;
  127. const body = JSON.stringify({
  128. engine: engine,
  129. config: config,
  130. data: data,
  131. });
  132. return post(path, body, signal).then((response: PROTOCOL.BaseResponse) => {
  133. return response.data;
  134. }).catch(() => {
  135. return "";
  136. })
  137. }
  138. // =========================== Agent APIs ===========================
  139. const AGENT_PATH = BASE_PATH + `/agent/${SERVER_VERSION}`
  140. export async function api_agent_get_list(): Promise<PROTOCOL.EngineDesc[]> {
  141. const path = `${AGENT_PATH}/engine`;
  142. return get(path, null).then((response: PROTOCOL.EngineListResponse) => {
  143. return response.data
  144. }).catch(() => {
  145. return [] as PROTOCOL.EngineDesc[]
  146. })
  147. }
  148. export async function api_agent_get_default(): Promise<PROTOCOL.EngineDesc> {
  149. const path = `${AGENT_PATH}/engine/default`;
  150. return get(path, null).then((response: PROTOCOL.EngineDefaultResponse) => {
  151. return response.data
  152. }).catch(() => {
  153. return {} as PROTOCOL.EngineDesc
  154. })
  155. }
  156. export async function api_agent_get_config(
  157. engine: string
  158. ): Promise<PROTOCOL.EngineParamDesc[]> {
  159. const path = `${AGENT_PATH}/engine/${engine}`;
  160. return get(path, null).then((response: PROTOCOL.EngineConfigResponse) => {
  161. return response.data;
  162. }).catch(() => {
  163. return [] as PROTOCOL.EngineParamDesc[];
  164. })
  165. }
  166. export async function api_agent_create_conversation(
  167. engine: string,
  168. config: {},
  169. ): Promise<string>{
  170. const path = `${AGENT_PATH}/engine/${engine}`;
  171. const body = JSON.stringify({
  172. engine: engine,
  173. data: config,
  174. });
  175. return post(path, body, null).then((response: PROTOCOL.StringResponse) => {
  176. return response.data;
  177. }).catch(() => {
  178. return "";
  179. })
  180. }
  181. export function api_agent_stream(
  182. engine: string,
  183. config: {},
  184. data: string,
  185. conversation_id: string,
  186. signal: AbortSignal,
  187. onOk: (response: PROTOCOL.EventResponse) => void,
  188. onError: (error: Error) => void = (error) => {}
  189. ){
  190. const path = `${AGENT_PATH}/engine`
  191. const url = getHost() + path;
  192. fetchEventSource(url, {
  193. method: "POST",
  194. headers: {
  195. 'Content-Type': 'application/json',
  196. 'Request-Id': uuidv4(),
  197. 'User-Id': "",
  198. },
  199. body: JSON.stringify({
  200. engine: engine,
  201. config: config,
  202. data: data,
  203. conversation_id: conversation_id
  204. }),
  205. signal: signal,
  206. onmessage: (msg) => {
  207. const { event, data } = msg;
  208. const eventResp : PROTOCOL.EventResponse = {
  209. event: event as PROTOCOL.STREAMING_EVENT_TYPE,
  210. data: data
  211. }
  212. onOk(eventResp)
  213. },
  214. onerror(error) {
  215. throw new Error(error)
  216. },
  217. }).catch((error) => {
  218. errorHandler(error, signal)
  219. })
  220. }
  221. // =========================== Custom APIs ===========================
  222. export async function api_get_engine_list(
  223. engineType: string
  224. ){
  225. switch (engineType){
  226. case PROTOCOL.ENGINE_TYPE.ASR:
  227. return api_asr_get_list();
  228. case PROTOCOL.ENGINE_TYPE.TTS:
  229. return api_tts_get_list();
  230. case PROTOCOL.ENGINE_TYPE.AGENT:
  231. return api_agent_get_list();
  232. }
  233. }
  234. export async function api_get_engine_default(
  235. engineType: string
  236. ){
  237. switch (engineType){
  238. case PROTOCOL.ENGINE_TYPE.ASR:
  239. return api_asr_get_default();
  240. case PROTOCOL.ENGINE_TYPE.TTS:
  241. return api_tts_get_default();
  242. case PROTOCOL.ENGINE_TYPE.AGENT:
  243. return api_agent_get_default();
  244. }
  245. }
  246. export function api_get_engine_config(
  247. engineType: string,
  248. engine: string
  249. ){
  250. switch (engineType){
  251. case PROTOCOL.ENGINE_TYPE.ASR:
  252. return api_asr_get_config(engine);
  253. case PROTOCOL.ENGINE_TYPE.TTS:
  254. return api_tts_get_config(engine);
  255. case PROTOCOL.ENGINE_TYPE.AGENT:
  256. return api_agent_get_config(engine);
  257. }
  258. }
  259. // =========================== Face Detection APIs ===========================
  260. const FACE_DETECTION_PATH = BASE_PATH + `/face_detection/v0`
  261. export interface FaceDetectionResponse {
  262. hasFace: boolean;
  263. faceCount: number;
  264. faces: Array<{
  265. bbox: {
  266. x1: number;
  267. y1: number;
  268. x2: number;
  269. y2: number;
  270. };
  271. confidence: number;
  272. landmarks: Array<[number, number]>;
  273. }>;
  274. }
  275. export async function api_face_detection(imageBlob: Blob): Promise<FaceDetectionResponse> {
  276. const path = `${FACE_DETECTION_PATH}/detect`;
  277. const formData = new FormData();
  278. const imageFile = new File([imageBlob], 'image.jpg', { type: 'image/jpeg' });
  279. formData.append('file', imageFile);
  280. return filePost(path, formData, null).then((response: any) => {
  281. return response.data as FaceDetectionResponse;
  282. }).catch(() => {
  283. return { hasFace: false, faceCount: 0, faces: [] } as FaceDetectionResponse;
  284. });
  285. }
  286. export async function api_face_detection_base64(imageData: string): Promise<FaceDetectionResponse> {
  287. const path = `${FACE_DETECTION_PATH}/detect/base64`;
  288. const formData = new FormData();
  289. formData.append('image_data', imageData);
  290. return filePost(path, formData, null).then((response: any) => {
  291. return response.data as FaceDetectionResponse;
  292. }).catch(() => {
  293. return { hasFace: false, faceCount: 0, faces: [] } as FaceDetectionResponse;
  294. });
  295. }