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,293 @@
/*
* 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.IO;
using System.Linq;
using System.Reflection;
using Meta.WitAi.Configuration;
using Meta.WitAi.Data.Info;
using UnityEngine;
using UnityEngine.Serialization;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Meta.WitAi.Data.Configuration
{
public class WitConfiguration : ScriptableObject, IWitRequestConfiguration
{
/// <summary>
/// Access token used in builds to make requests for data from Wit.ai
/// </summary>
[Tooltip("Access token used in builds to make requests for data from Wit.ai")]
[FormerlySerializedAs("clientAccessToken")]
[SerializeField] private string _clientAccessToken;
/// <summary>
/// Application info
/// </summary>
[FormerlySerializedAs("application")]
[SerializeField] private WitAppInfo _appInfo; //to be replaced by _configData
/// <summary>
/// Configuration data about the app.
/// </summary>
[SerializeField] private WitConfigurationAssetData[] _configData;
/// <summary>
/// Configuration id
/// </summary>
[FormerlySerializedAs("configId")]
[HideInInspector] [SerializeField] private string _configurationId;
[Tooltip("The number of milliseconds to wait before requests to Wit.ai will timeout")]
[SerializeField] public int timeoutMS = 10000;
/// <summary>
/// Configuration parameters to set up a custom endpoint for testing purposes and request forwarding. The default values here will work for most.
/// </summary>
[Tooltip("Configuration parameters to set up a custom endpoint for testing purposes and request forwarding. The default values here will work for most.")]
[SerializeField] public WitEndpointConfig endpointConfiguration = new WitEndpointConfig();
/// <summary>
/// True if this configuration should not show up in the demo list
/// </summary>
[SerializeField] public bool isDemoOnly;
/// <summary>
/// When set to true, will use Conduit to dispatch voice commands.
/// </summary>
[Tooltip("Conduit enables manifest-based dispatching to invoke callbacks with native types directly without requiring manual parsing.")]
[SerializeField] public bool useConduit = true;
/// <summary>
/// The path to the Conduit manifest.
/// </summary>
[SerializeField] private string _manifestLocalPath;
/// <summary>
/// The assemblies that we want to exclude from Conduit.
/// </summary>
[SerializeField] public List<string> excludedAssemblies = new List<string>
{
"Oculus.Voice.Demo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"Meta.WitAi.Samples, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
};
[Tooltip("When true, Conduit will attempt to match incoming requests by type when no exact matches are found. This increases tolerance but reduces runtime performance.")]
[SerializeField] public bool relaxedResolution;
/// <summary>
/// Safe access of local path
/// </summary>
public string ManifestLocalPath
{
get
{
#if UNITY_EDITOR
if (string.IsNullOrEmpty(_manifestLocalPath))
{
_manifestLocalPath = $"ConduitManifest-{Guid.NewGuid()}.json";
SaveConfiguration();
}
#endif
return _manifestLocalPath;
}
}
#if UNITY_EDITOR
/// <summary>
/// Returns manifest full editor path
/// </summary>
public string GetManifestEditorPath()
{
if (string.IsNullOrEmpty(_manifestLocalPath)) return string.Empty;
string lookup = Path.GetFileNameWithoutExtension(_manifestLocalPath);
string[] guids = UnityEditor.AssetDatabase.FindAssets(lookup);
if (guids != null && guids.Length > 0)
{
return UnityEditor.AssetDatabase.GUIDToAssetPath(guids[0]);
}
return string.Empty;
}
#endif
/// <summary>
/// Reset all data
/// </summary>
public void ResetData()
{
_configurationId = null;
_appInfo = new WitAppInfo();
endpointConfiguration = new WitEndpointConfig();
}
/// <summary>
/// Refreshes the individual data components of the configuration.
/// </summary>
public void UpdateDataAssets()
{
#if UNITY_EDITOR
RefreshPlugins();
#endif
foreach (WitConfigurationAssetData data in _configData)
{
data.Refresh(this);
}
}
// Logger invalid warnings
private const string INVALID_APP_ID_NO_CLIENT_TOKEN = "App Info Not Set - No Client Token";
private const string INVALID_APP_ID_WITH_CLIENT_TOKEN =
"App Info Not Set - Has Client Token";
public string GetLoggerAppId()
{
// Get application id
string applicationId = GetApplicationId();
if (String.IsNullOrEmpty(applicationId))
{
// NOTE: If a dev only provides a client token we may not have the application id.
string clientAccessToken = GetClientAccessToken();
if (!string.IsNullOrEmpty(clientAccessToken))
{
return INVALID_APP_ID_WITH_CLIENT_TOKEN;
}
return INVALID_APP_ID_NO_CLIENT_TOKEN;
}
return applicationId;
}
#region IWitRequestConfiguration
/// <summary>
/// Returns unique configuration guid
/// </summary>
public string GetConfigurationId()
{
#if UNITY_EDITOR
// Ensure configuration id is generated
if (string.IsNullOrEmpty(_configurationId))
{
_configurationId = Guid.NewGuid().ToString();
}
#endif
// Return configuration id
return _configurationId;
}
/// <summary>
/// Returns unique application id
/// </summary>
public string GetApplicationId() => _appInfo.id;
/// <summary>
/// Returns application info
/// </summary>
public WitAppInfo GetApplicationInfo() => _appInfo;
/// <summary>
/// Returns all the configuration data for this app.
/// </summary>
/// <returns></returns>
public WitConfigurationAssetData[] GetConfigData()
{
if (_configData == null)
{
_configData = Array.Empty<WitConfigurationAssetData>();
}
return _configData;
}
/// <summary>
/// Return endpoint override
/// </summary>
public IWitRequestEndpointInfo GetEndpointInfo() => endpointConfiguration;
/// <summary>
/// Returns client access token
/// </summary>
public string GetClientAccessToken()
{
return _clientAccessToken;
}
#if UNITY_EDITOR
/// <summary>
/// Editor only setter
/// </summary>
public void SetClientAccessToken(string newToken)
{
_clientAccessToken = newToken;
SaveConfiguration();
}
/// <summary>
/// Returns server access token (Editor Only)
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public string GetServerAccessToken()
{
return WitAuthUtility.GetAppServerToken(GetApplicationId());
}
/// <summary>
/// Set application info
/// </summary>
public void SetApplicationInfo(WitAppInfo newInfo)
{
_appInfo = newInfo;
SaveConfiguration();
}
/// <summary>
/// Saves the plugin-specific data for this WitConfiguration
/// </summary>
public void SetConfigData(WitConfigurationAssetData[] configData)
{
_configData = configData;
}
// Save this configuration asset
private void SaveConfiguration()
{
EditorUtility.SetDirty(this);
#if UNITY_2021_3_OR_NEWER
AssetDatabase.SaveAssetIfDirty(this);
#else
AssetDatabase.SaveAssets();
#endif
}
private void RefreshPlugins()
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
// Find all derived data types
List<Type> dataPlugins = typeof(WitConfigurationAssetData).GetSubclassTypes();
// Create instances of the types and register them
List<WitConfigurationAssetData> newConfigs = new List<WitConfigurationAssetData>();
var configurationAssetPath = AssetDatabase.GetAssetPath(this);
foreach (Type dataType in dataPlugins)
{
// Grab existing if present
var plugin = (WitConfigurationAssetData)AssetDatabase.LoadAssetAtPath(configurationAssetPath, dataType);
// Generate instance & add to asset
if (plugin == null)
{
plugin = (WitConfigurationAssetData)CreateInstance(dataType);
plugin.name = dataType.Name;
AssetDatabase.AddObjectToAsset(plugin, configurationAssetPath);
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(plugin));
plugin = (WitConfigurationAssetData)AssetDatabase.LoadAssetAtPath(configurationAssetPath, dataType);
}
newConfigs.Add(plugin);
}
SetConfigData(newConfigs.ToArray());
AssetDatabase.SaveAssets();
}
#endif
#endregion
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae5a46bda3295124c99b0e6537ac7252
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,107 @@
/*
* 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 UnityEngine.Serialization;
using Meta.WitAi.Data.Configuration;
namespace Meta.WitAi.Configuration
{
[Serializable]
public class WitEndpointConfig : IWitRequestEndpointInfo
{
/// <summary>
/// Customized uri scheme (Ex. https)
/// </summary>
[SerializeField] [FormerlySerializedAs("uriScheme")]
private string _uriScheme;
public string UriScheme => string.IsNullOrEmpty(_uriScheme) ? WitConstants.URI_SCHEME : _uriScheme;
/// <summary>
/// Customized host location (Ex. api.wit.ai)
/// </summary>
[SerializeField] [FormerlySerializedAs("authority")]
private string _authority;
public string Authority =>
string.IsNullOrEmpty(_authority) ? WitConstants.URI_AUTHORITY : _authority;
/// <summary>
/// Customized host port (Ex. api.wit.ai)
/// </summary>
[SerializeField] [FormerlySerializedAs("port")]
private int _port;
public int Port => _port <= 0 ? WitConstants.URI_DEFAULT_PORT : _port;
/// <summary>
/// API version to be used for this endpoint. Defaults to sdk default version
/// </summary>
[SerializeField] [FormerlySerializedAs("witApiVersion")]
private string _witApiVersion;
public string WitApiVersion => string.IsNullOrEmpty(_witApiVersion)
? WitConstants.API_VERSION
: _witApiVersion;
/// <summary>
/// Endpoint used for text based voice command. Defaults to 'message'
/// </summary>
[SerializeField] [FormerlySerializedAs("message")]
private string _message;
public string Message =>
string.IsNullOrEmpty(_message) ? WitConstants.ENDPOINT_MESSAGE : _message;
/// <summary>
/// Endpoint used for audio based voice command. Defaults to 'speech'
/// </summary>
[SerializeField] [FormerlySerializedAs("speech")]
private string _speech;
public string Speech =>
string.IsNullOrEmpty(_speech) ? WitConstants.ENDPOINT_SPEECH : _speech;
/// <summary>
/// Endpoint used for audio based transcription. Defaults to 'dictation'
/// </summary>
[SerializeField] [FormerlySerializedAs("dictation")]
private string _dictation;
public string Dictation => string.IsNullOrEmpty(_dictation) ? WitConstants.ENDPOINT_DICTATION : _dictation;
/// <summary>
/// Endpoint used for Text-To-Speech. Defaults to 'synthesize'
/// </summary>
[SerializeField]
private string _synthesize;
public string Synthesize => string.IsNullOrEmpty(_synthesize) ? WitConstants.ENDPOINT_TTS : _synthesize;
/// <summary>
/// Endpoint used for Composer text requests. Defaults to 'event'
/// </summary>
[SerializeField]
private string _event;
public string Event => string.IsNullOrEmpty(_event) ? WitConstants.ENDPOINT_COMPOSER_MESSAGE : _event;
/// <summary>
/// Endpoint used for Composer audio requests. Defaults to 'converse'
/// </summary>
[SerializeField]
private string _converse;
public string Converse => string.IsNullOrEmpty(_converse) ? WitConstants.ENDPOINT_COMPOSER_SPEECH : _converse;
// Default endpoint data
private static WitEndpointConfig defaultEndpointConfig = new WitEndpointConfig();
/// <summary>
/// Generates a configuration using a preset if possible
/// </summary>
public static WitEndpointConfig GetEndpointConfig(WitConfiguration witConfig)
{
return witConfig && null != witConfig.endpointConfiguration
? witConfig.endpointConfiguration
: defaultEndpointConfig;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 61a0415bfdfa4d64e89801fbc0b30ec7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,60 @@
/*
* 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.Json;
using Meta.WitAi.Requests;
using Meta.WitAi.Interfaces;
namespace Meta.WitAi.Configuration
{
public class WitRequestOptions : VoiceServiceRequestOptions
{
/// <summary>
/// An interface that provides a list of entities that should be used for nlu resolution.
/// </summary>
public IDynamicEntitiesProvider dynamicEntities;
/// <summary>
/// The maximum number of intent matches to return
/// </summary>
public int nBestIntents = -1;
/// <summary>
/// The tag for snapshot
/// </summary>
public string tag;
/// <summary>
/// Formerly used for request id
/// </summary>
[Obsolete("Use 'RequestId' property instead")] [JsonIgnore]
public string requestID => RequestId;
/// <summary>
/// Callback for completion
/// </summary>
public Action<WitRequest> onResponse;
// Get json string. Used to get the payload for PI.
// PI will reparse these parameters and construct it's own request.
public string ToJsonString()
{
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["nBestIntents"] = nBestIntents.ToString();
parameters["tag"] = tag;
parameters["requestID"] = RequestId;
foreach (var key in QueryParams.Keys)
{
parameters[key] = QueryParams[key];
}
return JsonConvert.SerializeObject(parameters);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a6834fd3c55fb41a1885302e6043f5d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,79 @@
/*
* 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.Data.Configuration;
using Meta.WitAi.Interfaces;
using Meta.WitAi.Utilities;
using UnityEngine;
using UnityEngine.Serialization;
namespace Meta.WitAi.Configuration
{
[Serializable]
public class WitRuntimeConfiguration
{
[Tooltip("Configuration for the application used in this instance of Wit.ai services")]
[SerializeField]
public WitConfiguration witConfiguration;
[Header("Keepalive")]
[Tooltip("The minimum volume from the mic needed to keep the activation alive")]
[SerializeField]
public float minKeepAliveVolume = .0005f;
[FormerlySerializedAs("minKeepAliveTime")]
[Tooltip(
"The amount of time in seconds an activation will be kept open after volume is under the keep alive threshold")]
[SerializeField]
[DynamicRange("RecordingTimeRange")]
public float minKeepAliveTimeInSeconds = 2f;
[FormerlySerializedAs("minTranscriptionKeepAliveTime")]
[Tooltip(
"The amount of time in seconds an activation will be kept open after words have been detected in the live transcription")]
[SerializeField]
[DynamicRange("RecordingTimeRange")]
public float minTranscriptionKeepAliveTimeInSeconds = 1f;
[Tooltip("The maximum amount of time in seconds the mic will stay active")]
[SerializeField]
[DynamicRange("RecordingTimeRange")]
public float maxRecordingTime = 20;
protected virtual Vector2 RecordingTimeRange => new Vector2(0, 20);
[Header("Sound Activation")]
[Tooltip("The minimum volume level needed to be heard to start collecting data from the audio source.")]
[SerializeField] public float soundWakeThreshold = .0005f;
[Tooltip("The length of the individual samples read from the audio source")]
[Range(10, 500)] [SerializeField] public int sampleLengthInMs = 10;
[Tooltip("The total audio data that should be buffered for lookback purposes on sound based activations.")]
[SerializeField] public float micBufferLengthInSeconds = 1;
[Tooltip("The maximum amount of concurrent requests that can occur")]
[Range(1, 10)] [SerializeField] public int maxConcurrentRequests = 5;
[Header("Custom Transcription")]
[Tooltip(
"If true, the audio recorded in the activation will be sent to Wit.ai for processing. If a custom transcription provider is set and this is false, only the transcription will be sent to Wit.ai for processing")]
[SerializeField]
public bool sendAudioToWit = true;
[Tooltip("A custom provider that returns text to be used for nlu processing on activation instead of sending audio.")]
[SerializeField] public CustomTranscriptionProvider customTranscriptionProvider;
[Tooltip("If always record is set the mic will fill the mic data buffer as long as the component is enabled in the scene.")]
public bool alwaysRecord;
[Tooltip("The preferred number of seconds to offset from the time the activation happens. A negative value here could help to catch any words that may have been cut off at the beginning of an activation (assuming input is already being read into the buffer)")]
public float preferredActivationOffset = -.5f;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bd8d40c9f75b44b5940fcc21769d6af0
timeCreated: 1629397017