Initial Commit

This commit is contained in:
2025-07-04 20:33:06 +03:00
commit 8f09347ae0
9219 changed files with 2447903 additions and 0 deletions
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d192dfd6dc3ff0240b7171d81525428b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,14 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
namespace Meta.WitAi.Data.Configuration
{
public interface IApplicationDetailProvider
{
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ed426c1b615d4b44a3c55c12850ce15
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8b74ce5059d44106941f1fcb6419a0e6
timeCreated: 1677872564
@@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using Meta.WitAi;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Data.Configuration.Tabs
{
public class WitConfigurationApplicationTab : WitConfigurationEditorTab
{
public override Type DataType => null;
public override string TabID { get; } = "application";
public override int TabOrder { get; } = 0;
public override string TabLabel { get; } = WitTexts.Texts.ConfigurationApplicationTabLabel;
public override string MissingLabel { get; } = WitTexts.Texts.ConfigurationApplicationMissingLabel;
public override bool ShouldTabShow(WitAppInfo appInfo)
{
return true;
}
public override string GetPropertyName(string tabID)
{
return "_appInfo";
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bebd7edc23f2449f86d2b4c28582465c
timeCreated: 1677872642
@@ -0,0 +1,39 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Text;
using Meta.WitAi.Data.Info;
using UnityEditor;
namespace Meta.WitAi.Data.Configuration.Tabs
{
public abstract class WitConfigurationEditorTab
{
// the WitConfigurationData type relevant to this tab
public abstract Type DataType { get; }
public abstract string TabID { get; }
public abstract int TabOrder { get; }
public abstract string TabLabel { get; }
public abstract string MissingLabel { get; }
public abstract bool ShouldTabShow(WitAppInfo appInfo);
public virtual bool ShouldTabShow(WitConfiguration configuration) { return false; }
public virtual string GetPropertyName(string tabID)
{
StringBuilder sb = new StringBuilder();
sb.Append("_appInfo");
sb.Append($".{TabID}");
return sb.ToString();
}
public virtual string GetTabText(bool titleLabel)
{
return titleLabel ? TabLabel : MissingLabel;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6dedb23257484140becc3ef2e04f3bc1
timeCreated: 1677855364
@@ -0,0 +1,27 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using Meta.WitAi;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Data.Configuration.Tabs
{
public class WitConfigurationEntitiesTab: WitConfigurationEditorTab
{
public override int TabOrder { get; } = 2;
public override Type DataType => null;
public override string TabID { get; } = "entities";
public override string TabLabel { get; } = WitTexts.Texts.ConfigurationEntitiesTabLabel;
public override string MissingLabel { get; } = WitTexts.Texts.ConfigurationEntitiesMissingLabel;
public override bool ShouldTabShow(WitAppInfo appInfo)
{
return null != appInfo.entities;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5bd06d8523c94460b26f1228c2efd3e8
timeCreated: 1677872927
@@ -0,0 +1,26 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using Meta.WitAi;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Data.Configuration.Tabs
{
public class WitConfigurationIntentsTab : WitConfigurationEditorTab
{
public override Type DataType => null;
public override int TabOrder { get; } = 1;
public override string TabID { get; } = "intents";
public override string TabLabel { get; } = WitTexts.Texts.ConfigurationIntentsTabLabel;
public override string MissingLabel { get; } = WitTexts.Texts.ConfigurationIntentsMissingLabel;
public override bool ShouldTabShow(WitAppInfo appInfo)
{
return null != appInfo.intents;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c693b199fe184d9fb432dd65a4b47bee
timeCreated: 1677872672
@@ -0,0 +1,26 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using Meta.WitAi;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Data.Configuration.Tabs
{
public class WitConfigurationTraitsTab : WitConfigurationEditorTab
{
public override Type DataType => null;
public override int TabOrder { get; } = 3;
public override string TabID { get; } = "traits";
public override string TabLabel { get; } = WitTexts.Texts.ConfigurationTraitsTabLabel;
public override string MissingLabel { get; } = WitTexts.Texts.ConfigurationTraitsMissingLabel;
public override bool ShouldTabShow(WitAppInfo appInfo)
{
return null != appInfo.traits;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e918e26b57b74f01af337608e8d9a531
timeCreated: 1677872967
@@ -0,0 +1,26 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using Meta.WitAi;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Data.Configuration.Tabs
{
public class WitConfigurationVoicesTab: WitConfigurationEditorTab
{
public override Type DataType => null;
public override int TabOrder { get; } = 4;
public override string TabID { get; } = "voices";
public override string TabLabel { get; } = WitTexts.Texts.ConfigurationVoicesTabLabel;
public override string MissingLabel { get; } = WitTexts.Texts.ConfigurationVoicesMissingLabel;
public override bool ShouldTabShow(WitAppInfo appInfo)
{
return null != appInfo.voices;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d61288c0131e4c43bf0bce4d39f9d829
timeCreated: 1677869703
@@ -0,0 +1,14 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
namespace Meta.WitAi.Data.Configuration
{
public class WitApplicationDetailProvider : IApplicationDetailProvider
{
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 394d4d63ba17f4ed5918eccdd3b7059f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,631 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using Meta.WitAi.Data.Configuration.Tabs;
using Lib.Wit.Runtime.Requests;
using Meta.Conduit.Editor;
using Meta.WitAi.Configuration;
using Meta.WitAi.Data.Configuration;
using Meta.Conduit;
using Meta.Voice.TelemetryUtilities;
using Meta.WitAi.Lib;
using UnityEditor;
using UnityEngine;
using Meta.WitAi.Windows.Components;
namespace Meta.WitAi.Windows
{
[InitializeOnLoadAttribute]
public class WitConfigurationEditor : Editor
{
private ConduitManifestGenerationManager _conduitManifestGenerationManager;
public WitConfiguration Configuration {
get => _configuration;
private set
{
if (_configuration == value)
{
return;
}
_configuration = value;
_conduitManifestGenerationManager = ConduitManifestGenerationManager.GetInstance(_configuration);
}
}
private WitConfiguration _configuration;
private string _serverToken;
private string _appName;
private string _appID;
private bool _initialized = false;
public bool drawHeader = true;
private bool _foldout = true;
private int _requestTab = 0;
private bool _syncInProgress = false;
private bool _didCheckAutoTrainAvailability = false;
private bool _isAutoTrainAvailable = false;
/// <summary>
/// Whether or not server specific functionality like sync
/// should be disabled for this configuration
/// </summary>
protected virtual bool _disableServerPost => false;
private static readonly ManifestLoader ManifestLoader = new ManifestLoader();
private static readonly IWitVRequestFactory VRequestFactory = new WitVRequestFactory();
private EnumSynchronizer _enumSynchronizer;
private static Type[] _tabTypes;
private WitConfigurationEditorTab[] _tabs;
private const string ENTITY_SYNC_CONSENT_KEY = "Conduit.EntitySync.Consent";
protected virtual Texture2D HeaderIcon => WitTexts.HeaderIcon;
public virtual string HeaderUrl => WitTexts.GetAppURL(Configuration.GetApplicationId(), WitTexts.WitAppEndpointType.Settings);
protected virtual string DocsUrl => WitTexts.Texts.WitDocsUrl;
protected virtual string OpenButtonLabel => WitTexts.Texts.WitOpenButtonLabel;
public void Initialize()
{
// Shared between all WitConfigurationEditors
if (_tabTypes == null)
{
_tabTypes = typeof(WitConfigurationEditorTab).GetSubclassTypes().ToArray();
}
// Generate tab instances
if (_tabs == null)
{
_tabs = _tabTypes.Select(type => (WitConfigurationEditorTab)Activator.CreateInstance(type))
.OrderBy(tab =>tab.TabOrder)
.ToArray();
}
// Refresh configuration & auth tokens
Configuration = target as WitConfiguration;
// Get app server token
_serverToken = WitAuthUtility.GetAppServerToken(Configuration);
if (CanConfigurationRefresh(Configuration) && WitConfigurationUtility.IsServerTokenValid(_serverToken))
{
// Get client token if needed
_appID = Configuration.GetApplicationId();
if (string.IsNullOrEmpty(_appID))
{
Configuration.SetServerToken(_serverToken);
}
// Refresh additional data
else
{
SafeRefresh();
}
}
}
public void OnDisable()
{
ConduitManifestGenerationManager.PersistStatistics();
}
public override void OnInspectorGUI()
{
// Init if needed
if (!_initialized || Configuration != target)
{
Initialize();
_initialized = true;
}
// Draw header
WitEditorUI.LayoutHeaderText(target.name, HeaderUrl, DocsUrl);
// Layout content
LayoutContent();
}
private void LayoutConduitContent()
{
if (_conduitManifestGenerationManager == null)
{
_conduitManifestGenerationManager = ConduitManifestGenerationManager.GetInstance(Configuration);
}
var isServerTokenValid = WitConfigurationUtility.IsServerTokenValid(_serverToken);
if (!isServerTokenValid && !_disableServerPost)
{
GUILayout.TextArea(WitTexts.Texts.ConfigurationConduitMissingTokenLabel, WitStyles.LabelError);
}
EditorGUI.indentLevel++;
// Set conduit
var updated = false;
WitEditorUI.LayoutToggle(new GUIContent(WitTexts.Texts.ConfigurationConduitUseConduitLabel), ref Configuration.useConduit, ref updated);
if (updated)
{
EditorUtility.SetDirty(Configuration);
}
// Configuration buttons
GUILayout.Space(EditorGUI.indentLevel * WitStyles.ButtonMargin);
{
GUI.enabled = Configuration.useConduit;
updated = false;
WitEditorUI.LayoutToggle(
new GUIContent(WitTexts.Texts.ConfigurationConduitRelaxedResolutionsLabel,
WitTexts.Texts.ConfigurationConduitRelaxedResolutionsTooltip),
ref Configuration.relaxedResolution, ref updated);
if (updated)
{
EditorUtility.SetDirty(Configuration);
}
GUILayout.BeginHorizontal();
{
if (_conduitManifestGenerationManager != null && WitEditorUI.LayoutTextButton(_conduitManifestGenerationManager.ManifestAvailable ? WitTexts.Texts.ConfigurationConduitUpdateManifestLabel : WitTexts.Texts.ConfigurationConduitGenerateManifestLabel))
{
_conduitManifestGenerationManager.GenerateManifest(Configuration, true);
}
GUI.enabled = Configuration.useConduit && _conduitManifestGenerationManager.ManifestAvailable ;
if (WitEditorUI.LayoutTextButton(WitTexts.Texts.ConfigurationConduitSelectManifestLabel) && _conduitManifestGenerationManager.ManifestAvailable )
{
Selection.activeObject =
AssetDatabase.LoadAssetAtPath<TextAsset>(Configuration.GetManifestEditorPath());
}
GUI.enabled = Configuration.useConduit;
if (WitEditorUI.LayoutTextButton(WitTexts.Texts.ConfigurationConduitSpecifyAssembliesLabel))
{
PresentAssemblySelectionDialog();
}
if (isServerTokenValid && !_disableServerPost)
{
GUI.enabled = Configuration.useConduit && _conduitManifestGenerationManager.ManifestAvailable && !_syncInProgress;
if (WitEditorUI.LayoutTextButton(WitTexts.Texts.ConfigurationConduitSyncEntitiesLabel))
{
SyncEntities();
GUIUtility.ExitGUI();
return;
}
if (_isAutoTrainAvailable)
{
if (WitEditorUI.LayoutTextButton(WitTexts.Texts.ConfigurationConduitAutoTrainLabel) && _conduitManifestGenerationManager.ManifestAvailable )
{
SyncEntities(() => { AutoTrainOnWitAi(Configuration); });
}
}
}
GUI.enabled = true;
}
GUILayout.EndHorizontal();
}
EditorGUI.indentLevel--;
}
protected virtual void LayoutContent()
{
// Begin vertical box
GUILayout.BeginVertical(EditorStyles.helpBox);
// Check for app name/id update
ReloadAppData();
// Title Foldout
GUILayout.BeginHorizontal();
string foldoutText = WitTexts.Texts.ConfigurationHeaderLabel;
if (!string.IsNullOrEmpty(_appName))
{
foldoutText = foldoutText + " - " + _appName;
}
_foldout = WitEditorUI.LayoutFoldout(new GUIContent(foldoutText), _foldout);
// Refresh button
if (CanConfigurationRefresh(Configuration))
{
if (string.IsNullOrEmpty(_appName))
{
bool isValid = WitConfigurationUtility.IsServerTokenValid(_serverToken);
GUI.enabled = isValid;
if (WitEditorUI.LayoutTextButton(WitTexts.Texts.ConfigurationRefreshButtonLabel))
{
ApplyServerToken(_serverToken);
}
}
else
{
bool isRefreshing = Configuration.IsUpdatingData();
GUI.enabled = !isRefreshing;
if (WitEditorUI.LayoutTextButton(isRefreshing ? WitTexts.Texts.ConfigurationRefreshingButtonLabel : WitTexts.Texts.ConfigurationRefreshButtonLabel))
{
SafeRefresh();
}
}
}
GUI.enabled = true;
GUILayout.EndHorizontal();
GUILayout.Space(WitStyles.ButtonMargin);
// Show configuration app data
if (_foldout)
{
// Indent
EditorGUI.indentLevel++;
// Server access token
bool updated = false;
WitEditorUI.LayoutPasswordField(WitTexts.ConfigurationServerTokenContent, ref _serverToken, ref updated);
if (updated && WitConfigurationUtility.IsServerTokenValid(_serverToken))
{
ApplyServerToken(_serverToken);
}
// Additional data
if (Configuration)
{
LayoutConfigurationData();
}
// Undent
EditorGUI.indentLevel--;
}
// End vertical box layout
GUILayout.EndVertical();
GUILayout.BeginVertical(EditorStyles.helpBox);
LayoutConduitContent();
GUILayout.EndVertical();
// Layout configuration request tabs
LayoutConfigurationRequestTabs();
// Additional open wit button
GUILayout.FlexibleSpace();
if (GUILayout.Button(OpenButtonLabel, WitStyles.TextButton))
{
Application.OpenURL(HeaderUrl);
}
}
// Reload app data if needed
private void ReloadAppData()
{
// Check for changes
string checkID = "";
string checkName = "";
if (Configuration != null)
{
checkID = Configuration.GetApplicationId();
if (!string.IsNullOrEmpty(checkID))
{
checkName = Configuration.GetApplicationInfo().name;
}
}
// Reset
if (!string.Equals(_appName, checkName) || !string.Equals(_appID, checkID))
{
// Refresh app data
_appName = checkName;
_appID = checkID;
// Do not clear token if failed to set
string newToken = WitAuthUtility.GetAppServerToken(Configuration);
if (!string.IsNullOrEmpty(newToken))
{
_serverToken = newToken;
}
}
}
// Apply server token
public void ApplyServerToken(string newToken)
{
if (newToken != _serverToken)
{
_serverToken = newToken;
Configuration.ResetData();
}
WitAuthUtility.ServerToken = _serverToken;
Configuration.SetServerToken(_serverToken);
_conduitManifestGenerationManager.GenerateManifest(Configuration, false);
}
// Whether or not to allow a configuration to refresh
protected virtual bool CanConfigurationRefresh(WitConfiguration configuration)
{
return configuration;
}
// Layout configuration data
protected virtual void LayoutConfigurationData()
{
// Reset update
bool updated = false;
// Client access field
string clientAccessToken = Configuration.GetClientAccessToken();
WitEditorUI.LayoutPasswordField(WitTexts.ConfigurationClientTokenContent, ref clientAccessToken, ref updated);
if (updated && string.IsNullOrEmpty(clientAccessToken))
{
VLog.E("Client access token is not defined. Cannot perform requests with '" + Configuration.name + "'.");
}
// Timeout field
WitEditorUI.LayoutIntField(WitTexts.ConfigurationRequestTimeoutContent, ref Configuration.timeoutMS, ref updated);
// Updated
if (updated)
{
Configuration.SetClientAccessToken(clientAccessToken);
}
// Show configuration app data
LayoutConfigurationEndpoint();
}
// Layout endpoint data
protected virtual void LayoutConfigurationEndpoint()
{
// Generate if needed
if (Configuration.endpointConfiguration == null)
{
Configuration.endpointConfiguration = new WitEndpointConfig();
EditorUtility.SetDirty(Configuration);
}
// Handle via serialized object
var serializedObj = new SerializedObject(Configuration);
var serializedProp = serializedObj.FindProperty("endpointConfiguration");
EditorGUILayout.PropertyField(serializedProp);
serializedObj.ApplyModifiedProperties();
}
// Tabs
protected virtual void LayoutConfigurationRequestTabs()
{
// Application info
Data.Info.WitAppInfo appInfo = Configuration.GetApplicationInfo();
// Indent
EditorGUI.indentLevel++;
// Iterate tabs
if (_tabs != null)
{
GUILayout.BeginHorizontal();
for (int i = 0; i < _tabs.Length; i++)
{
// Enable if not selected
GUI.enabled = _requestTab != i;
// If valid and clicked, begin selecting
if (null != appInfo.id &&
(_tabs[i].ShouldTabShow(appInfo) || _tabs[i].ShouldTabShow(Configuration)))
{
if (WitEditorUI.LayoutTabButton(_tabs[i].GetTabText(true)))
{
_requestTab = i;
}
}
// If invalid, stop selecting
else if (_requestTab == i)
{
_requestTab = -1;
}
}
GUI.enabled = true;
GUILayout.EndHorizontal();
// Layout selected tab using property id
string propertyID = _requestTab >= 0 && _requestTab < _tabs.Length
? _tabs[_requestTab].TabID
: string.Empty;
if (!string.IsNullOrEmpty(propertyID) && Configuration != null)
{
var newConfigData = Array.Find(Configuration.GetConfigData(), d => d.GetType() == _tabs[_requestTab].DataType);
SerializedObject serializedObj;
if (newConfigData == null)
{
serializedObj = new SerializedObject(Configuration);
}
else
{
serializedObj = new SerializedObject(newConfigData);
}
SerializedProperty serializedProp = serializedObj.FindProperty(_tabs[_requestTab].GetPropertyName(propertyID));
if (serializedProp == null)
{
WitEditorUI.LayoutErrorLabel(_tabs[_requestTab].GetTabText(false));
}
else if (!serializedProp.isArray)
{
EditorGUILayout.PropertyField(serializedProp);
}
else if (serializedProp.arraySize == 0)
{
WitEditorUI.LayoutErrorLabel(_tabs[_requestTab].GetTabText(false));
}
else
{
for (int i = 0; i < serializedProp.arraySize; i++)
{
SerializedProperty serializedPropChild = serializedProp.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(serializedPropChild);
}
}
serializedObj.ApplyModifiedProperties();
}
}
// Undent
EditorGUI.indentLevel--;
}
// Safe refresh
protected virtual void SafeRefresh()
{
if (EditorApplication.isPlayingOrWillChangePlaymode) return;
if (WitConfigurationUtility.IsServerTokenValid(_serverToken))
{
Configuration.SetServerToken(_serverToken);
Configuration.UpdateDataAssets();
}
else if (WitConfigurationUtility.IsClientTokenValid(Configuration.GetClientAccessToken()))
{
Configuration.RefreshAppInfo();
Configuration.UpdateDataAssets();
}
if (Configuration.useConduit)
{
CheckAutoTrainAvailabilityIfNeeded();
}
}
private void CheckAutoTrainAvailabilityIfNeeded()
{
if (_didCheckAutoTrainAvailability || !WitConfigurationUtility.IsServerTokenValid(_serverToken)) {
return;
}
_didCheckAutoTrainAvailability = true;
CheckAutoTrainIsAvailable(Configuration, (isAvailable) => {
_isAutoTrainAvailable = isAvailable;
Telemetry.LogInstantEvent(Telemetry.TelemetryEventId.CheckAutoTrain, new Dictionary<Telemetry.AnnotationKey, string>
{
{ Telemetry.AnnotationKey.IsAvailable, isAvailable.ToString() }
});
});
}
// Show dialog to disable/enable assemblies
private void PresentAssemblySelectionDialog()
{
var assemblyWalker = _conduitManifestGenerationManager.AssemblyWalker;
var assemblyNames = assemblyWalker.GetAllAssemblies().Select(a => a.FullName).ToList();
assemblyWalker.AssembliesToIgnore = new HashSet<string>(Configuration.excludedAssemblies);
WitMultiSelectionPopup.Show(assemblyNames, assemblyWalker.AssembliesToIgnore, (disabledAssemblies) => {
assemblyWalker.AssembliesToIgnore = new HashSet<string>(disabledAssemblies);
Configuration.excludedAssemblies = new List<string>(assemblyWalker.AssembliesToIgnore);
_conduitManifestGenerationManager.GenerateManifest(Configuration, false);
});
}
// Sync entities
private void SyncEntities(Action successCallback = null)
{
var instanceKey = Telemetry.StartEvent(Telemetry.TelemetryEventId.SyncEntities);
if (!EditorUtility.DisplayDialog("Synchronizing with Wit.Ai entities", "This will synchronize local enums with Wit.Ai entities. Part of this process involves generating code locally and may result in overwriting existing code. Please make sure to backup your work before proceeding.", "Proceed", "Cancel", DialogOptOutDecisionType.ForThisSession, ENTITY_SYNC_CONSENT_KEY))
{
Telemetry.EndEvent(instanceKey, Telemetry.ResultType.Cancel);
VLog.D("Entity Sync cancelled");
return;
}
// Fail without server token
var validServerToken = WitConfigurationUtility.IsServerTokenValid(_serverToken);
if (!validServerToken)
{
Telemetry.EndEventWithFailure(instanceKey, "Invalid server token");
VLog.E($"Conduit Sync Failed\nError: Invalid server token");
return;
}
// Generate
if (_enumSynchronizer == null)
{
var assemblyWalker = _conduitManifestGenerationManager.AssemblyWalker;
_enumSynchronizer = new EnumSynchronizer(Configuration, assemblyWalker, new FileIo(), VRequestFactory);
}
// Sync
_syncInProgress = true;
EditorUtility.DisplayProgressBar("Conduit Entity Sync", "Generating Manifest.", 0f );
_conduitManifestGenerationManager.GenerateManifest(Configuration, false);
var manifest = LoadManifest(Configuration.ManifestLocalPath);
const float initializationProgress = 0.1f;
EditorUtility.DisplayProgressBar("Conduit Entity Sync", "Synchronizing entities. Please wait...", initializationProgress);
VLog.D("Synchronizing enums with Wit.Ai entities");
CoroutineUtility.StartCoroutine(_enumSynchronizer.SyncWitEntities(manifest, (success, data) =>
{
_syncInProgress = false;
EditorUtility.ClearProgressBar();
if (!success)
{
Telemetry.EndEventWithFailure(instanceKey, data);
VLog.E($"Conduit failed to synchronize entities\nError: {data}");
}
else
{
Telemetry.EndEvent(instanceKey, Telemetry.ResultType.Success);
VLog.D("Conduit successfully synchronized entities");
successCallback?.Invoke();
}
},
(status, progress) =>
{
EditorUtility.DisplayProgressBar("Conduit Entity Sync", status,
initializationProgress + (1f - initializationProgress) * progress);
}));
}
private void AutoTrainOnWitAi(WitConfiguration configuration)
{
var instanceKey = Telemetry.StartEvent(Telemetry.TelemetryEventId.AutoTrain);
var manifest = LoadManifest(configuration.ManifestLocalPath);
var intents = _conduitManifestGenerationManager.ExtractManifestData();
VLog.D($"Auto training on WIT.ai: {intents.Count} intents.");
configuration.ImportData(manifest, (isSuccess, error) =>
{
if (isSuccess)
{
Telemetry.EndEvent(instanceKey, Telemetry.ResultType.Success);
EditorUtility.DisplayDialog("Auto Train", "Successfully started auto train process on WIT.ai.",
"OK");
}
else
{
var failureMessage =
$"Failed to import generated manifest JSON into WIT.ai: {error}. Manifest:\n{manifest}";
Telemetry.EndEventWithFailure(instanceKey, failureMessage);
VLog.E(failureMessage);
EditorUtility.DisplayDialog("Auto Train", "Failed to start auto train process on WIT.ai.", "OK");
}
});
}
private void CheckAutoTrainIsAvailable(WitConfiguration configuration, Action<bool> onComplete)
{
var appInfo = configuration.GetApplicationInfo();
var manifestText = _conduitManifestGenerationManager.GenerateEmptyManifest(appInfo.name, appInfo.id);
var manifest = ManifestLoader.LoadManifestFromString(manifestText);
configuration.ImportData(manifest, (result, error) => onComplete(result), true);
}
private static Manifest LoadManifest(string manifestPath)
{
var instanceKey = Telemetry.StartEvent(Telemetry.TelemetryEventId.LoadManifest);
var manifest = ManifestLoader.LoadManifest(manifestPath);
if (manifest == null)
{
Telemetry.EndEventWithFailure(instanceKey);
}
Telemetry.EndEvent(instanceKey, Telemetry.ResultType.Success);
return manifest;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fda2e192978913c42af9533c9a0baa01
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using UnityEditor;
namespace Meta.WitAi.Data.Configuration
{
public class WitConfigurationPostprocessor : AssetPostprocessor
{
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets,
string[] movedFromAssetPaths)
{
WitConfigurationUtility.NeedsConfigReload();
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 16fe7d4f8f3e51a42ab214947550a298
timeCreated: 1631316958
@@ -0,0 +1,391 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
#if UNITY_EDITOR
//#define VERBOSE_LOG
#endif
using System;
using System.Collections.Generic;
using Meta.Conduit;
using Meta.Voice.TelemetryUtilities;
using Meta.WitAi.Json;
using UnityEditor;
using UnityEngine;
using Meta.WitAi.Lib;
using Meta.WitAi.Requests;
using Meta.WitAi.Windows;
using Meta.WitAi.Interfaces;
using UnityEngine.SceneManagement;
namespace Meta.WitAi.Data.Configuration
{
public static class WitConfigurationUtility
{
#region ACCESS
// Return wit configs
public static WitConfiguration[] WitConfigs
{
get
{
// Reload if not setup
if (_witConfigs == null)
{
ReloadConfigurationData();
}
// Force reload
if (_needsConfigReload)
{
ReloadConfigurationData();
}
// Return config data
return _witConfigs;
}
}
// Wit configuration assets
private static WitConfiguration[] _witConfigs = null;
// Wit configuration asset names
public static string[] WitConfigNames => _witConfigNames;
private static string[] _witConfigNames = Array.Empty<string>();
// Config reload
private static bool _needsConfigReload = false;
// Has configuration
public static bool HasValidCustomConfig()
{
// Find a valid custom configuration
return Array.Exists(WitConfigs, (c) => !c.isDemoOnly);
}
// Enable config reload on next access
public static void NeedsConfigReload()
{
_needsConfigReload = true;
}
// Refresh configuration asset list
public static void ReloadConfigurationData()
{
// Reloaded
_needsConfigReload = false;
// Find all Wit Configurations
List<WitConfiguration> loaded = GetLoadedConfigurations();
List<WitConfiguration> found = new List<WitConfiguration>();
string[] guids = AssetDatabase.FindAssets("t:WitConfiguration");
foreach (var guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
WitConfiguration config = AssetDatabase.LoadAssetAtPath<WitConfiguration>(path);
if (!config.isDemoOnly || loaded.Contains(config))
{
found.Add(config);
}
}
// Store wit configuration data
_witConfigs = found.ToArray();
// Obtain all names
_witConfigNames = new string[_witConfigs.Length];
for (int i = 0; i < _witConfigs.Length; i++)
{
_witConfigNames[i] = _witConfigs[i].name;
}
}
// Get configuration index
public static int GetConfigurationIndex(WitConfiguration configuration)
{
// Search through configs
return Array.FindIndex(WitConfigs, (checkConfig) => checkConfig == configuration );
}
// Get configuration index
public static int GetConfigurationIndex(string configurationName)
{
// Search through configs
return Array.FindIndex(WitConfigs, (checkConfig) => string.Equals(checkConfig.name, configurationName));
}
// Return all configurations referenced in loaded scenes
public static List<WitConfiguration> GetLoadedConfigurations()
{
// Get results
List<WitConfiguration> results = new List<WitConfiguration>();
// Iterate loaded scenes
for (int sceneIndex = 0; sceneIndex < SceneManager.sceneCount; sceneIndex++)
{
Scene scene = SceneManager.GetSceneAt(sceneIndex);
if (!scene.IsValid() || !scene.isLoaded)
{
continue;
}
foreach (var rootGameObject in scene.GetRootGameObjects())
{
IWitConfigurationProvider[] providers = rootGameObject.GetComponentsInChildren<IWitConfigurationProvider>(true);
if (providers != null)
{
foreach (var provider in providers)
{
WitConfiguration config = provider.Configuration;
if (config != null && !results.Contains(config))
{
results.Add(config);
}
}
}
}
}
// Return results list
return results;
}
#endregion
#region MANAGEMENT
// Create configuration for token with blank configuration
public static int CreateConfiguration(string serverToken)
{
// Generate blank asset
WitConfiguration configurationAsset = ScriptableObject.CreateInstance<WitConfiguration>();
configurationAsset.name = WitTexts.Texts.ConfigurationFileNameLabel;
configurationAsset.ResetData();
// Create
int index = SaveConfiguration(serverToken, configurationAsset);
if (index == -1)
{
configurationAsset.DestroySafely();
}
// Return new index
return index;
}
// Get asset save directory
public static string GetFileSaveDirectory(string title, string fileName, string fileExt)
{
// Determine root directory with selection if possible
string rootDirectory = Application.dataPath;
if (Selection.activeObject)
{
// Get asset path
string selectedPath = AssetDatabase.GetAssetPath(Selection.activeObject);
// Only allow if in assets
if (selectedPath.StartsWith("Assets"))
{
if (AssetDatabase.IsValidFolder(selectedPath))
{
rootDirectory = selectedPath;
}
else if (!string.IsNullOrEmpty(selectedPath))
{
rootDirectory = new System.IO.FileInfo(selectedPath).DirectoryName;
}
}
}
// Save panel
return EditorUtility.SaveFilePanel(title, rootDirectory, fileName, fileExt);
}
// Save configuration after determining path
public static int SaveConfiguration(string serverToken, WitConfiguration configurationAsset)
{
string savePath = GetFileSaveDirectory(WitTexts.Texts.ConfigurationFileManagerLabel, WitTexts.Texts.ConfigurationFileNameLabel, "asset");
return SaveConfiguration(savePath, serverToken, configurationAsset);
}
// Save configuration to selected location
public static int SaveConfiguration(string savePath, string serverToken, WitConfiguration configurationAsset)
{
// Ensure valid save path
if (string.IsNullOrEmpty(savePath))
{
return -1;
}
// Must be in assets
string unityPath = savePath.Replace("\\", "/");
if (!unityPath.StartsWith(Application.dataPath))
{
VLog.E($"Configuration Utility - Cannot Create Configuration Outside of Assets Directory\nPath: {unityPath}");
return -1;
}
// Determine local unity path
unityPath = unityPath.Replace(Application.dataPath, "Assets");
AssetDatabase.CreateAsset(configurationAsset, unityPath);
AssetDatabase.SaveAssets();
configurationAsset.UpdateDataAssets(); //must be done after SaveAssets
// Refresh configurations
ReloadConfigurationData();
// Get new index following reload
string name = System.IO.Path.GetFileNameWithoutExtension(unityPath);
int index = GetConfigurationIndex(name);
// Set server token
if (!string.IsNullOrEmpty(serverToken))
{
_witConfigs[index].SetServerToken(serverToken);
}
// Return index
return index;
}
#endregion
#region TOKENS
// Token valid check
public static bool IsServerTokenValid(string serverToken)
{
return !string.IsNullOrEmpty(serverToken) && WitAuthUtility.IsServerTokenValid(serverToken);
}
// Token valid check
public static bool IsClientTokenValid(string clientToken)
{
return !string.IsNullOrEmpty(clientToken) && clientToken.Length == 32;
}
// Sets server token for all configurations if possible
public static void SetServerToken(string serverToken, Action<string> onSetComplete = null)
{
// Invalid token
if (!IsServerTokenValid(serverToken))
{
SetServerTokenComplete(string.Empty, "", onSetComplete);
return;
}
// Perform a list app request to get app for token
WitAppInfoUtility.GetAppInfo(serverToken, (clientToken, info, error) =>
{
SetServerTokenComplete(serverToken, error, onSetComplete);
});
}
// Set server token complete
private static void SetServerTokenComplete(string serverToken, string error, Action<string> onSetComplete)
{
// Failed
if (!string.IsNullOrEmpty(error))
{
VLog.E($"Set Server Token Failed\n{error}");
WitAuthUtility.ServerToken = "";
}
// Success
else
{
// Log Success
VLog.D("Set Server Token Success");
// Apply token
WitAuthUtility.ServerToken = serverToken;
// Refresh configurations
ReloadConfigurationData();
}
// On complete
onSetComplete?.Invoke(error);
}
// Sets server token for specified configuration by updating it's application data
public static void SetServerToken(this WitConfiguration configuration, string serverToken, Action<string> onSetComplete = null)
{
var instanceKey = Telemetry.StartEvent(Telemetry.TelemetryEventId.SupplyToken);
// Invalid
if (!IsServerTokenValid(serverToken))
{
onSetComplete?.Invoke("Invalid Token");
return;
}
// Perform a list app request to get app for token
WitAppInfoUtility.GetAppInfo(serverToken, (clientToken, info, error) =>
{
// Set client access token
configuration.SetClientAccessToken(clientToken);
// Set application info
configuration.SetApplicationInfo(info);
// Set server token
if (!string.IsNullOrEmpty(info.id))
{
WitAuthUtility.SetAppServerToken(info.id, serverToken);
}
// Complete
if (!string.IsNullOrEmpty(error))
{
Telemetry.EndEventWithFailure(instanceKey, error);
}
else
{
Telemetry.EndEvent(instanceKey, Telemetry.ResultType.Success);
}
onSetComplete?.Invoke(error);
});
}
// Determine if is a server token
public static VRequest CheckServerToken(string serverToken, Action<bool> onComplete) => WitAppInfoUtility.CheckServerToken(serverToken, onComplete);
#endregion
#region APP DATA IMPORT
/// <summary>
/// Import supplied Manifest into WIT.ai.
/// </summary>
internal static void ImportData(this WitConfiguration configuration, Manifest manifest, VRequest.RequestCompleteDelegate<bool> onComplete = null, bool suppressLogs = false)
{
var manifestData = GetSanitizedManifestString(manifest);
var request = new WitSyncVRequest(configuration);
VLog.SuppressLogs = suppressLogs;
request.RequestImportData(manifestData, (error, responseData) =>
{
VLog.SuppressLogs = false;
if (!string.IsNullOrEmpty(error))
{
onComplete?.Invoke(false, error);
}
else
{
onComplete?.Invoke(true, string.Empty);
}
});
}
/// <summary>
/// Returns a serialized version of the manifest after removing internal data that should not be sent to IDM.
/// </summary>
/// <param name="manifest">The manifest to process.</param>
private static string GetSanitizedManifestString(Manifest manifest)
{
var filter = new WitParameterFilter();
foreach (var action in manifest.Actions)
{
action.Parameters.RemoveAll(a => filter.ShouldFilterOut(a.EntityType));
}
return JsonConvert.SerializeObject(manifest);
}
#endregion
#region REFRESH
// Refreshes configuration data
public static void RefreshAppInfo(this WitConfiguration configuration, Action<string> onRefreshComplete = null)
{
// Ignore during runtime
if (Application.isPlaying)
{
onRefreshComplete?.Invoke(null);
return;
}
// Update application info
WitAppInfoUtility.Update(configuration, (info, s) =>
{
// Set application info
configuration.SetApplicationInfo(info);
// Complete
onRefreshComplete?.Invoke(s);
});
}
#endregion
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 67da0cb4ba914f6cb2a97a343ff81db1
timeCreated: 1631316958
@@ -0,0 +1,94 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using UnityEditor;
using System.Reflection;
using Meta.WitAi.Configuration;
namespace Meta.WitAi.Windows
{
[CustomPropertyDrawer(typeof(WitEndpointConfig))]
public class WitEndpointConfigDrawer : WitPropertyDrawer
{
// All WitEndpointConfig parameters
private const string FIELD_URISCHEME = "_uriScheme";
private const string FIELD_AUTHORITY = "_authority";
private const string FIELD_PORT = "_port";
private const string FIELD_API = "_witApiVersion";
private const string FIELD_SPEECH = "_speech";
private const string FIELD_MESSAGE = "_message";
private const string FIELD_DICTATION = "_dictation";
private const string FIELD_SYNTHESIZE = "_synthesize";
// Allow edit with lock
protected override WitPropertyEditType EditType => WitPropertyEditType.LockEdit;
// Get default fields
protected override string GetDefaultFieldValue(SerializedProperty property, FieldInfo subfield)
{
// Iterate options
switch (subfield.Name)
{
case FIELD_URISCHEME:
return WitConstants.URI_SCHEME;
case FIELD_AUTHORITY:
return WitConstants.URI_AUTHORITY;
case FIELD_PORT:
return "0";
case FIELD_API:
return WitConstants.API_VERSION;
case FIELD_SPEECH:
return WitConstants.ENDPOINT_SPEECH;
case FIELD_MESSAGE:
return WitConstants.ENDPOINT_MESSAGE;
case FIELD_DICTATION:
return WitConstants.ENDPOINT_DICTATION;
case FIELD_SYNTHESIZE:
return WitConstants.ENDPOINT_TTS;
case "_event":
return WitConstants.ENDPOINT_COMPOSER_MESSAGE;
case "_converse":
return WitConstants.ENDPOINT_COMPOSER_SPEECH;
}
// Return base
return base.GetDefaultFieldValue(property, subfield);
}
// Use name value for title if possible
protected override string GetLocalizedText(SerializedProperty property, string key)
{
// Iterate options
switch (key)
{
case LocalizedTitleKey:
return WitTexts.Texts.ConfigurationEndpointTitleLabel;
case FIELD_URISCHEME:
return WitTexts.Texts.ConfigurationEndpointUriLabel;
case FIELD_AUTHORITY:
return WitTexts.Texts.ConfigurationEndpointAuthLabel;
case FIELD_PORT:
return WitTexts.Texts.ConfigurationEndpointPortLabel;
case FIELD_API:
return WitTexts.Texts.ConfigurationEndpointApiLabel;
case FIELD_SPEECH:
return WitTexts.Texts.ConfigurationEndpointSpeechLabel;
case FIELD_MESSAGE:
return WitTexts.Texts.ConfigurationEndpointMessageLabel;
case FIELD_DICTATION:
return WitTexts.Texts.ConfigurationEndpointDictationLabel;
case FIELD_SYNTHESIZE:
return WitTexts.Texts.ConfigurationEndpointSynthesizeLabel;
case "_event":
return WitTexts.Texts.ConfigurationEndpointComposerEventLabel;
case "_converse":
return WitTexts.Texts.ConfigurationEndpointComposerConverseLabel;
}
// Default to base
return base.GetLocalizedText(property, key);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5fff8addd8c86d94d9e793036f5e5538
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,38 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Collections.Generic;
using Meta.WitAi.Data;
using Meta.WitAi.Lib;
using Meta.Conduit.Editor;
using Meta.WitAi.Json;
namespace Meta.WitAi.Windows
{
/// <summary>
/// Filters out parameters of specific types.
/// </summary>
internal class WitParameterFilter : IParameterFilter
{
/// <summary>
/// Tests if a parameter type should be filtered out.
/// </summary>
/// <param name="type">The data type.</param>
/// <returns>True if the parameter type should be filtered out. False otherwise.</returns>
public bool ShouldFilterOut(Type type)
{
return type == typeof(WitResponseNode) || type == typeof(VoiceSession);
}
public bool ShouldFilterOut(string typeName)
{
return typeName == nameof(WitResponseNode) || typeName == nameof(VoiceSession);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 32bad071f0c2d4fa1b657f119f712adc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,38 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Collections.Generic;
using Meta.WitAi.Data;
using Meta.WitAi.Json;
using Meta.Conduit.Editor;
namespace Meta.WitAi.Windows
{
/// <summary>
/// Validates whether a data type if supported by Wit.
/// </summary>
internal class WitParameterValidator : IParameterValidator
{
/// <summary>
/// These are the types that we natively support.
/// </summary>
private readonly HashSet<Type> _builtInTypes = new HashSet<Type>()
{ typeof(string), typeof(int), typeof(DateTime), typeof(float), typeof(double), typeof(decimal) };
/// <summary>
/// Tests if a parameter type can be supplied directly to a callback method from.
/// </summary>
/// <param name="type">The data type.</param>
/// <returns>True if the parameter type is supported. False otherwise.</returns>
public bool IsSupportedParameterType(Type type)
{
return type.IsEnum || _builtInTypes.Contains(type) || type == typeof(WitResponseNode) || type == typeof(VoiceSession) || type == typeof(Exception);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b06aba70db204455b215439ad07b8253
timeCreated: 1653423412
@@ -0,0 +1,175 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using UnityEngine;
using Meta.WitAi.Data.Configuration;
using Meta.WitAi.Lib;
using Meta.WitAi.Requests;
namespace Meta.WitAi.Windows
{
public class WitWelcomeWizard : WitScriptableWizard
{
protected string serverToken;
public Action<WitConfiguration> successAction;
protected override Texture2D HeaderIcon => WitTexts.HeaderIcon;
protected override GUIContent Title => WitTexts.SetupTitleContent;
protected override string ButtonLabel => WitTexts.Texts.SetupSubmitButtonLabel;
protected override string ContentSubheaderLabel => WitTexts.Texts.SetupSubheaderLabel;
// Whether currently using a client token
private bool _isCheckingToken = false;
private bool _usingClientToken = false;
private VRequest _request;
protected override void OnEnable()
{
base.OnEnable();
_isCheckingToken = false;
_usingClientToken = false;
serverToken = string.Empty;
WitAuthUtility.ServerToken = serverToken;
}
protected virtual void OnDisable()
{
StopTokenCheck();
}
protected override bool DrawWizardGUI()
{
// Layout base
base.DrawWizardGUI();
// True if valid server token
return WitConfigurationUtility.IsServerTokenValid(serverToken);
}
protected override void LayoutFields()
{
// Token label
string serverTokenLabelText = WitTexts.Texts.SetupServerTokenLabel;
serverTokenLabelText = serverTokenLabelText.Replace(WitStyles.WitLinkKey, WitStyles.WitLinkColor);
if (GUILayout.Button(serverTokenLabelText, WitStyles.Label))
{
Application.OpenURL(WitTexts.GetAppURL("", WitTexts.WitAppEndpointType.Settings));
}
// Token field
bool updated = false;
WitEditorUI.LayoutPasswordField(null, ref serverToken, ref updated);
// Verifying
if (_isCheckingToken)
{
WitEditorUI.LayoutLabel(WitTexts.Texts.SetupServerTokenVerifyLabel);
}
// Client token warning
else if (_usingClientToken)
{
WitEditorUI.LayoutErrorLabel(WitTexts.Texts.SetupClientTokenWarningLabel);
}
// Determine if new token is a server token
if (updated && WitConfigurationUtility.IsServerTokenValid(serverToken))
{
CheckToken();
}
}
private void CheckToken()
{
// Cancel previous check
StopTokenCheck();
// Begin checking
_isCheckingToken = true;
// Perform request
_request = WitConfigurationUtility.CheckServerToken(serverToken, (success) =>
{
_usingClientToken = !success;
_isCheckingToken = false;
});
}
private void StopTokenCheck()
{
// Ignore if not checking
if (!_isCheckingToken)
{
return;
}
// Kill request
if (_request != null)
{
_request.Cancel();
_request = null;
}
// Done checking
_isCheckingToken = false;
}
protected override void OnWizardCreate()
{
ValidateAndClose();
}
protected virtual void ValidateAndClose()
{
// Verify
if (_isCheckingToken)
{
VLog.E(WitTexts.Texts.SetupServerTokenVerifyWarning);
return;
}
// Check client token
if (_usingClientToken)
{
if (!WitConfigurationUtility.IsClientTokenValid(serverToken))
{
VLog.E(WitTexts.Texts.SetupSubmitFailLabel);
return;
}
}
// Check server token
else
{
WitAuthUtility.ServerToken = serverToken;
if (!WitAuthUtility.IsServerTokenValid())
{
VLog.E(WitTexts.Texts.SetupSubmitFailLabel);
return;
}
}
// Create configuration
int index = CreateConfiguration(serverToken);
if (index != -1)
{
// Complete
Close();
WitConfiguration c = WitConfigurationUtility.WitConfigs[index];
if (successAction == null)
{
WitWindowUtility.OpenConfigurationWindow(c);
}
else
{
successAction(c);
}
}
}
protected virtual int CreateConfiguration(string newToken)
{
// Generate asset with client token
if (_usingClientToken)
{
WitConfiguration configuration = ScriptableObject.CreateInstance<WitConfiguration>();
configuration.SetClientAccessToken(newToken);
return WitConfigurationUtility.SaveConfiguration(string.Empty, configuration);
}
// Generate asset with server token
return WitConfigurationUtility.CreateConfiguration(newToken);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 842ab427b28d8450597f95ef8c8689f7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,224 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using Meta.Voice.TelemetryUtilities;
using UnityEditor;
using UnityEngine;
using Meta.WitAi.Data.Configuration;
namespace Meta.WitAi.Windows
{
public class WitWindow : WitConfigurationWindow
{
protected WitConfigurationEditor witInspector;
protected string serverToken;
protected override GUIContent Title => WitTexts.SettingsTitleContent;
protected override string HeaderUrl => witInspector ? witInspector.HeaderUrl : base.HeaderUrl;
// VLog log level
private static int _logLevel = -1;
private static string[] _logLevelNames;
private static readonly VLogLevel[] _logLevels = (Enum.GetValues(typeof(VLogLevel)) as VLogLevel[])?.Reverse().ToArray();
#if VSDK_TELEMETRY_AVAILABLE
private static int _telemetryLogLevel = -1;
private static string[] _telemetryLogLevelNames;
private static readonly TelemetryLogLevel[] _telemetryLogLevels = new TelemetryLogLevel[]
{ TelemetryLogLevel.Off, TelemetryLogLevel.Basic, TelemetryLogLevel.Verbose };
#endif
public virtual bool ShowWitConfiguration => true;
public virtual bool ShowGeneralSettings => true;
public static bool ShowTooltips
{
get => EditorPrefs.GetBool("VSDK::Settings::Tooltips", true);
set => EditorPrefs.SetBool("VSDK::Settings::Tooltips", value);
}
protected override void OnEnable()
{
base.OnEnable();
if (string.IsNullOrEmpty(serverToken))
{
serverToken = WitAuthUtility.ServerToken;
}
RefreshLogLevel();
InitializeTelemetryLevelOptions();
SetWitEditor();
}
protected virtual void SetWitEditor()
{
// Destroy inspector
if (witInspector != null)
{
DestroyImmediate(witInspector);
witInspector = null;
}
// Generate new inspector & initialize immediately
if (witConfiguration)
{
witInspector = (WitConfigurationEditor)Editor.CreateEditor(witConfiguration);
witInspector.drawHeader = false;
witInspector.Initialize();
}
}
protected override void LayoutContent()
{
if (ShowGeneralSettings) DrawGeneralSettings();
if (ShowWitConfiguration) DrawWitConfigurations();
}
private void DrawGeneralSettings()
{
// VLog level
bool updated = false;
RefreshLogLevel();
int logLevel = _logLevel;
WitEditorUI.LayoutPopup(WitTexts.Texts.VLogLevelLabel, _logLevelNames, ref logLevel, ref updated);
if (updated)
{
SetLogLevel(logLevel);
}
var showTooltips = ShowTooltips;
WitEditorUI.LayoutToggle(new GUIContent(WitTexts.Texts.ShowTooltipsLabel), ref showTooltips, ref updated);
if (updated)
{
ShowTooltips = showTooltips;
}
#if VSDK_TELEMETRY_AVAILABLE && UNITY_EDITOR_WIN
var enableTelemetry = TelemetryConsentManager.ConsentProvided;
WitEditorUI.LayoutToggle(new GUIContent(WitTexts.Texts.TelemetryEnabledLabel), ref enableTelemetry, ref updated);
if (updated)
{
TelemetryConsentManager.ConsentProvided = enableTelemetry;
}
var telemetryLogLevel = _telemetryLogLevel;
WitEditorUI.LayoutPopup(WitTexts.Texts.TelemetryLevelLabel, _telemetryLogLevelNames, ref telemetryLogLevel, ref updated);
if (updated)
{
_telemetryLogLevel = Math.Max(0, telemetryLogLevel);
Telemetry.LogLevel = _telemetryLogLevels[_telemetryLogLevel];
}
#endif
}
private void DrawWitConfigurations()
{
// Server access token
GUILayout.BeginHorizontal();
bool updated = false;
WitEditorUI.LayoutPasswordField(WitTexts.SettingsServerTokenContent, ref serverToken, ref updated);
if (updated)
{
RelinkServerToken(false);
}
if (WitEditorUI.LayoutTextButton(WitTexts.Texts.SettingsRelinkButtonLabel))
{
RelinkServerToken(true);
}
if (WitEditorUI.LayoutTextButton(WitTexts.Texts.SettingsAddButtonLabel))
{
OpenConfigGenerationWindow();
}
GUILayout.EndHorizontal();
GUILayout.Space(WitStyles.ButtonMargin);
// Configuration select
base.LayoutContent();
// Update inspector if needed
if (witInspector == null || witConfiguration == null || witInspector.Configuration != witConfiguration)
{
SetWitEditor();
}
// Layout configuration inspector
if (witConfiguration && witInspector)
{
witInspector.OnInspectorGUI();
}
}
// Apply server token
private void RelinkServerToken(bool closeIfInvalid)
{
// Open Setup if Invalid
bool invalid = !WitConfigurationUtility.IsServerTokenValid(serverToken);
if (invalid)
{
// Clear if desired
if (string.IsNullOrEmpty(serverToken))
{
WitAuthUtility.ServerToken = serverToken;
}
// Open New & Close
if (closeIfInvalid)
{
// Generate new configuration
OpenConfigGenerationWindow();
// Close
Close();
}
return;
}
// Set valid server token
WitAuthUtility.ServerToken = serverToken;
WitConfigurationUtility.SetServerToken(serverToken);
}
private static void RefreshLogLevel()
{
if (_logLevelNames != null && _logLevelNames.Length == _logLevels.Length)
{
return;
}
List<string> logLevelOptions = new List<string>();
foreach (var level in _logLevels)
{
logLevelOptions.Add(level.ToString());
}
_logLevelNames = logLevelOptions.ToArray();
VLog.Init();
_logLevel = logLevelOptions.IndexOf(VLog.EditorLogLevel.ToString());
}
private void SetLogLevel(int newLevel)
{
_logLevel = Mathf.Clamp(0, newLevel, _logLevels.Length);
VLog.EditorLogLevel = _logLevels[_logLevel];
}
private static void InitializeTelemetryLevelOptions()
{
#if VSDK_TELEMETRY_AVAILABLE
_telemetryLogLevelNames = new string [_telemetryLogLevels.Length];
for (int i = 0; i < _telemetryLogLevelNames.Length; ++i)
{
_telemetryLogLevelNames[i] = _telemetryLogLevels[i].ToString();
}
var currentLevel = Telemetry.LogLevel.ToString();
for (int i = 0; i < _telemetryLogLevelNames.Length; ++i)
{
if (_telemetryLogLevelNames[i] == currentLevel)
{
_telemetryLogLevel = i;
return;
}
}
#endif
}
}
}
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 15c29f496a2443b4aa5e0ab283126a83
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- m_ViewDataDictionary: {instanceID: 0}
- witIcon: {fileID: 2800000, guid: d3b5ac4c8b01ef14a8a66d7e2a4991cc, type: 3}
- mainHeader: {fileID: 2800000, guid: 6a61dbb599169b64ca5584c8eebeb69e, type: 3}
- continueButton: {fileID: 2800000, guid: 2ed0be21c4a8bce4fadffab71d5b6e85, type: 3}
- witConfiguration: {instanceID: 0}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,101 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System.Globalization;
using System.Text.RegularExpressions;
using Meta.WitAi.Configuration;
using Meta.WitAi.Data.Configuration;
using UnityEditor;
using UnityEngine;
namespace Meta.WitAi.Data
{
public class WitDataCreation
{
const string PATH_KEY = "Facebook::Wit::ValuePath";
public static WitConfiguration FindDefaultWitConfig()
{
string[] guids = AssetDatabase.FindAssets("t:WitConfiguration");
if(guids.Length > 0)
{
string path = AssetDatabase.GUIDToAssetPath(guids[0]);
return AssetDatabase.LoadAssetAtPath<WitConfiguration>(path);
}
return null;
}
public static void AddWitToScene()
{
var witGo = new GameObject
{
name = "Wit"
};
var wit = witGo.AddComponent<Wit>();
var runtimeConfiguration = new WitRuntimeConfiguration()
{
witConfiguration = FindDefaultWitConfig()
};
wit.RuntimeConfiguration = runtimeConfiguration;
}
public static WitStringValue CreateStringValue(string path)
{
var asset = ScriptableObject.CreateInstance<WitStringValue>();
CreateValueAsset("Create String Value", path, asset);
return asset;
}
public static WitFloatValue CreateFloatValue(string path)
{
var asset = ScriptableObject.CreateInstance<WitFloatValue>();
CreateValueAsset("Create Float Value", path, asset);
return asset;
}
public static WitIntValue CreateIntValue(string path)
{
var asset = ScriptableObject.CreateInstance<WitIntValue>();
CreateValueAsset("Create Int Value", path, asset);
return asset;
}
private static void CreateValueAsset(string label, string path, WitValue asset)
{
asset.path = path;
var saveDir = EditorPrefs.GetString(PATH_KEY, Application.dataPath);
string name;
if (!string.IsNullOrEmpty(path))
{
name = Regex.Replace(path, @"\[[\]0-9]+", "");
name = name.Replace(".", " ");
name = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name);
}
else
{
name = asset.GetType().Name;
}
var filePath = EditorUtility.SaveFilePanelInProject(label, name, "asset", "Please select a location for your asset.");
if (!string.IsNullOrEmpty(filePath))
{
EditorPrefs.SetString(PATH_KEY, filePath);
if (filePath.StartsWith("Assets/StreamingAssets"))
{
EditorUtility.DisplayDialog("Restricted Folder","Cannot use StreamingAssets folder for saving normal assets. \nPlease select another folder inside Assets.", "OK");
return;
}
AssetDatabase.CreateAsset(asset, filePath);
AssetDatabase.SaveAssets();
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 40da7661eee64aaa81d3a0886ce34911
timeCreated: 1624319178