ai.muna.muna 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/Editor/Build/AndroidBuildHandler.cs +96 -0
  2. package/Editor/Build/AndroidBuildHandler.cs.meta +11 -0
  3. package/Editor/Build/BuildHandler.cs +128 -0
  4. package/Editor/Build/BuildHandler.cs.meta +11 -0
  5. package/Editor/Build/LinuxBuildHandler.cs +26 -0
  6. package/Editor/Build/LinuxBuildHandler.cs.meta +11 -0
  7. package/Editor/Build/WebGLBuildHandler.cs +69 -0
  8. package/Editor/Build/WebGLBuildHandler.cs.meta +11 -0
  9. package/Editor/Build/WindowsBuildHandler.cs +24 -0
  10. package/Editor/Build/WindowsBuildHandler.cs.meta +11 -0
  11. package/Editor/Build/iOSBuildHandler.cs +119 -0
  12. package/Editor/Build/iOSBuildHandler.cs.meta +11 -0
  13. package/Editor/Build/macOSBuildHandler.cs +133 -0
  14. package/Editor/Build/macOSBuildHandler.cs.meta +11 -0
  15. package/Editor/Build.meta +8 -0
  16. package/Editor/Muna.Editor.asmdef +18 -0
  17. package/Editor/Muna.Editor.asmdef.meta +7 -0
  18. package/Editor/MunaMenu.cs +32 -0
  19. package/Editor/MunaMenu.cs.meta +11 -0
  20. package/Editor/MunaProjectSettings.cs +43 -0
  21. package/Editor/MunaProjectSettings.cs.meta +11 -0
  22. package/Editor/MunaSettingsProvider.cs +27 -0
  23. package/Editor/MunaSettingsProvider.cs.meta +11 -0
  24. package/Editor.meta +8 -0
  25. package/LICENSE +201 -0
  26. package/LICENSE.meta +7 -0
  27. package/Plugins/Android/Function.aar +0 -0
  28. package/Plugins/Android/Function.aar.meta +32 -0
  29. package/Plugins/Android.meta +8 -0
  30. package/Plugins/Linux/arm64/libFunction.so +0 -0
  31. package/Plugins/Linux/arm64/libFunction.so.meta +62 -0
  32. package/Plugins/Linux/arm64.meta +8 -0
  33. package/Plugins/Linux/x86_64/libFunction.so +0 -0
  34. package/Plugins/Linux/x86_64/libFunction.so.meta +82 -0
  35. package/Plugins/Linux/x86_64.meta +8 -0
  36. package/Plugins/Linux.meta +8 -0
  37. package/Plugins/Web/libFunction.a +0 -0
  38. package/Plugins/Web/libFunction.a.meta +87 -0
  39. package/Plugins/Web.meta +8 -0
  40. package/Plugins/Windows/arm64/Function.dll +0 -0
  41. package/Plugins/Windows/arm64/Function.dll.meta +58 -0
  42. package/Plugins/Windows/arm64.meta +8 -0
  43. package/Plugins/Windows/x86_64/Function.dll +0 -0
  44. package/Plugins/Windows/x86_64/Function.dll.meta +82 -0
  45. package/Plugins/Windows/x86_64.meta +8 -0
  46. package/Plugins/Windows.meta +8 -0
  47. package/Plugins/iOS/Function.xcframework/Info.plist +75 -0
  48. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Function +0 -0
  49. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Headers/FXNConfiguration.h +313 -0
  50. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Headers/FXNPrediction.h +165 -0
  51. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Headers/FXNPredictionStream.h +63 -0
  52. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Headers/FXNPredictor.h +108 -0
  53. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Headers/FXNStatus.h +42 -0
  54. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Headers/FXNValue.h +395 -0
  55. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Headers/FXNValueMap.h +148 -0
  56. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Headers/FXNVersion.h +26 -0
  57. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Headers/Function.h +18 -0
  58. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Info.plist +0 -0
  59. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/Modules/module.modulemap +6 -0
  60. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/PrivacyInfo.xcprivacy +36 -0
  61. package/Plugins/iOS/Function.xcframework/ios-arm64/Function.framework/_CodeSignature/CodeResources +223 -0
  62. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Function +0 -0
  63. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Headers/FXNConfiguration.h +313 -0
  64. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Headers/FXNPrediction.h +165 -0
  65. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Headers/FXNPredictionStream.h +63 -0
  66. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Headers/FXNPredictor.h +108 -0
  67. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Headers/FXNStatus.h +42 -0
  68. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Headers/FXNValue.h +395 -0
  69. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Headers/FXNValueMap.h +148 -0
  70. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Headers/FXNVersion.h +26 -0
  71. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Headers/Function.h +18 -0
  72. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Info.plist +0 -0
  73. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/Modules/module.modulemap +6 -0
  74. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/PrivacyInfo.xcprivacy +36 -0
  75. package/Plugins/iOS/Function.xcframework/ios-arm64_x86_64-simulator/Function.framework/_CodeSignature/CodeResources +223 -0
  76. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Function +0 -0
  77. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Headers/FXNConfiguration.h +313 -0
  78. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Headers/FXNPrediction.h +165 -0
  79. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Headers/FXNPredictionStream.h +63 -0
  80. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Headers/FXNPredictor.h +108 -0
  81. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Headers/FXNStatus.h +42 -0
  82. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Headers/FXNValue.h +395 -0
  83. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Headers/FXNValueMap.h +148 -0
  84. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Headers/FXNVersion.h +26 -0
  85. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Headers/Function.h +18 -0
  86. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Info.plist +0 -0
  87. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/Modules/module.modulemap +6 -0
  88. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/PrivacyInfo.xcprivacy +36 -0
  89. package/Plugins/iOS/Function.xcframework/xros-arm64/Function.framework/_CodeSignature/CodeResources +223 -0
  90. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Function +0 -0
  91. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Headers/FXNConfiguration.h +313 -0
  92. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Headers/FXNPrediction.h +165 -0
  93. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Headers/FXNPredictionStream.h +63 -0
  94. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Headers/FXNPredictor.h +108 -0
  95. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Headers/FXNStatus.h +42 -0
  96. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Headers/FXNValue.h +395 -0
  97. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Headers/FXNValueMap.h +148 -0
  98. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Headers/FXNVersion.h +26 -0
  99. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Headers/Function.h +18 -0
  100. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Info.plist +0 -0
  101. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/Modules/module.modulemap +6 -0
  102. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/PrivacyInfo.xcprivacy +36 -0
  103. package/Plugins/iOS/Function.xcframework/xros-arm64_x86_64-simulator/Function.framework/_CodeSignature/CodeResources +223 -0
  104. package/Plugins/iOS/Function.xcframework.meta +83 -0
  105. package/Plugins/iOS.meta +8 -0
  106. package/Plugins/macOS/Function.dylib +0 -0
  107. package/Plugins/macOS/Function.dylib.meta +82 -0
  108. package/Plugins/macOS.meta +8 -0
  109. package/Plugins.meta +8 -0
  110. package/README.md +79 -0
  111. package/README.md.meta +7 -0
  112. package/Runtime/API/DotNetClient.cs +106 -0
  113. package/Runtime/API/DotNetClient.cs.meta +11 -0
  114. package/Runtime/API/MunaClient.cs +96 -0
  115. package/Runtime/API/MunaClient.cs.meta +11 -0
  116. package/Runtime/API.meta +8 -0
  117. package/Runtime/Beta/BetaClient.cs +33 -0
  118. package/Runtime/Beta/BetaClient.cs.meta +11 -0
  119. package/Runtime/Beta/PredictionService.cs +32 -0
  120. package/Runtime/Beta/PredictionService.cs.meta +11 -0
  121. package/Runtime/Beta/RemoteAcceleration.cs +38 -0
  122. package/Runtime/Beta/RemoteAcceleration.cs.meta +11 -0
  123. package/Runtime/Beta/RemotePredictionService.cs +187 -0
  124. package/Runtime/Beta/RemotePredictionService.cs.meta +11 -0
  125. package/Runtime/Beta/Value.cs +92 -0
  126. package/Runtime/Beta/Value.cs.meta +11 -0
  127. package/Runtime/Beta.meta +8 -0
  128. package/Runtime/C/Configuration.cs +139 -0
  129. package/Runtime/C/Configuration.cs.meta +11 -0
  130. package/Runtime/C/Function.cs +294 -0
  131. package/Runtime/C/Function.cs.meta +11 -0
  132. package/Runtime/C/Prediction.cs +70 -0
  133. package/Runtime/C/Prediction.cs.meta +11 -0
  134. package/Runtime/C/PredictionStream.cs +36 -0
  135. package/Runtime/C/PredictionStream.cs.meta +11 -0
  136. package/Runtime/C/Predictor.cs +42 -0
  137. package/Runtime/C/Predictor.cs.meta +11 -0
  138. package/Runtime/C/Value.cs +194 -0
  139. package/Runtime/C/Value.cs.meta +11 -0
  140. package/Runtime/C/ValueMap.cs +50 -0
  141. package/Runtime/C/ValueMap.cs.meta +11 -0
  142. package/Runtime/C.meta +8 -0
  143. package/Runtime/Muna.Runtime.asmdef +27 -0
  144. package/Runtime/Muna.Runtime.asmdef.meta +7 -0
  145. package/Runtime/Muna.cs +109 -0
  146. package/Runtime/Muna.cs.meta +11 -0
  147. package/Runtime/Services/Prediction.cs +247 -0
  148. package/Runtime/Services/Prediction.cs.meta +11 -0
  149. package/Runtime/Services/Predictor.cs +44 -0
  150. package/Runtime/Services/Predictor.cs.meta +11 -0
  151. package/Runtime/Services/User.cs +43 -0
  152. package/Runtime/Services/User.cs.meta +11 -0
  153. package/Runtime/Services.meta +8 -0
  154. package/Runtime/Types/Dtype.cs +118 -0
  155. package/Runtime/Types/Dtype.cs.meta +11 -0
  156. package/Runtime/Types/Image.cs +93 -0
  157. package/Runtime/Types/Image.cs.meta +11 -0
  158. package/Runtime/Types/Prediction.cs +113 -0
  159. package/Runtime/Types/Prediction.cs.meta +11 -0
  160. package/Runtime/Types/Predictor.cs +193 -0
  161. package/Runtime/Types/Predictor.cs.meta +11 -0
  162. package/Runtime/Types/Tensor.cs +58 -0
  163. package/Runtime/Types/Tensor.cs.meta +11 -0
  164. package/Runtime/Types/User.cs +54 -0
  165. package/Runtime/Types/User.cs.meta +11 -0
  166. package/Runtime/Types.meta +8 -0
  167. package/Runtime.meta +8 -0
  168. package/Unity/API/PredictionCacheClient.cs +144 -0
  169. package/Unity/API/PredictionCacheClient.cs.meta +11 -0
  170. package/Unity/API/UnityClient.cs +147 -0
  171. package/Unity/API/UnityClient.cs.meta +11 -0
  172. package/Unity/API.meta +8 -0
  173. package/Unity/Internal/MunaSettings.cs +59 -0
  174. package/Unity/Internal/MunaSettings.cs.meta +11 -0
  175. package/Unity/Internal.meta +8 -0
  176. package/Unity/Muna.Unity.asmdef +29 -0
  177. package/Unity/Muna.Unity.asmdef.meta +7 -0
  178. package/Unity/MunaUnity.cs +130 -0
  179. package/Unity/MunaUnity.cs.meta +11 -0
  180. package/Unity/Types/CachedPrediction.cs +36 -0
  181. package/Unity/Types/CachedPrediction.cs.meta +11 -0
  182. package/Unity/Types.meta +8 -0
  183. package/Unity.meta +8 -0
  184. package/package.json +38 -0
  185. package/package.json.meta +7 -0
