ai.muna.muna 0.0.44 → 0.0.46

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 (50) hide show
  1. package/Editor/MunaMenu.cs +17 -7
  2. package/Plugins/Android/Muna.aar +0 -0
  3. package/Plugins/macOS/Function.dylib.meta +26 -25
  4. package/README.md +1 -1
  5. package/Runtime/API/DotNetClient.cs +0 -3
  6. package/Runtime/Beta/BetaClient.cs +14 -1
  7. package/Runtime/Beta/OpenAI/AudioService.cs +38 -0
  8. package/Runtime/Beta/OpenAI/AudioService.cs.meta +11 -0
  9. package/Runtime/Beta/OpenAI/ChatService.cs +38 -0
  10. package/Runtime/Beta/OpenAI/ChatService.cs.meta +11 -0
  11. package/Runtime/Beta/OpenAI/CompletionService.cs +117 -0
  12. package/Runtime/Beta/OpenAI/CompletionService.cs.meta +11 -0
  13. package/Runtime/Beta/OpenAI/EmbeddingService.cs +252 -0
  14. package/Runtime/Beta/OpenAI/EmbeddingService.cs.meta +11 -0
  15. package/Runtime/Beta/OpenAI/OpenAIClient.cs +50 -0
  16. package/Runtime/Beta/OpenAI/OpenAIClient.cs.meta +11 -0
  17. package/Runtime/Beta/OpenAI/SpeechService.cs +256 -0
  18. package/Runtime/Beta/OpenAI/SpeechService.cs.meta +11 -0
  19. package/Runtime/Beta/OpenAI/Types.cs +364 -0
  20. package/Runtime/Beta/OpenAI/Types.cs.meta +11 -0
  21. package/Runtime/Beta/OpenAI.meta +8 -0
  22. package/Runtime/Beta/Remote/RemotePredictionService.cs +50 -70
  23. package/Runtime/Beta/{Value.cs → Types/Value.cs} +3 -4
  24. package/Runtime/Beta/Types.meta +8 -0
  25. package/Runtime/C/Configuration.cs +1 -1
  26. package/Runtime/C/Function.cs +1 -1
  27. package/Runtime/C/Prediction.cs +1 -1
  28. package/Runtime/C/PredictionStream.cs +1 -1
  29. package/Runtime/C/Predictor.cs +1 -1
  30. package/Runtime/C/Value.cs +3 -2
  31. package/Runtime/C/ValueMap.cs +1 -1
  32. package/Runtime/Muna.cs +2 -2
  33. package/Runtime/Types/Parameter.cs +75 -0
  34. package/Runtime/Types/Parameter.cs.meta +11 -0
  35. package/Runtime/Types/Predictor.cs +0 -53
  36. package/Unity/API/PredictionCacheClient.cs +1 -1
  37. package/Unity/Converters/Color.cs +46 -0
  38. package/Unity/Converters/Color.cs.meta +2 -0
  39. package/Unity/Converters/Rect.cs +230 -0
  40. package/Unity/Converters/Rect.cs.meta +2 -0
  41. package/Unity/Converters/Vector2.cs +44 -0
  42. package/Unity/Converters/Vector2.cs.meta +2 -0
  43. package/Unity/Converters/Vector3.cs +45 -0
  44. package/Unity/Converters/Vector3.cs.meta +2 -0
  45. package/Unity/Converters/Vector4.cs +46 -0
  46. package/Unity/Converters/Vector4.cs.meta +2 -0
  47. package/Unity/Converters.meta +8 -0
  48. package/Unity/MunaUnity.cs +67 -19
  49. package/package.json +1 -1
  50. /package/Runtime/Beta/{Value.cs.meta → Types/Value.cs.meta} +0 -0
@@ -0,0 +1,364 @@
1
+ /*
2
+ * Muna
3
+ * Copyright © 2025 NatML Inc. All rights reserved.
4
+ */
5
+
6
+ #nullable enable
7
+
8
+ namespace Muna.Beta.OpenAI {
9
+
10
+ using System;
11
+ using System.Runtime.Serialization;
12
+ using Newtonsoft.Json;
13
+ using Newtonsoft.Json.Converters;
14
+
15
+ /// <summary>
16
+ /// Binary data with an optional content type.
17
+ /// </summary>
18
+ public sealed class BinaryData {
19
+
20
+ /// <summary>
21
+ /// Whether this data is empty.
22
+ /// </summary>
23
+ public bool IsEmpty => data.Length == 0;
24
+
25
+ /// <summary>
26
+ /// Number of bytes of this data.
27
+ /// </summary>
28
+ public int Length => data.Length;
29
+
30
+ /// <summary>
31
+ /// MIME type of this data
32
+ /// </summary>
33
+ public string? MediaType { get; private set; }
34
+
35
+ /// <summary>
36
+ /// Convert the `BinaryData` to a byte array.
37
+ /// </summary>
38
+ public byte[] ToArray() => data;
39
+
40
+ /// <summary>
41
+ /// Gets the value of this instance as bytes without any further interpretation.
42
+ /// </summary>
43
+ public ReadOnlyMemory<byte> ToMemory() => new ReadOnlyMemory<byte>(data);
44
+
45
+ private readonly byte[] data;
46
+
47
+ public BinaryData(byte[] data, string? mediaType = null) {
48
+ this.data = data;
49
+ this.MediaType = mediaType;
50
+ }
51
+ }
52
+
53
+ /// <summary>
54
+ /// Embedding.
55
+ /// </summary>
56
+ public sealed class Embedding {
57
+
58
+ /// <summary>
59
+ /// The object type, which is always "embedding".
60
+ /// </summary>
61
+ [JsonProperty(@"object")]
62
+ #pragma warning disable 8618
63
+ public string Object;
64
+ #pragma warning restore 8618
65
+
66
+ /// <summary>
67
+ /// Embedding vector as number array.
68
+ /// </summary>
69
+ [JsonProperty(@"embedding")]
70
+ public float[]? Floats;
71
+
72
+ /// <summary>
73
+ /// Index of the embedding in the list of embeddings.
74
+ /// </summary>
75
+ [JsonProperty(@"index")]
76
+ public int Index;
77
+
78
+ /// <summary>
79
+ /// Embedding vector as a base64 string.
80
+ /// </summary>
81
+ [JsonIgnore]
82
+ public string? Base64;
83
+ }
84
+
85
+ public sealed class CreateEmbeddingResponse {
86
+
87
+ #pragma warning disable 8618
88
+ /// <summary>
89
+ /// The object type, which is always "list".
90
+ /// </summary>
91
+ [JsonProperty(@"object")]
92
+ public string Object;
93
+
94
+ /// <summary>
95
+ /// The name of the model used to generate the embedding.
96
+ /// </summary>
97
+ [JsonProperty(@"model")]
98
+ public string Model;
99
+
100
+ /// <summary>
101
+ /// The list of embeddings generated by the model.
102
+ /// </summary>
103
+ [JsonProperty(@"data")]
104
+ public Embedding[] Data;
105
+ #pragma warning restore 8618
106
+
107
+ /// <summary>
108
+ /// The usage information for the request.
109
+ /// </summary>
110
+ [JsonProperty(@"usage")]
111
+ public UsageInfo Usage;
112
+
113
+ /// <summary>
114
+ /// Usage information for the request.
115
+ /// </summary>
116
+ public struct UsageInfo {
117
+
118
+ /// <summary>
119
+ /// Number of tokens used by the prompt.
120
+ /// </summary>
121
+ [JsonProperty(@"prompt_tokens")]
122
+ public int PromptTokens;
123
+
124
+ /// <summary>
125
+ /// Total number of tokens used by the request.
126
+ /// </summary>
127
+ [JsonProperty(@"total_tokens")]
128
+ public int TotalTokens;
129
+ }
130
+ }
131
+
132
+ /// <summary>
133
+ /// Chat message.
134
+ /// </summary>
135
+ public sealed class ChatMessage {
136
+
137
+ /// <summary>
138
+ /// Message role.
139
+ /// </summary>
140
+ [JsonConverter(typeof(StringEnumConverter))]
141
+ public enum ChatRole {
142
+ /// <summary>
143
+ /// Assistant.
144
+ /// </summary>
145
+ [EnumMember(Value = @"assistant")]
146
+ Assistant = 1,
147
+ /// <summary>
148
+ /// User
149
+ /// </summary>
150
+ [EnumMember(Value = @"user")]
151
+ User = 2,
152
+ /// <summary>
153
+ /// Developer.
154
+ /// </summary>
155
+ [EnumMember(Value = @"developer")]
156
+ Developer = 3,
157
+ /// <summary>
158
+ /// System.
159
+ /// </summary>
160
+ [EnumMember(Value = @"system")]
161
+ System = 4,
162
+ /// <summary>
163
+ /// Tool.
164
+ /// </summary>
165
+ [EnumMember(Value = @"tool")]
166
+ Tool = 5,
167
+ }
168
+
169
+ /// <summary>
170
+ /// Message role.
171
+ /// </summary>
172
+ [JsonProperty(@"role")]
173
+ public ChatRole Role;
174
+
175
+ /// <summary>
176
+ /// Message content.
177
+ /// </summary>
178
+ [JsonProperty(@"content")]
179
+ public string? Content;
180
+ }
181
+
182
+ /// <summary>
183
+ /// Chat completion.
184
+ /// </summary>
185
+ public sealed class ChatCompletion {
186
+
187
+ #pragma warning disable 8618
188
+ /// <summary>
189
+ /// The object type, which is always `chat.completion`.
190
+ /// </summary>
191
+ [JsonProperty(@"object")]
192
+ public string Object;
193
+
194
+ /// <summary>
195
+ /// Completion unique identifier.
196
+ /// </summary>
197
+ [JsonProperty(@"id")]
198
+ public string Id;
199
+
200
+ /// <summary>
201
+ /// Model that generated the chat completion.
202
+ /// </summary>
203
+ [JsonProperty(@"model")]
204
+ public string Model;
205
+
206
+ /// <summary>
207
+ /// Chat completion choices.
208
+ /// Can be more than one if `n` is greater than 1.
209
+ /// </summary>
210
+ [JsonProperty(@"choices")]
211
+ public Choice[] Choices;
212
+
213
+ /// <summary>
214
+ /// Date created as a unix timestamp (in seconds).
215
+ /// </summary>
216
+ [JsonProperty(@"created")]
217
+ public long Created;
218
+
219
+ /// <summary>
220
+ /// Usage statistics for the completion request.
221
+ /// </summary>
222
+ [JsonProperty(@"usage")]
223
+ public UsageInfo Usage;
224
+
225
+ public sealed class Choice {
226
+
227
+ /// <summary>
228
+ /// Index of this choice in the list of choices.
229
+ /// </summary>
230
+ [JsonProperty(@"index")]
231
+ public int Index;
232
+
233
+ /// <summary>
234
+ /// Completion message generated by the model.
235
+ /// </summary>
236
+ [JsonProperty(@"message")]
237
+ public ChatMessage Message;
238
+
239
+ /// <summary>
240
+ /// The reason the model stopped generating tokens. This will be:
241
+ ///
242
+ /// `stop` if the model hit a natural stop point or a provided stop sequence.
243
+ /// `length` if the maximum number of tokens specified in the request was reached.
244
+ /// `content_filter` if content was omitted due to a flag from our content filters.
245
+ /// `tool_calls` if the model called a tool.
246
+ /// `function_call` (deprecated) if the model called a function.
247
+ /// </summary>
248
+ [JsonProperty(@"finish_reason")]
249
+ public string? FinishReason;
250
+ }
251
+ #pragma warning restore 8618
252
+
253
+ public struct UsageInfo {
254
+
255
+ /// <summary>
256
+ /// Number of tokens in the generated completion.
257
+ /// </summary>
258
+ [JsonProperty(@"completion_tokens")]
259
+ public int CompletionTokens;
260
+
261
+ /// <summary>
262
+ /// Number of tokens in the prompt.
263
+ /// </summary>
264
+ [JsonProperty(@"prompt_tokens")]
265
+ public int PromptTokens;
266
+
267
+ /// <summary>
268
+ /// Total number of tokens used in the request (prompt + completion).
269
+ /// </summary>
270
+ [JsonProperty(@"total_tokens")]
271
+ public int TotalTokens;
272
+ }
273
+ }
274
+
275
+ /// <summary>
276
+ /// Chat completion chunk.
277
+ /// </summary>
278
+ public sealed class ChatCompletionChunk {
279
+
280
+ #pragma warning disable 8618
281
+ /// <summary>
282
+ /// The object type, which is always `chat.completion.chunk`.
283
+ /// </summary>
284
+ [JsonProperty(@"object")]
285
+ public string Object;
286
+
287
+ /// <summary>
288
+ /// Completion unique identifier.
289
+ /// All chunks from a given completion share the same identifier.
290
+ /// </summary>
291
+ [JsonProperty(@"id")]
292
+ public string Id;
293
+
294
+ /// <summary>
295
+ /// Model that generated the chat completion.
296
+ /// </summary>
297
+ [JsonProperty(@"model")]
298
+ public string Model;
299
+
300
+ /// <summary>
301
+ /// Chat completion choices.
302
+ /// Can be more than one if `n` is greater than 1.
303
+ /// Can also be empty for the last chunk if you set `stream_options: {"include_usage": true}`.
304
+ /// </summary>
305
+ [JsonProperty(@"choices")]
306
+ public Choice[] Choices;
307
+ #pragma warning restore 8618
308
+
309
+ /// <summary>
310
+ /// Date created as a unix timestamp (in seconds).
311
+ /// All chunks from a given completion share the same creation timestamp.
312
+ /// </summary>
313
+ [JsonProperty(@"created")]
314
+ public long Created;
315
+
316
+ /// <summary>
317
+ /// Usage statistics for the completion request.
318
+ /// </summary>
319
+ [JsonProperty(@"usage")]
320
+ public ChatCompletion.UsageInfo? Usage;
321
+
322
+ public sealed class Choice {
323
+
324
+ /// <summary>
325
+ /// Index of this choice in the list of choices.
326
+ /// </summary>
327
+ [JsonProperty(@"index")]
328
+ public int Index;
329
+
330
+ /// <summary>
331
+ /// Completion message delta generated by the model when streaming.
332
+ /// </summary>
333
+ [JsonProperty(@"delta")]
334
+ public MessageDelta? Delta;
335
+
336
+ /// <summary>
337
+ /// The reason the model stopped generating tokens. This will be:
338
+ ///
339
+ /// `stop` if the model hit a natural stop point or a provided stop sequence.
340
+ /// `length` if the maximum number of tokens specified in the request was reached.
341
+ /// `content_filter` if content was omitted due to a flag from our content filters.
342
+ /// `tool_calls` if the model called a tool.
343
+ /// `function_call` (deprecated) if the model called a function.
344
+ /// </summary>
345
+ [JsonProperty(@"finish_reason")]
346
+ public string? FinishReason;
347
+
348
+ public sealed class MessageDelta {
349
+
350
+ /// <summary>
351
+ /// Role of the author of this message.
352
+ /// </summary>
353
+ [JsonProperty(@"role")]
354
+ public ChatMessage.ChatRole? Role;
355
+
356
+ /// <summary>
357
+ /// Content of the message chunk.
358
+ /// </summary>
359
+ [JsonProperty(@"content")]
360
+ public string? Content;
361
+ }
362
+ }
363
+ }
364
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: cc44ab5ef48204d5bade71a3dc9640ed
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,8 @@
1
+ fileFormatVersion: 2
2
+ guid: b6c7d82c12a544ba98437c05417089e8
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -39,7 +39,7 @@ namespace Muna.Beta.Services {
39
39
  await Configuration.InitializationTask;
40
40
  var inputMap = (await Task.WhenAll(inputs.Select(async pair => (
41
41
  name: pair.Key,
42
- value: await ToValue(pair.Value, pair.Key)
42
+ value: await ToValue(pair.Value)
43
43
  )))).ToDictionary(pair => pair.name, pair => pair.value);
44
44
  var prediction = (await client.Request<RemotePrediction>(
45
45
  method: @"POST",
@@ -69,55 +69,52 @@ namespace Muna.Beta.Services {
69
69
 
70
70
  internal RemotePredictionService(MunaClient client) => this.client = client;
71
71
 
72
- private async Task<Value> ToValue( // INCOMPLETE // Image
73
- object? value,
74
- string name,
75
- int maxDataUrlSize = 4 * 1024 * 1024
76
- ) => value switch {
77
- null => new Value { type = Dtype.Null },
78
- float x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Float32, shape = new int[0] },
79
- double x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Float64, shape = new int[0] },
80
- sbyte x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int8, shape = new int[0] },
81
- short x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int16, shape = new int[0] },
82
- int x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int32, shape = new int[0] },
83
- long x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int64, shape = new int[0] },
84
- byte x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint8, shape = new int[0] },
85
- ushort x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint16, shape = new int[0] },
86
- uint x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint32, shape = new int[0] },
87
- ulong x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint64, shape = new int[0] },
88
- bool x => new Value { data = await Upload(new [] { x }.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Bool, shape = new int[0] },
89
- float[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Float32, shape = new [] { x.Length } },
90
- double[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Float64, shape = new [] { x.Length } },
91
- sbyte[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int8, shape = new [] { x.Length } },
92
- short[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int16, shape = new [] { x.Length } },
93
- int[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int32, shape = new [] { x.Length } },
94
- long[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int64, shape = new [] { x.Length } },
95
- byte[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint8, shape = new [] { x.Length } },
96
- ushort[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint16, shape = new [] { x.Length } },
97
- uint[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint32, shape = new [] { x.Length } },
98
- ulong[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint64, shape = new [] { x.Length } },
99
- bool[] x => new Value { data = await Upload(x.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Bool, shape = new [] { x.Length } },
100
- Tensor<float> x => new Value { data = await Upload(x.data.ToStream(),name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Float32, shape = x.shape },
101
- Tensor<double> x => new Value { data = await Upload(x.data.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Float64, shape = x.shape },
102
- Tensor<sbyte> x => new Value { data = await Upload(x.data.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int8, shape = x.shape },
103
- Tensor<short> x => new Value { data = await Upload(x.data.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int16, shape = x.shape },
104
- Tensor<int> x => new Value { data = await Upload(x.data.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int32, shape = x.shape },
105
- Tensor<long> x => new Value { data = await Upload(x.data.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Int64, shape = x.shape },
106
- Tensor<byte> x => new Value { data = await Upload(x.data.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint8, shape = x.shape },
107
- Tensor<ushort> x => new Value { data = await Upload(x.data.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint16, shape = x.shape },
108
- Tensor<uint> x => new Value { data = await Upload(x.data.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint32, shape = x.shape },
109
- Tensor<ulong> x => new Value { data = await Upload(x.data.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Uint64, shape = x.shape },
110
- Tensor<bool> x => new Value { data = await Upload(x.data.ToStream(), name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Bool, shape = x.shape },
111
- string x => new Value { data = await Upload(x.ToStream(), name, mime: @"text/plain", maxDataUrlSize: maxDataUrlSize), type = Dtype.String },
112
- IList x => new Value { data = await Upload(JsonConvert.SerializeObject(x).ToStream(), name, mime: @"application/json", maxDataUrlSize: maxDataUrlSize), type = Dtype.List },
113
- IDictionary x => new Value { data = await Upload(JsonConvert.SerializeObject(x).ToStream(), name, mime: @"application/json", maxDataUrlSize: maxDataUrlSize), type = Dtype.Dict },
114
- Image x => new Value { data = "", type = Dtype.Image },
115
- Stream x => new Value { data = await Upload(x, name, maxDataUrlSize: maxDataUrlSize), type = Dtype.Binary },
116
- Enum x => await ToValue(x.ToObject(), name, maxDataUrlSize: maxDataUrlSize),
72
+ private async Task<RemoteValue> ToValue(object? value) => value switch { // INCOMPLETE // Image
73
+ null => new() { type = Dtype.Null },
74
+ float x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Float32, shape = new int[0] },
75
+ double x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Float64, shape = new int[0] },
76
+ sbyte x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Int8, shape = new int[0] },
77
+ short x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Int16, shape = new int[0] },
78
+ int x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Int32, shape = new int[0] },
79
+ long x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Int64, shape = new int[0] },
80
+ byte x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Uint8, shape = new int[0] },
81
+ ushort x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Uint16, shape = new int[0] },
82
+ uint x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Uint32, shape = new int[0] },
83
+ ulong x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Uint64, shape = new int[0] },
84
+ bool x => new() { data = await Upload(new [] { x }.ToStream()), type = Dtype.Bool, shape = new int[0] },
85
+ float[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Float32, shape = new [] { x.Length } },
86
+ double[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Float64, shape = new [] { x.Length } },
87
+ sbyte[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Int8, shape = new [] { x.Length } },
88
+ short[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Int16, shape = new [] { x.Length } },
89
+ int[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Int32, shape = new [] { x.Length } },
90
+ long[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Int64, shape = new [] { x.Length } },
91
+ byte[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Uint8, shape = new [] { x.Length } },
92
+ ushort[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Uint16, shape = new [] { x.Length } },
93
+ uint[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Uint32, shape = new [] { x.Length } },
94
+ ulong[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Uint64, shape = new [] { x.Length } },
95
+ bool[] x => new() { data = await Upload(x.ToStream()), type = Dtype.Bool, shape = new [] { x.Length } },
96
+ Tensor<float> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Float32, shape = x.shape },
97
+ Tensor<double> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Float64, shape = x.shape },
98
+ Tensor<sbyte> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Int8, shape = x.shape },
99
+ Tensor<short> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Int16, shape = x.shape },
100
+ Tensor<int> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Int32, shape = x.shape },
101
+ Tensor<long> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Int64, shape = x.shape },
102
+ Tensor<byte> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Uint8, shape = x.shape },
103
+ Tensor<ushort> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Uint16, shape = x.shape },
104
+ Tensor<uint> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Uint32, shape = x.shape },
105
+ Tensor<ulong> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Uint64, shape = x.shape },
106
+ Tensor<bool> x => new() { data = await Upload(x.data.ToStream()), type = Dtype.Bool, shape = x.shape },
107
+ string x => new() { data = await Upload(x.ToStream(), mime: @"text/plain"), type = Dtype.String },
108
+ IList x => new() { data = await Upload(JsonConvert.SerializeObject(x).ToStream(), mime: @"application/json"), type = Dtype.List },
109
+ IDictionary x => new() { data = await Upload(JsonConvert.SerializeObject(x).ToStream(), mime: @"application/json"), type = Dtype.Dict },
110
+ Image x => new() { data = "", type = Dtype.Image },
111
+ Stream x => new() { data = await Upload(x), type = Dtype.Binary },
112
+ Enum x => await ToValue(x.ToObject()),
113
+ RemoteValue x => x,
117
114
  _ => throw new InvalidOperationException($"Failed to serialize value '{value}' of type `{value.GetType()}` because it is not supported"),
118
115
  };
119
116
 
120
- private async Task<object?> ToObject(Value value) { // INCOMPLETE // Image
117
+ private async Task<object?> ToObject(RemoteValue value) { // INCOMPLETE // Image
121
118
  if (value.type == Dtype.Null)
122
119
  return null;
123
120
  using var stream = await Download(value.data!);
@@ -142,24 +139,13 @@ namespace Muna.Beta.Services {
142
139
  };
143
140
  }
144
141
 
145
- private async Task<string> Upload(
142
+ private Task<string> Upload(
146
143
  Stream stream,
147
- string name,
148
- string? mime = @"application/octet-stream",
149
- int maxDataUrlSize = 4 * 1024 * 1024
144
+ string? mime = @"application/octet-stream"
150
145
  ) {
151
- if (stream.Length <= maxDataUrlSize) {
152
- var data = Convert.ToBase64String(stream.ToArray<byte>());
153
- var result = $"data:{mime};base64,{data}";
154
- return result;
155
- }
156
- var value = await client.Request<CreateValueResponse>(
157
- method: @"POST",
158
- path: "/values",
159
- payload: new () { [@"name"] = name }
160
- );
161
- await client.Upload(stream, value!.uploadUrl!, mime: mime);
162
- return value.downloadUrl!;
146
+ var data = Convert.ToBase64String(stream.ToArray<byte>());
147
+ var result = $"data:{mime};base64,{data}";
148
+ return Task.FromResult(result);
163
149
  }
164
150
 
165
151
  private async Task<Stream> Download(string url) {
@@ -172,15 +158,9 @@ namespace Muna.Beta.Services {
172
158
  return await client.Download(url);
173
159
  }
174
160
 
175
- [Preserve, Serializable]
176
- private class CreateValueResponse {
177
- public string? uploadUrl;
178
- public string? downloadUrl;
179
- }
180
-
181
161
  [Preserve, Serializable]
182
162
  private class RemotePrediction : Prediction {
183
- public new Value[]? results;
163
+ public new RemoteValue[]? results;
184
164
  }
185
165
  #endregion
186
166
  }
@@ -18,7 +18,7 @@ namespace Muna.Beta {
18
18
  /// Remote prediction value.
19
19
  /// </summary>
20
20
  [Preserve, Serializable]
21
- internal class Value {
21
+ public sealed class RemoteValue {
22
22
 
23
23
  /// <summary>
24
24
  /// Value URL.
@@ -58,10 +58,9 @@ namespace Muna.Beta {
58
58
  public static unsafe Stream ToStream<T>(this T[] data) where T : unmanaged {
59
59
  if (data is byte[] raw)
60
60
  return new MemoryStream(raw);
61
- var size = data.Length * sizeof(T);
62
- var array = new byte[size];
61
+ var array = new byte[data.Length * sizeof(T)];
63
62
  fixed (void* src = data, dst = array)
64
- Buffer.MemoryCopy(src, dst, size, size);
63
+ Buffer.MemoryCopy(src, dst, array.Length, array.Length);
65
64
  return new MemoryStream(array);
66
65
  }
67
66
 
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: 13abad7ab83f14becbb10f8b4482e27a
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -11,7 +11,7 @@ namespace Muna.C {
11
11
  using System.Runtime.InteropServices;
12
12
  using System.Text;
13
13
  using System.Threading.Tasks;
14
- using static Muna;
14
+ using static Function;
15
15
 
16
16
  public sealed class Configuration : IDisposable {
17
17
 
@@ -11,7 +11,7 @@ namespace Muna.C {
11
11
  using System.Runtime.InteropServices;
12
12
  using System.Text;
13
13
 
14
- internal static unsafe class Muna {
14
+ internal static unsafe class Function {
15
15
 
16
16
  public const string Assembly =
17
17
  #if (UNITY_IOS || UNITY_VISIONOS || UNITY_WEBGL) && !UNITY_EDITOR
@@ -9,7 +9,7 @@ namespace Muna.C {
9
9
 
10
10
  using System;
11
11
  using System.Text;
12
- using static Muna;
12
+ using static Function;
13
13
 
14
14
  public sealed class Prediction : IDisposable {
15
15
 
@@ -8,7 +8,7 @@
8
8
  namespace Muna.C {
9
9
 
10
10
  using System;
11
- using static Muna;
11
+ using static Function;
12
12
 
13
13
  public sealed class PredictionStream : IDisposable {
14
14
 
@@ -8,7 +8,7 @@
8
8
  namespace Muna.C {
9
9
 
10
10
  using System;
11
- using static Muna;
11
+ using static Function;
12
12
 
13
13
  public sealed class Predictor : IDisposable {
14
14
 
@@ -14,7 +14,7 @@ namespace Muna.C {
14
14
  using System.Runtime.InteropServices;
15
15
  using Newtonsoft.Json;
16
16
  using Newtonsoft.Json.Linq;
17
- using static Muna;
17
+ using static Function;
18
18
 
19
19
  public unsafe sealed class Value : IDisposable {
20
20
 
@@ -170,8 +170,9 @@ namespace Muna.C {
170
170
  private static unsafe T[] ToArray<T>(T* data, int[] shape) where T : unmanaged {
171
171
  var count = shape.Aggregate(1, (a, b) => a * b);
172
172
  var result = new T[count];
173
+ var size = count * sizeof(T);
173
174
  fixed (void* dst = result)
174
- Buffer.MemoryCopy(data, dst, count * sizeof(T), count * sizeof(T));
175
+ Buffer.MemoryCopy(data, dst, size, size);
175
176
  return result;
176
177
  }
177
178