WitResultUtilities.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /*
  2. * Copyright (c) Meta Platforms, Inc. and affiliates.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the license found in the
  6. * LICENSE file in the root directory of this source tree.
  7. */
  8. using Meta.WitAi.Data.Entities;
  9. using Meta.WitAi.Data.Intents;
  10. using Meta.WitAi.Json;
  11. using UnityEngine;
  12. namespace Meta.WitAi
  13. {
  14. public static class WitResultUtilities
  15. {
  16. // Keys
  17. public const string WIT_KEY_TRANSCRIPTION = "text";
  18. public const string WIT_KEY_INTENTS = "intents";
  19. public const string WIT_KEY_ENTITIES = "entities";
  20. public const string WIT_KEY_TRAITS = "traits";
  21. public const string WIT_KEY_FINAL = "is_final";
  22. #region Base Response methods
  23. /// <summary>
  24. /// Get the transcription from a wit response node
  25. /// </summary>
  26. public static string GetTranscription(this WitResponseNode witResponse) =>
  27. null != witResponse
  28. && witResponse.AsObject != null
  29. && witResponse.AsObject.HasChild(WIT_KEY_TRANSCRIPTION)
  30. ? witResponse[WIT_KEY_TRANSCRIPTION].Value
  31. : string.Empty;
  32. /// <summary>
  33. /// Get whether this response is a 'final' response
  34. /// </summary>
  35. public static bool HasResponse(this WitResponseNode witResponse) =>
  36. null != witResponse
  37. && witResponse.AsObject != null
  38. && (witResponse.AsObject.HasChild(WIT_KEY_INTENTS)
  39. || witResponse.AsObject.HasChild(WIT_KEY_ENTITIES)
  40. || witResponse.AsObject.HasChild(WIT_KEY_TRAITS));
  41. /// <summary>
  42. /// Get whether this response is a 'final' response
  43. /// </summary>
  44. public static bool GetIsFinal(this WitResponseNode witResponse) =>
  45. null != witResponse
  46. && witResponse.AsObject != null
  47. && witResponse.AsObject.HasChild(WIT_KEY_FINAL)
  48. && witResponse[WIT_KEY_FINAL].AsBool;
  49. #endregion
  50. #region Entity methods
  51. /// <summary>
  52. /// Converts wit response node into a wit entity
  53. /// </summary>
  54. public static WitEntityData AsWitEntity(this WitResponseNode witResponse) => new WitEntityData(witResponse);
  55. /// <summary>
  56. /// Converts wit response node into a float entity
  57. /// </summary>
  58. public static WitEntityFloatData AsWitFloatEntity(this WitResponseNode witResponse) => new WitEntityFloatData(witResponse);
  59. /// <summary>
  60. /// Converts wit response node into an int entity
  61. /// </summary>
  62. public static WitEntityIntData AsWitIntEntity(this WitResponseNode witResponse) => new WitEntityIntData(witResponse);
  63. /// <summary>
  64. /// Gets the string value of the first entity
  65. /// </summary>
  66. /// <param name="witResponse"></param>
  67. /// <param name="name"></param>
  68. /// <returns></returns>
  69. public static string GetFirstEntityValue(this WitResponseNode witResponse, string name)
  70. {
  71. return witResponse?[WIT_KEY_ENTITIES]?[name]?[0]?["value"]?.Value;
  72. }
  73. /// <summary>
  74. /// Gets a collection of string value containing the selected value from
  75. /// each entity in the response.
  76. /// </summary>
  77. /// <param name="witResponse"></param>
  78. /// <param name="name"></param>
  79. /// <returns></returns>
  80. public static string[] GetAllEntityValues(this WitResponseNode witResponse, string name)
  81. {
  82. var values = new string[witResponse?[WIT_KEY_ENTITIES]?[name]?.Count ?? 0];
  83. for (var i = 0; i < witResponse?[WIT_KEY_ENTITIES]?[name]?.Count; i++)
  84. {
  85. values[i] = witResponse?[WIT_KEY_ENTITIES]?[name]?[i]?["value"]?.Value;
  86. }
  87. return values;
  88. }
  89. /// <summary>
  90. /// Gets the first entity as a WitResponseNode
  91. /// </summary>
  92. /// <param name="witResponse"></param>
  93. /// <param name="name"></param>
  94. /// <returns></returns>
  95. public static WitResponseNode GetFirstEntity(this WitResponseNode witResponse, string name)
  96. {
  97. return witResponse?[WIT_KEY_ENTITIES]?[name][0];
  98. }
  99. /// <summary>
  100. /// Gets the first entity with the given name as string data
  101. /// </summary>
  102. /// <param name="witResponse"></param>
  103. /// <param name="name">The entity name typically something like name:name</param>
  104. /// <returns></returns>
  105. public static WitEntityData GetFirstWitEntity(this WitResponseNode witResponse, string name)
  106. {
  107. var array = witResponse?[WIT_KEY_ENTITIES]?[name].AsArray;
  108. return array?.Count > 0 ? array[0].AsWitEntity() : null;
  109. }
  110. /// <summary>
  111. /// Gets The first entity with the given name as int data
  112. /// </summary>
  113. /// <param name="witResponse"></param>
  114. /// <param name="name">The entity name typically something like name:name</param>
  115. /// <returns></returns>
  116. public static WitEntityIntData GetFirstWitIntEntity(this WitResponseNode witResponse,
  117. string name)
  118. {
  119. var array = witResponse?[WIT_KEY_ENTITIES]?[name].AsArray;
  120. return array?.Count > 0 ? array[0].AsWitIntEntity() : null;
  121. }
  122. /// <summary>
  123. /// Gets The first entity with the given name as int data
  124. /// </summary>
  125. /// <param name="witResponse"></param>
  126. /// <param name="name">The entity name typically something like name:name</param>
  127. /// <returns></returns>
  128. public static int GetFirstWitIntValue(this WitResponseNode witResponse,
  129. string name, int defaultValue)
  130. {
  131. var array = witResponse?[WIT_KEY_ENTITIES]?[name].AsArray;
  132. if (null == array || array.Count == 0) return defaultValue;
  133. return array[0].AsWitIntEntity().value;
  134. }
  135. /// <summary>
  136. /// Gets the first entity with the given name as float data
  137. /// </summary>
  138. /// <param name="witResponse"></param>
  139. /// <param name="name">The entity name typically something like name:name</param>
  140. /// <returns></returns>
  141. public static WitEntityFloatData GetFirstWitFloatEntity(this WitResponseNode witResponse, string name)
  142. {
  143. var array = witResponse?[WIT_KEY_ENTITIES]?[name].AsArray;
  144. return array?.Count > 0 ? array[0].AsWitFloatEntity() : null;
  145. }
  146. /// <summary>
  147. /// Gets The first entity with the given name as int data
  148. /// </summary>
  149. /// <param name="witResponse"></param>
  150. /// <param name="name">The entity name typically something like name:name</param>
  151. /// <returns></returns>
  152. public static float GetFirstWitFloatValue(this WitResponseNode witResponse,
  153. string name, float defaultValue)
  154. {
  155. var array = witResponse?[WIT_KEY_ENTITIES]?[name].AsArray;
  156. if (null == array || array.Count == 0) return defaultValue;
  157. return array[0].AsWitFloatEntity().value;
  158. }
  159. /// <summary>
  160. /// Gets all entities in the given response
  161. /// </summary>
  162. /// <param name="witResponse">The root response node of an VoiceService.events.OnResponse event</param>
  163. /// <returns></returns>
  164. public static WitEntityData[] GetEntities(this WitResponseNode witResponse, string name)
  165. {
  166. var entityJsonArray = witResponse?[WIT_KEY_ENTITIES]?[name].AsArray;
  167. var entities = new WitEntityData[entityJsonArray?.Count ?? 0];
  168. for (int i = 0; i < entities.Length; i++)
  169. {
  170. entities[i] = entityJsonArray[i].AsWitEntity();
  171. }
  172. return entities;
  173. }
  174. /// <summary>
  175. /// Returns the total number of entities
  176. /// </summary>
  177. /// <param name="response"></param>
  178. /// <returns></returns>
  179. public static int EntityCount(this WitResponseNode response)
  180. {
  181. return response?[WIT_KEY_ENTITIES]?.AsArray?.Count ?? 0;
  182. }
  183. /// <summary>
  184. /// Gets all float entity values in the given response with the specified entity name
  185. /// </summary>
  186. /// <param name="witResponse">The root response node of an VoiceService.events.OnResponse event</param>
  187. /// <param name="name">The entity name typically something like name:name</param>
  188. /// <returns></returns>
  189. public static WitEntityFloatData[] GetFloatEntities(this WitResponseNode witResponse, string name)
  190. {
  191. var entityJsonArray = witResponse?[WIT_KEY_ENTITIES]?[name].AsArray;
  192. var entities = new WitEntityFloatData[entityJsonArray?.Count ?? 0];
  193. for (int i = 0; i < entities.Length; i++)
  194. {
  195. entities[i] = entityJsonArray[i].AsWitFloatEntity();
  196. }
  197. return entities;
  198. }
  199. /// <summary>
  200. /// Gets all int entity values in the given response with the specified entity name
  201. /// </summary>
  202. /// <param name="witResponse">The root response node of an VoiceService.events.OnResponse event</param>
  203. /// <param name="name">The entity name typically something like name:name</param>
  204. /// <returns></returns>
  205. public static WitEntityIntData[] GetIntEntities(this WitResponseNode witResponse, string name)
  206. {
  207. var entityJsonArray = witResponse?[WIT_KEY_ENTITIES]?[name].AsArray;
  208. var entities = new WitEntityIntData[entityJsonArray?.Count ?? 0];
  209. for (int i = 0; i < entities.Length; i++)
  210. {
  211. entities[i] = entityJsonArray[i].AsWitIntEntity();
  212. }
  213. return entities;
  214. }
  215. #endregion
  216. #region Intent methods
  217. /// <summary>
  218. /// Converts wit response node into wit intent data
  219. /// </summary>
  220. public static WitIntentData AsWitIntent(this WitResponseNode witResponse) => new WitIntentData(witResponse);
  221. /// <summary>
  222. /// Gets the first intent's name
  223. /// </summary>
  224. /// <param name="witResponse"></param>
  225. /// <returns></returns>
  226. public static string GetIntentName(this WitResponseNode witResponse)
  227. {
  228. return witResponse == null || !witResponse.AsObject.HasChild(WIT_KEY_INTENTS) ? null : witResponse[WIT_KEY_INTENTS][0]?["name"]?.Value;
  229. }
  230. /// <summary>
  231. /// Gets the first intent node
  232. /// </summary>
  233. /// <param name="witResponse"></param>
  234. /// <returns></returns>
  235. public static WitResponseNode GetFirstIntent(this WitResponseNode witResponse)
  236. {
  237. return witResponse == null || !witResponse.AsObject.HasChild(WIT_KEY_INTENTS) ? null : witResponse[WIT_KEY_INTENTS][0];
  238. }
  239. /// <summary>
  240. /// Gets the first set of intent data
  241. /// </summary>
  242. /// <param name="witResponse"></param>
  243. /// <returns>WitIntentData or null if no intents are found</returns>
  244. public static WitIntentData GetFirstIntentData(this WitResponseNode witResponse)
  245. {
  246. var array = witResponse == null || !witResponse.AsObject.HasChild(WIT_KEY_INTENTS) ? null : witResponse[WIT_KEY_INTENTS]?.AsArray;
  247. return array?.Count > 0 ? array[0].AsWitIntent() : null;
  248. }
  249. /// <summary>
  250. /// Gets all intents in the given response
  251. /// </summary>
  252. /// <param name="witResponse">The root response node of an VoiceService.events.OnResponse event</param>
  253. /// <returns></returns>
  254. public static WitIntentData[] GetIntents(this WitResponseNode witResponse)
  255. {
  256. var intentResponseArray = witResponse == null || !witResponse.AsObject.HasChild(WIT_KEY_INTENTS) ? null : witResponse[WIT_KEY_INTENTS]?.AsArray;
  257. var intents = new WitIntentData[intentResponseArray?.Count ?? 0];
  258. for (int i = 0; i < intents.Length; i++)
  259. {
  260. intents[i] = intentResponseArray[i].AsWitIntent();
  261. }
  262. return intents;
  263. }
  264. #endregion
  265. #region Misc. Helper Methods
  266. public static string GetPathValue(this WitResponseNode response, string path)
  267. {
  268. string[] nodes = path.Trim('.').Split('.');
  269. var node = response;
  270. foreach (var nodeName in nodes)
  271. {
  272. string[] arrayElements = SplitArrays(nodeName);
  273. node = node[arrayElements[0]];
  274. for (int i = 1; i < arrayElements.Length; i++)
  275. {
  276. node = node[int.Parse(arrayElements[i])];
  277. }
  278. }
  279. return node.Value;
  280. }
  281. public static void SetString(this WitResponseNode response, string path, string value)
  282. {
  283. string[] nodes = path.Trim('.').Split('.');
  284. var node = response;
  285. int nodeIndex;
  286. for(nodeIndex = 0; nodeIndex < nodes.Length - 1; nodeIndex++)
  287. {
  288. var nodeName = nodes[nodeIndex];
  289. string[] arrayElements = SplitArrays(nodeName);
  290. node = node[arrayElements[0]];
  291. for (int i = 1; i < arrayElements.Length; i++)
  292. {
  293. node = node[int.Parse(arrayElements[i])];
  294. }
  295. }
  296. node[nodes[nodeIndex]] = value;
  297. }
  298. public static void RemovePath(this WitResponseNode response, string path)
  299. {
  300. string[] nodes = path.Trim('.').Split('.');
  301. var node = response;
  302. WitResponseNode parent = null;
  303. foreach (var nodeName in nodes)
  304. {
  305. string[] arrayElements = SplitArrays(nodeName);
  306. parent = node;
  307. node = node[arrayElements[0]];
  308. for (int i = 1; i < arrayElements.Length; i++)
  309. {
  310. node = node[int.Parse(arrayElements[i])];
  311. }
  312. }
  313. if (null != parent) parent.Remove(node);
  314. }
  315. public static WitResponseReference GetWitResponseReference(string path)
  316. {
  317. string[] nodes = path.Trim('.').Split('.');
  318. var rootNode = new WitResponseReference()
  319. {
  320. path = path
  321. };
  322. var node = rootNode;
  323. foreach (var nodeName in nodes)
  324. {
  325. string[] arrayElements = SplitArrays(nodeName);
  326. var childObject = new ObjectNodeReference()
  327. {
  328. path = path
  329. };
  330. childObject.key = arrayElements[0];
  331. node.child = childObject;
  332. node = childObject;
  333. for (int i = 1; i < arrayElements.Length; i++)
  334. {
  335. var childIndex = new ArrayNodeReference()
  336. {
  337. path = path
  338. };
  339. childIndex.index = int.Parse(arrayElements[i]);
  340. node.child = childIndex;
  341. node = childIndex;
  342. }
  343. }
  344. return rootNode;
  345. }
  346. public static string GetCodeFromPath(string path)
  347. {
  348. string[] nodes = path.Trim('.').Split('.');
  349. string code = "witResponse";
  350. foreach (var nodeName in nodes)
  351. {
  352. string[] arrayElements = SplitArrays(nodeName);
  353. code += $"[\"{arrayElements[0]}\"]";
  354. for (int i = 1; i < arrayElements.Length; i++)
  355. {
  356. code += $"[{arrayElements[i]}]";
  357. }
  358. }
  359. code += ".Value";
  360. return code;
  361. }
  362. private static string[] SplitArrays(string nodeName)
  363. {
  364. var nodes = nodeName.Split('[');
  365. for (int i = 0; i < nodes.Length; i++)
  366. {
  367. nodes[i] = nodes[i].Trim(']');
  368. }
  369. return nodes;
  370. }
  371. #endregion
  372. #region Trait Methods
  373. /// <summary>
  374. /// Gets the string value of the first trait
  375. /// </summary>
  376. /// <param name="witResponse"></param>
  377. /// <param name="name"></param>
  378. /// <returns></returns>
  379. public static string GetTraitValue(this WitResponseNode witResponse, string name)
  380. {
  381. return witResponse?[WIT_KEY_TRAITS]?[name]?[0]?["value"]?.Value;
  382. }
  383. #endregion
  384. }
  385. #region WitResponseReference Child Classes
  386. public class WitResponseReference
  387. {
  388. public WitResponseReference child;
  389. public string path;
  390. public virtual string GetStringValue(WitResponseNode response)
  391. {
  392. return child.GetStringValue(response);
  393. }
  394. public virtual int GetIntValue(WitResponseNode response)
  395. {
  396. return child.GetIntValue(response);
  397. }
  398. public virtual float GetFloatValue(WitResponseNode response)
  399. {
  400. return child.GetFloatValue(response);
  401. }
  402. }
  403. public class ArrayNodeReference : WitResponseReference
  404. {
  405. public int index;
  406. public override string GetStringValue(WitResponseNode response)
  407. {
  408. if (null != child)
  409. {
  410. return child.GetStringValue(response[index]);
  411. }
  412. return response[index].Value;
  413. }
  414. public override int GetIntValue(WitResponseNode response)
  415. {
  416. if (null != child)
  417. {
  418. return child.GetIntValue(response[index]);
  419. }
  420. return response[index].AsInt;
  421. }
  422. public override float GetFloatValue(WitResponseNode response)
  423. {
  424. if (null != child)
  425. {
  426. return child.GetFloatValue(response[index]);
  427. }
  428. return response[index].AsInt;
  429. }
  430. }
  431. public class ObjectNodeReference : WitResponseReference
  432. {
  433. public string key;
  434. public override string GetStringValue(WitResponseNode response)
  435. {
  436. if (null != child && null != response?[key])
  437. {
  438. return child.GetStringValue(response[key]);
  439. }
  440. return response?[key]?.Value;
  441. }
  442. public override int GetIntValue(WitResponseNode response)
  443. {
  444. if (null != child)
  445. {
  446. return child.GetIntValue(response[key]);
  447. }
  448. return response[key].AsInt;
  449. }
  450. public override float GetFloatValue(WitResponseNode response)
  451. {
  452. if (null != child)
  453. {
  454. return child.GetFloatValue(response[key]);
  455. }
  456. return response[key].AsFloat;
  457. }
  458. }
  459. #endregion
  460. }