@@ -0,0 +1,96 @@
1
+ /*
2
+ * Muna
3
+ * Copyright © 2025 NatML Inc. All rights reserved.
4
+ */
5
+
6
+ namespace Muna.Editor.Build {
7
+
8
+ using System;
9
+ using System.Collections.Generic;
10
+ using System.IO;
11
+ using System.Linq;
12
+ using System.Threading.Tasks;
13
+ using UnityEngine;
14
+ using UnityEditor;
15
+ using UnityEditor.Android;
16
+ using UnityEditor.Build.Reporting;
17
+ using API;
18
+ using Services;
19
+ using MunaSettings = Internal.MunaSettings;
20
+
21
+ internal sealed class AndroidBuildHandler : BuildHandler, IPostGenerateGradleAndroidProject {
22
+
23
+ private static List<CachedPrediction> cache;
24
+ private static Dictionary<AndroidArchitecture, string> ArchToClientId = new() {
25
+ [AndroidArchitecture.ARMv7] = @"android-armeabi-v7a",
26
+ [AndroidArchitecture.ARM64] = @"android-arm64-v8a",
27
+ };
28
+
29
+ protected override BuildTarget[] targets => new[] {
30
+ BuildTarget.Android
31
+ };
32
+
33
+ protected override MunaSettings CreateSettings(BuildReport report) {
34
+ var projectSettings = MunaProjectSettings.instance;
35
+ var settings = MunaSettings.Create(projectSettings.accessKey);
36
+ var embeds = GetEmbeds();
37
+ var targets = ArchToClientId
38
+ .Where(pair => PlayerSettings.Android.targetArchitectures.HasFlag(pair.Key))
39
+ .Select(pair => pair.Value)
40
+ .ToArray();
41
+ var cache = embeds
42
+ .SelectMany(embed => {
43
+ var client = new DotNetClient(embed.url, embed.accessKey);
44
+ var muna = new Muna(client);
45
+ var predictions = targets.SelectMany(target => embed.tags.Select(tag => {
46
+ try {
47
+ var prediction = Task.Run(() => muna.Predictions.Create(
48
+ tag,
49
+ clientId: target,
50
+ configurationId: @""
51
+ )).Result;
52
+ return new CachedPrediction(prediction, target);
53
+ } catch (AggregateException ex) {
54
+ Debug.LogWarning($"Muna: Failed to embed {tag} predictor with error: {ex.InnerException}. Predictions with this predictor will likely fail at runtime.");
55
+ return null;
56
+ }
57
+ }));
58
+ return predictions;
59
+ })
60
+ .Where(pred => pred != null)
61
+ .ToList();
62
+ settings.cache = cache;
63
+ AndroidBuildHandler.cache = cache;
64
+ return settings;
65
+ }
66
+
67
+ void IPostGenerateGradleAndroidProject.OnPostGenerateGradleAndroidProject(string projectPath) {
68
+ if (cache == null)
69
+ return;
70
+ foreach (var prediction in cache) {
71
+ // Check
72
+ var arch = prediction.clientId.Replace("android-", string.Empty).Replace(":", string.Empty);
73
+ var libDir = Path.Combine(projectPath, @"src", @"main", @"jniLibs", arch);
74
+ if (!Directory.Exists(libDir))
75
+ continue;
76
+ // Fetch resources
77
+ var client = new DotNetClient(Muna.URL);
78
+ foreach (var resource in prediction.resources) {
79
+ try {
80
+ if (resource.type != @"dso")
81
+ continue;
82
+ var baseName = Path.GetFileName(PredictionService.GetResourcePath(resource, libDir));
83
+ var libName = $"lib{baseName}.so";
84
+ var path = Path.Combine(libDir, libName);
85
+ using var dsoStream = Task.Run(() => client.Download(resource.url)).Result;
86
+ using var fileStream = File.Create(path);
87
+ dsoStream.CopyTo(fileStream);
88
+ } catch (AggregateException ex) {
89
+ Debug.LogWarning($"Muna: Failed to embed prediction resource for {prediction.tag} predictor with error: {ex.InnerException}. Predictions with this predictor will likely fail at runtime.");
90
+ }
91
+ }
92
+ }
93
+ cache = null;
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: d955e4a0d7d1d47c8b3c044ee2545020
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,128 @@
1
+ /*
2
+ * Muna
3
+ * Copyright © 2025 NatML Inc. All rights reserved.
4
+ */
5
+
6
+ #nullable enable
7
+
8
+ using MunaClient = Muna.Muna;
9
+ using EmbedAttribute = Muna.Muna.EmbedAttribute;
10
+
11
+ namespace Muna.Editor.Build {
12
+
13
+ using System;
14
+ using System.Collections.Generic;
15
+ using System.IO;
16
+ using System.Linq;
17
+ using System.Reflection;
18
+ using UnityEditor;
19
+ using UnityEditor.Build;
20
+ using UnityEditor.Build.Reporting;
21
+ using UnityEngine;
22
+ using Internal;
23
+
24
+ internal abstract class BuildHandler : IPreprocessBuildWithReport {
25
+
26
+ #region --Client API--
27
+ internal struct Embed {
28
+ public string url;
29
+ public string? accessKey;
30
+ public string[] tags;
31
+ }
32
+
33
+ protected abstract BuildTarget[] targets { get; }
34
+ public virtual int callbackOrder => -1_000_000; // run very early, but not too early ;)
35
+
36
+ protected abstract MunaSettings CreateSettings(BuildReport report);
37
+
38
+ internal static Embed[] GetEmbeds() {
39
+ var assemblies = AppDomain.CurrentDomain.GetAssemblies();
40
+ var types = assemblies.SelectMany(assembly => assembly.GetTypes()).ToArray();
41
+ var defaultEmbeds = types
42
+ .SelectMany(type => Attribute.GetCustomAttributes(type, typeof(EmbedAttribute)))
43
+ .Cast<EmbedAttribute>()
44
+ .Select(embed => new Embed {
45
+ url = MunaClient.URL,
46
+ accessKey = MunaProjectSettings.instance.accessKey,
47
+ tags = embed.tags
48
+ })
49
+ .ToArray();
50
+ var customEmbeds = types
51
+ .SelectMany(type => { // thanks Jamie!
52
+ try {
53
+ return type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
54
+ }
55
+ catch (Exception ex) {
56
+ Debug.LogWarning($"Muna: Failed to inspect type {type} for predictor embeds with exception: {ex.Message}. Predictions might fail at runtime.");
57
+ return new PropertyInfo[0];
58
+ }
59
+ })
60
+ .Where(property =>
61
+ Attribute.IsDefined(property, typeof(EmbedAttribute)) &&
62
+ property.PropertyType == typeof(MunaClient)
63
+ )
64
+ .Select(property => {
65
+ var attribute = property.GetCustomAttribute<EmbedAttribute>();
66
+ var getter = CreateDelegateForProperty<MunaClient>(property);
67
+ var muna = getter!();
68
+ return new Embed {
69
+ url = muna.client.url,
70
+ accessKey = muna.client.accessKey,
71
+ tags = attribute.tags
72
+ };
73
+ })
74
+ .ToArray();
75
+ return Enumerable.Concat(defaultEmbeds, customEmbeds).ToArray();
76
+ }
77
+ #endregion
78
+
79
+
80
+ #region --Operations--
81
+ protected const string CachePath = @"Assets/__MUNA_DELETE_THIS__";
82
+
83
+ void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report) {
84
+ if (!targets.Contains(report.summary.platform))
85
+ return;
86
+ var settings = CreateSettings(report);
87
+ EditorApplication.update += FailureListener;
88
+ ClearSettings();
89
+ EmbedSettings(settings);
90
+ }
91
+
92
+ private void FailureListener() {
93
+ if (BuildPipeline.isBuildingPlayer)
94
+ return;
95
+ ClearSettings();
96
+ EditorApplication.update -= FailureListener;
97
+ }
98
+ #endregion
99
+
100
+
101
+ #region --Utilities--
102
+
103
+ private static void EmbedSettings(MunaSettings settings) {
104
+ Directory.CreateDirectory(CachePath);
105
+ AssetDatabase.CreateAsset(settings, $"{CachePath}/Muna.asset");
106
+ var assets = PlayerSettings.GetPreloadedAssets()?.ToList() ?? new List<UnityEngine.Object>();
107
+ assets.Add(settings);
108
+ PlayerSettings.SetPreloadedAssets(assets.ToArray());
109
+ }
110
+
111
+ private static void ClearSettings() {
112
+ var assets = PlayerSettings.GetPreloadedAssets()?.ToList();
113
+ if (assets != null) {
114
+ assets.RemoveAll(asset => asset && asset.GetType() == typeof(MunaSettings));
115
+ PlayerSettings.SetPreloadedAssets(assets.ToArray());
116
+ }
117
+ AssetDatabase.DeleteAsset(CachePath);
118
+ }
119
+
120
+ private static Func<T>? CreateDelegateForProperty<T>(PropertyInfo property) {
121
+ var getter = property.GetGetMethod(true);
122
+ return getter != null && getter.ReturnType == typeof(T) ?
123
+ (Func<T>)Delegate.CreateDelegate(typeof(Func<T>), getter) :
124
+ null;
125
+ }
126
+ #endregion
127
+ }
128
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 9023dbd8ca47845ab831ee70a0406629
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Muna
3
+ * Copyright © 2025 NatML Inc. All rights reserved.
4
+ */
5
+
6
+ namespace Muna.Editor.Build {
7
+
8
+ using UnityEditor;
9
+ using UnityEditor.Build.Reporting;
10
+ using MunaSettings = Internal.MunaSettings;
11
+
12
+ internal sealed class LinuxBuildHandler : BuildHandler {
13
+
14
+ protected override BuildTarget[] targets => new [] {
15
+ BuildTarget.StandaloneLinux64,
16
+ BuildTarget.LinuxHeadlessSimulation,
17
+ BuildTarget.EmbeddedLinux,
18
+ };
19
+
20
+ protected override MunaSettings CreateSettings(BuildReport report) {
21
+ var projectSettings = MunaProjectSettings.instance;
22
+ var settings = MunaSettings.Create(projectSettings.accessKey);
23
+ return settings;
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 36715cfd2cebf432d9aaeb1578b48800
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,69 @@
1
+ /*
2
+ * Muna
3
+ * Copyright © 2025 NatML Inc. All rights reserved.
4
+ */
5
+
6
+ #nullable enable
7
+
8
+ namespace Muna.Editor.Build {
9
+
10
+ using System.Collections.Generic;
11
+ using System.IO;
12
+ using System.Text.RegularExpressions;
13
+ using UnityEditor;
14
+ using UnityEditor.Build.Reporting;
15
+ using MunaSettings = Internal.MunaSettings;
16
+
17
+ internal sealed class WebGLBuildHandler : BuildHandler {
18
+
19
+ protected override BuildTarget[] targets => new[] {
20
+ BuildTarget.WebGL
21
+ };
22
+ private static string[] EM_ARGS => new [] {
23
+ @"-Wl,-uFXN_WEBGL_INIT",
24
+ @"-lembind",
25
+ @"-sEXTRA_EXPORTED_RUNTIME_METHODS=FS",
26
+ };
27
+
28
+ protected override MunaSettings CreateSettings(BuildReport report) {
29
+ var configPath = Path.Combine(GetEmscriptenPath(), @"tools", @"config.py");
30
+ if (File.Exists(configPath)) {
31
+ var config = File.ReadAllText(configPath).TrimEnd();
32
+ if (!Regex.IsMatch(config, @"FROZEN_CACHE\s*=\s*False\s*$", RegexOptions.Multiline))
33
+ File.WriteAllText(configPath, config + "\nFROZEN_CACHE = False");
34
+ }
35
+ PlayerSettings.WebGL.emscriptenArgs = GetEmscriptenArgs();
36
+ var projectSettings = MunaProjectSettings.instance;
37
+ var settings = MunaSettings.Create(projectSettings.accessKey);
38
+ return settings;
39
+ }
40
+
41
+ private static string GetEmscriptenArgs() {
42
+ var cleanedArgs = Regex.Replace(
43
+ PlayerSettings.WebGL.emscriptenArgs,
44
+ @"-Wl,-uFXN_WEBGL_PUSH.*?-Wl,-uFXN_WEBGL_POP",
45
+ string.Empty,
46
+ RegexOptions.Singleline
47
+ ).Split(' ');
48
+ var args = new List<string>();
49
+ args.AddRange(cleanedArgs);
50
+ args.Add(@"-Wl,-uFXN_WEBGL_PUSH");
51
+ args.AddRange(EM_ARGS);
52
+ args.Add(@"-Wl,-uFXN_WEBGL_POP");
53
+ return string.Join(@" ", args);
54
+ }
55
+
56
+ private static string GetEmscriptenPath() {
57
+ var rootDir = Path.GetDirectoryName(EditorApplication.applicationPath);
58
+ var emccDir = Path.Combine(
59
+ rootDir,
60
+ @"PlaybackEngines",
61
+ @"WebGLSupport",
62
+ @"BuildTools",
63
+ @"Emscripten",
64
+ @"emscripten"
65
+ );
66
+ return emccDir;
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: eb43a333834634ec381f03234637d1c7
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Muna
3
+ * Copyright © 2025 NatML Inc. All rights reserved.
4
+ */
5
+
6
+ namespace Muna.Editor.Build {
7
+
8
+ using UnityEditor;
9
+ using UnityEditor.Build.Reporting;
10
+ using MunaSettings = Internal.MunaSettings;
11
+
12
+ internal sealed class WindowsBuildHandler : BuildHandler {
13
+
14
+ protected override BuildTarget[] targets => new[] {
15
+ BuildTarget.StandaloneWindows64
16
+ };
17
+
18
+ protected override MunaSettings CreateSettings(BuildReport report) {
19
+ var projectSettings = MunaProjectSettings.instance;
20
+ var settings = MunaSettings.Create(projectSettings.accessKey);
21
+ return settings;
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 29c1d180e82014b5fb86b7a3cf6a2b18
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,119 @@
1
+ /*
2
+ * Muna
3
+ * Copyright © 2025 NatML Inc. All rights reserved.
4
+ */
5
+
6
+ namespace Muna.Editor.Build {
7
+
8
+ using System;
9
+ using System.Collections.Generic;
10
+ using System.IO;
11
+ using System.IO.Compression;
12
+ using System.Linq;
13
+ using System.Threading.Tasks;
14
+ using UnityEngine;
15
+ using UnityEditor;
16
+ using UnityEditor.Build;
17
+ using UnityEditor.Build.Reporting;
18
+ using API;
19
+ using MunaSettings = Internal.MunaSettings;
20
+
21
+ #if UNITY_IOS || UNITY_VISIONOS
22
+ using UnityEditor.iOS.Xcode;
23
+ using UnityEditor.iOS.Xcode.Extensions;
24
+ #endif
25
+
26
+ internal sealed class iOSBuildHandler : BuildHandler, IPostprocessBuildWithReport {
27
+
28
+ private List<CachedPrediction> cache;
29
+ private static readonly Dictionary<BuildTarget, string> ClientIds = new () {
30
+ [BuildTarget.iOS] = @"ios-arm64",
31
+ [BuildTarget.VisionOS] = @"visionos-arm64"
32
+ };
33
+
34
+ protected override BuildTarget[] targets => ClientIds.Keys.ToArray();
35
+
36
+ protected override MunaSettings CreateSettings(BuildReport report) {
37
+ var projectSettings = MunaProjectSettings.instance;
38
+ var settings = MunaSettings.Create(projectSettings.accessKey);
39
+ var embeds = GetEmbeds();
40
+ var cache = new List<CachedPrediction>();
41
+ var clientId = ClientIds[report.summary.platform];
42
+ foreach (var embed in embeds) {
43
+ var client = new DotNetClient(embed.url, embed.accessKey);
44
+ var muna = new Muna(client);
45
+ var predictions = embed.tags
46
+ .Select(tag => {
47
+ try {
48
+ var prediction = Task.Run(() => muna.Predictions.Create(
49
+ tag,
50
+ clientId: clientId,
51
+ configurationId: @""
52
+ )).Result;
53
+ return new CachedPrediction(prediction, clientId);
54
+ } catch (AggregateException ex) {
55
+ Debug.LogWarning($"Muna: Failed to embed {tag} predictor with error: {ex.InnerException}. Predictions with this predictor will likely fail at runtime.");
56
+ return null;
57
+ }
58
+ })
59
+ .Where(pred => pred != null)
60
+ .ToArray();
61
+ cache.AddRange(predictions);
62
+ }
63
+ settings.cache = cache;
64
+ this.cache = cache;
65
+ return settings;
66
+ }
67
+
68
+ void IPostprocessBuildWithReport.OnPostprocessBuild(BuildReport report) {
69
+ if (!targets.Contains(report.summary.platform))
70
+ return;
71
+ if (cache == null)
72
+ return;
73
+ var frameworkDir = Path.Combine(report.summary.outputPath, @"Frameworks", @"Muna");
74
+ Directory.CreateDirectory(frameworkDir);
75
+ var client = new DotNetClient(Muna.URL);
76
+ var frameworks = new List<string>();
77
+ foreach (var prediction in cache)
78
+ foreach (var resource in prediction.resources) {
79
+ try {
80
+ if (resource.type != @"dso")
81
+ continue;
82
+ var dsoPath = Path.GetTempFileName();
83
+ {
84
+ using var dsoStream = Task.Run(() => client.Download(resource.url)).Result;
85
+ using var fileStream = File.Create(dsoPath);
86
+ dsoStream.CopyTo(fileStream);
87
+ }
88
+ ZipFile.ExtractToDirectory(dsoPath, frameworkDir, true);
89
+ frameworks.Add(resource.name);
90
+ } catch (AggregateException ex) {
91
+ Debug.LogWarning($"Muna: Failed to embed prediction resource for {prediction.tag} predictor with error: {ex.InnerException}. Predictions with this predictor will likely fail at runtime.");
92
+ }
93
+ }
94
+ #if UNITY_IOS || UNITY_VISIONOS
95
+ var xcodeProjectName = report.summary.platform == BuildTarget.VisionOS ?
96
+ @"Unity-VisionOS.xcodeproj" : // Unity needs to fix `PBXProject::GetPBXProjectPath`
97
+ @"Unity-iPhone.xcodeproj";
98
+ var pbxPath = Path.Combine(
99
+ report.summary.outputPath,
100
+ xcodeProjectName,
101
+ @"project.pbxproj"
102
+ );
103
+ var project = new PBXProject();
104
+ project.ReadFromFile(pbxPath);
105
+ var targetGuid = project.GetUnityMainTargetGuid();
106
+ foreach (var framework in frameworks) {
107
+ var frameworkGuid = project.AddFile(
108
+ @"Frameworks/Muna/" + framework,
109
+ @"Frameworks/" + framework,
110
+ PBXSourceTree.Source
111
+ );
112
+ project.AddFileToEmbedFrameworks(targetGuid, frameworkGuid);
113
+ }
114
+ project.WriteToFile(pbxPath);
115
+ #endif
116
+ cache = null;
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 54671467a15d24530a381981bf979270
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,133 @@
1
+ /*
2
+ * Muna
3
+ * Copyright © 2025 NatML Inc. All rights reserved.
4
+ */
5
+
6
+ namespace Muna.Editor.Build {
7
+
8
+ using System;
9
+ using System.Collections.Generic;
10
+ using System.IO;
11
+ using System.Linq;
12
+ using System.Threading.Tasks;
13
+ using UnityEngine;
14
+ using UnityEditor;
15
+ using UnityEditor.Build;
16
+ using UnityEditor.Build.Reporting;
17
+ using API;
18
+ using Services;
19
+ using MunaSettings = Internal.MunaSettings;
20
+
21
+ #if UNITY_STANDALONE_OSX
22
+ using UnityEditor.iOS.Xcode;
23
+ using UnityEditor.iOS.Xcode.Extensions;
24
+ #endif
25
+
26
+ internal sealed class macOSBuildHandler : BuildHandler, IPostprocessBuildWithReport {
27
+
28
+ private List<CachedPrediction> cache;
29
+ private static readonly string[] ClientIds = new[] {
30
+ "macos-arm64",
31
+ "macos-x86_64"
32
+ };
33
+
34
+ protected override BuildTarget[] targets => new[] {
35
+ BuildTarget.StandaloneOSX
36
+ };
37
+
38
+ protected override MunaSettings CreateSettings(BuildReport report) {
39
+ // Create settings
40
+ var projectSettings = MunaProjectSettings.instance;
41
+ var settings = MunaSettings.Create(projectSettings.accessKey);
42
+ // Embed predictors
43
+ var embeds = GetEmbeds();
44
+ var cache = new List<CachedPrediction>();
45
+ foreach (var embed in embeds) {
46
+ var client = new DotNetClient(embed.url, embed.accessKey);
47
+ var muna = new Muna(client);
48
+ var predictions = (from tag in embed.tags from clientId in ClientIds select (clientId, tag))
49
+ .Select((pair) => {
50
+ var (clientId, tag) = pair;
51
+ try {
52
+ var prediction = Task.Run(() => muna.Predictions.Create(
53
+ tag,
54
+ clientId: clientId,
55
+ configurationId: @""
56
+ )).Result;
57
+ return new CachedPrediction(prediction, clientId);
58
+ }
59
+ catch (AggregateException ex) {
60
+ Debug.LogWarning($"Muna: Failed to embed {tag} predictor with error: {ex.InnerException}. Predictions with this predictor will likely fail at runtime.");
61
+ return null;
62
+ }
63
+ })
64
+ .Where(pred => pred != null)
65
+ .ToArray();
66
+ cache.AddRange(predictions);
67
+ }
68
+ // Cache
69
+ settings.cache = cache;
70
+ this.cache = cache;
71
+ // Return
72
+ return settings;
73
+ }
74
+
75
+ void IPostprocessBuildWithReport.OnPostprocessBuild(BuildReport report) {
76
+ // Check platform
77
+ if (!targets.Contains(report.summary.platform))
78
+ return;
79
+ // Check cache
80
+ if (cache == null)
81
+ return;
82
+ // Check if app or Xcode project
83
+ var outputPath = report.summary.outputPath;
84
+ var isApp = outputPath.EndsWith(@".app");
85
+ var frameworkDir = isApp ?
86
+ Path.Combine(outputPath, @"Contents", @"Frameworks") :
87
+ Path.Combine(outputPath, Application.productName, @"Frameworks", @"Muna");
88
+ Directory.CreateDirectory(frameworkDir);
89
+ // Embed
90
+ var frameworks = new List<string>();
91
+ var client = new DotNetClient(Muna.URL);
92
+ foreach (var prediction in cache)
93
+ foreach (var resource in prediction.resources) {
94
+ try {
95
+ if (resource.type != @"dso")
96
+ continue;
97
+ var dsoName = Path.GetFileName(PredictionService.GetResourcePath(resource, outputPath));
98
+ var dsoPath = Path.Combine(frameworkDir, dsoName);
99
+ using var dsoStream = Task.Run(() => client.Download(resource.url)).Result;
100
+ using var fileStream = File.Create(dsoPath);
101
+ dsoStream.CopyTo(fileStream);
102
+ frameworks.Add(dsoName);
103
+ } catch (AggregateException ex) {
104
+ Debug.LogWarning($"Muna: Failed to embed prediction resource for {prediction.tag} predictor with error: {ex.InnerException}. Predictions with this predictor will likely fail at runtime.");
105
+ }
106
+ }
107
+ // Check Xcode project
108
+ if (isApp)
109
+ return;
110
+ #if UNITY_STANDALONE_OSX
111
+ // Load Xcode project
112
+ var projectName = new DirectoryInfo(outputPath).Name + ".xcodeproj";
113
+ var pbxPath = Path.Combine(outputPath, projectName, @"project.pbxproj");
114
+ var project = new PBXProject();
115
+ project.ReadFromFile(pbxPath);
116
+ // Add frameworks
117
+ var targetGuid = project.GetUnityMainTargetGuid();
118
+ foreach (var framework in frameworks) {
119
+ var frameworkGuid = project.AddFile(
120
+ $"{Application.productName}/Frameworks/Muna/" + framework,
121
+ "Frameworks/" + framework,
122
+ PBXSourceTree.Source
123
+ );
124
+ project.AddFileToEmbedFrameworks(targetGuid, frameworkGuid);
125
+ }
126
+ // Write
127
+ project.WriteToFile(pbxPath);
128
+ #endif
129
+ // Empty cache
130
+ cache = null;
131
+ }
132
+ }
133
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 1a9c8accf3a8b4310ba32ed2a87606ca
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant: