version 16 with bug fixes

This commit is contained in:
Jacob Dubin
2026-04-23 07:35:15 -05:00
parent 41e90fc4c1
commit 1511f3a281
19 changed files with 11164 additions and 2 deletions

View File

@@ -228,6 +228,12 @@ Useful external references:
- more capable skill/runtime integration
- possible LLM or tool-use patterns inspired by workshop-era experimentation
## Latest Notes
- The `jibo test 19` bundle confirmed that gallery follow-up confirmation uses the stock local `shared/yes_no` rule family, not just the create/settings/surprise yes-no families. Spoken `yes` was being heard correctly, but leaking the global rules back into Nimbus instead of staying local.
- The same bundle also confirmed some `OPENJIBO_AUDIO_RECEIVED` noise was still coming from an older running build, because the current `.NET` source no longer emits that synthetic websocket event. When a live session still shows it, operator workflow should treat that as a rebuild/restart sanity-check clue before assuming a new regression.
- Spoken `cancel alarm` should map into stock `@be/clock` `delete` semantics, not generic chat. The current cloud path now mirrors that local intent so voice cancel can follow the same lane as the robot's clock skill.
## MCP-Like Ideas
Recent MIT workshop materials suggest experimentation around modern AI tooling for Jibo, including an MCP-oriented idea. We should treat that as inspiration for future OpenJibo directions, not as a present dependency or supported integration.

View File

@@ -6,7 +6,7 @@
This is the production-oriented path for restoring device connectivity and creating a foundation for future runtime, AI, and OTA work.
Current spoken cloud version: `Open Jibo Cloud version 1.0.15.`
Current spoken cloud version: `Open Jibo Cloud version 1.0.16.`
Release hygiene reminder:

View File

@@ -51,6 +51,8 @@ public sealed class JiboInteractionService(
"clock_menu" => BuildClockLaunchDecision("clock_menu", "clock", "menu", "Opening the clock menu."),
"timer_menu" => BuildClockLaunchDecision("timer", "Opening the timer."),
"alarm_menu" => BuildClockLaunchDecision("alarm", "Opening the alarm."),
"timer_delete" => BuildClockLaunchDecision("timer_delete", "timer", "delete", "Canceling the timer."),
"alarm_delete" => BuildClockLaunchDecision("alarm_delete", "alarm", "delete", "Canceling the alarm."),
"timer_value" => BuildTimerValueDecision(lowered, isTimerValueTurn),
"alarm_value" => BuildAlarmValueDecision(lowered, isAlarmValueTurn, referenceLocalTime),
"timer_clarify" => new JiboInteractionDecision("timer_clarify", "How long should I set the timer for?"),
@@ -288,6 +290,28 @@ public sealed class JiboInteractionService(
return "alarm_menu";
}
if (MatchesAny(
loweredTranscript,
"cancel alarm",
"delete alarm",
"remove alarm",
"stop alarm",
"turn off alarm"))
{
return "alarm_delete";
}
if (MatchesAny(
loweredTranscript,
"cancel timer",
"delete timer",
"remove timer",
"stop timer",
"turn off timer"))
{
return "timer_delete";
}
if (TryParseAlarmValue(loweredTranscript, isAlarmValueTurn, referenceLocalTime) is not null)
{
return "alarm_value";
@@ -616,6 +640,7 @@ public sealed class JiboInteractionService(
.Any(static rule =>
string.Equals(rule, "$YESNO", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "create/is_it_a_keeper", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "shared/yes_no", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "settings/download_now_later", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "surprises-date/offer_date_fact", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "surprises-ota/want_to_download_now", StringComparison.OrdinalIgnoreCase));

View File

@@ -2,7 +2,7 @@ namespace Jibo.Cloud.Application.Services;
public static class OpenJiboCloudBuildInfo
{
public const string Version = "1.0.15";
public const string Version = "1.0.16";
public static string VersionWords => Version.Replace(".", " dot ");

View File

@@ -457,6 +457,7 @@ public sealed class ResponsePlanToSocketMessagesMapper
return ReadRuleValues(turn)
.FirstOrDefault(static rule =>
string.Equals(rule, "create/is_it_a_keeper", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "shared/yes_no", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "settings/download_now_later", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "surprises-date/offer_date_fact", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "surprises-ota/want_to_download_now", StringComparison.OrdinalIgnoreCase));

View File

@@ -836,6 +836,7 @@ public sealed class WebSocketTurnFinalizationService(
.Concat(ReadRules(turn, "clientRules"))
.FirstOrDefault(static rule =>
string.Equals(rule, "create/is_it_a_keeper", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "shared/yes_no", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "settings/download_now_later", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "surprises-date/offer_date_fact", StringComparison.OrdinalIgnoreCase) ||
string.Equals(rule, "surprises-ota/want_to_download_now", StringComparison.OrdinalIgnoreCase));

View File

@@ -113,6 +113,26 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("No.", decision.ReplyText);
}
[Fact]
public async Task BuildDecisionAsync_SharedYesNoPrompt_MapsShortAffirmationToYesIntent()
{
var service = CreateService();
var decision = await service.BuildDecisionAsync(new TurnContext
{
RawTranscript = "yes",
NormalizedTranscript = "yes",
Attributes = new Dictionary<string, object?>
{
["listenRules"] = new[] { "shared/yes_no", "globals/gui_nav" },
["listenAsrHints"] = new[] { "$YESNO" }
}
});
Assert.Equal("yes", decision.IntentName);
Assert.Equal("Yes.", decision.ReplyText);
}
[Fact]
public async Task BuildDecisionAsync_SettingsDownloadPrompt_MapsShortDenialToNoIntent()
{
@@ -482,6 +502,23 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("What time should I set the alarm for?", decision.ReplyText);
}
[Fact]
public async Task BuildDecisionAsync_CancelAlarm_MapsToClockDeleteIntent()
{
var service = CreateService();
var decision = await service.BuildDecisionAsync(new TurnContext
{
RawTranscript = "cancel alarm",
NormalizedTranscript = "cancel alarm"
});
Assert.Equal("alarm_delete", decision.IntentName);
Assert.Equal("@be/clock", decision.SkillName);
Assert.Equal("alarm", decision.SkillPayload!["domain"]);
Assert.Equal("delete", decision.SkillPayload["clockIntent"]);
}
[Fact]
public async Task BuildDecisionAsync_SetTimerWithoutDuration_AsksForClarification()
{

View File

@@ -687,6 +687,38 @@ public sealed class JiboWebSocketServiceTests
Assert.Contains("What time should I set the alarm for?", esml, StringComparison.Ordinal);
}
[Fact]
public async Task ClientAsr_CancelAlarm_RedirectsIntoClockSkillWithDeleteIntent()
{
await _service.HandleMessageAsync(new WebSocketMessageEnvelope
{
HostName = "neo-hub.jibo.com",
Path = "/listen",
Kind = "neo-hub-listen",
Token = "hub-clock-cancel-alarm-token",
Text = """{"type":"LISTEN","transID":"trans-clock-cancel-alarm","data":{"rules":["globals/global_commands_launch"]}}"""
});
var replies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
{
HostName = "neo-hub.jibo.com",
Path = "/listen",
Kind = "neo-hub-listen",
Token = "hub-clock-cancel-alarm-token",
Text = """{"type":"CLIENT_ASR","transID":"trans-clock-cancel-alarm","data":{"text":"cancel alarm"}}"""
});
Assert.Equal(5, replies.Count);
using var listenPayload = JsonDocument.Parse(replies[0].Text!);
Assert.Equal("delete", listenPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("intent").GetString());
Assert.Equal("alarm", listenPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("entities").GetProperty("domain").GetString());
using var redirectPayload = JsonDocument.Parse(replies[2].Text!);
Assert.Equal("@be/clock", redirectPayload.RootElement.GetProperty("data").GetProperty("match").GetProperty("skillID").GetString());
Assert.Equal("delete", redirectPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("intent").GetString());
}
[Fact]
public async Task ClientAsr_OpenPhotoGallery_RedirectsIntoGallerySkill()
{
@@ -924,6 +956,37 @@ public sealed class JiboWebSocketServiceTests
Assert.Equal("surprises-ota/want_to_download_now", listenPayload.RootElement.GetProperty("data").GetProperty("match").GetProperty("rule").GetString());
}
[Fact]
public async Task ClientAsr_SharedYesNoPrompt_StripsGlobalRulesAndStaysLocal()
{
await _service.HandleMessageAsync(new WebSocketMessageEnvelope
{
HostName = "neo-hub.jibo.com",
Path = "/listen",
Kind = "neo-hub-listen",
Token = "hub-shared-yesno-token",
Text = """{"type":"LISTEN","transID":"trans-shared-yesno","data":{"rules":["shared/yes_no","globals/gui_nav","globals/mim_repeat","globals/global_commands_launch"],"asr":{"hints":["$YESNO"]}}}"""
});
var replies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
{
HostName = "neo-hub.jibo.com",
Path = "/listen",
Kind = "neo-hub-listen",
Token = "hub-shared-yesno-token",
Text = """{"type":"CLIENT_ASR","transID":"trans-shared-yesno","data":{"text":"yes"}}"""
});
Assert.Equal(3, replies.Count);
using var listenPayload = JsonDocument.Parse(replies[0].Text!);
Assert.Equal("yes", listenPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("intent").GetString());
var rules = listenPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("rules");
Assert.Single(rules.EnumerateArray());
Assert.Equal("shared/yes_no", rules[0].GetString());
Assert.Equal("shared/yes_no", listenPayload.RootElement.GetProperty("data").GetProperty("match").GetProperty("rule").GetString());
}
[Fact]
public async Task BufferedAudio_YesNoPromptWithSttFailure_AutoFinalizesAsLocalNoInput()
{

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
{
"exception": "System.InvalidOperationException: whisper.cpp returned no transcript for the buffered audio turn.\n at Jibo.Cloud.Infrastructure.Audio.LocalWhisperCppBufferedAudioSttStrategy.TranscribeAsync(TurnContext turn, CancellationToken cancellationToken) in /home/jake-dubin/JiboExperiments/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Audio/LocalWhisperCppBufferedAudioSttStrategy.cs:line 58\n at Jibo.Cloud.Application.Services.WebSocketTurnFinalizationService.ResolveTranscriptAsync(TurnContext turn, CloudSession session, CancellationToken cancellationToken) in /home/jake-dubin/JiboExperiments/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/WebSocketTurnFinalizationService.cs:line 219",
"message": "Error during STT processing"
}

View File

@@ -0,0 +1,4 @@
{
"exception": "System.InvalidOperationException: whisper.cpp returned no transcript for the buffered audio turn.\n at Jibo.Cloud.Infrastructure.Audio.LocalWhisperCppBufferedAudioSttStrategy.TranscribeAsync(TurnContext turn, CancellationToken cancellationToken) in /home/jake-dubin/JiboExperiments/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Audio/LocalWhisperCppBufferedAudioSttStrategy.cs:line 58\n at Jibo.Cloud.Application.Services.WebSocketTurnFinalizationService.ResolveTranscriptAsync(TurnContext turn, CloudSession session, CancellationToken cancellationToken) in /home/jake-dubin/JiboExperiments/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/WebSocketTurnFinalizationService.cs:line 242",
"message": "Error during STT processing"
}

View File

@@ -0,0 +1,4 @@
{
"exception": "System.InvalidOperationException: External process \u0027/usr/bin/ffmpeg\u0027 failed with exit code 187: ffmpeg version 6.1.1-3ubuntu5\u002Besm7 Copyright (c) 2000-2023 the FFmpeg developers\n built with gcc 13 (Ubuntu 13.3.0-6ubuntu2~24.04)\n configuration: --prefix=/usr --extra-version=3ubuntu5\u002Besm7 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --disable-omx --enable-gnutls --enable-libaom --enable-libass --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libharfbuzz --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-openal --enable-opencl --enable-opengl --disable-sndio --enable-libvpl --disable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-ladspa --enable-libbluray --enable-libjack --enable-libpulse --enable-librabbitmq --enable-librist --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libx264 --enable-libzmq --enable-libzvbi --enable-lv2 --enable-sdl2 --enable-libplacebo --enable-librav1e --enable-pocketsphinx --enable-librsvg --enable-libjxl --enable-shared\n libavutil 58. 29.100 / 58. 29.100\n libavcodec 60. 31.102 / 60. 31.102\n libavformat 60. 16.100 / 60. 16.100\n libavdevice 60. 3.100 / 60. 3.100\n libavfilter 9. 12.100 / 9. 12.100\n libswscale 7. 5.100 / 7. 5.100\n libswresample 4. 12.100 / 4. 12.100\n libpostproc 57. 3.100 / 57. 3.100\n[ogg @ 0x5d01666aaec0] Codec not found\n[in#0 @ 0x5d01666aadc0] Error opening input: End of file\nError opening input file /tmp/openjibo-stt/turn-3982e2cda6124a3cb01b848ba11678cd.ogg.\nError opening input files: End of file\n\n at Jibo.Cloud.Infrastructure.Audio.ExternalProcessRunner.RunAsync(String fileName, IReadOnlyList\u00601 arguments, CancellationToken cancellationToken) in /home/jake-dubin/JiboExperiments/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Audio/ExternalProcessRunner.cs:line 35\n at Jibo.Cloud.Infrastructure.Audio.LocalWhisperCppBufferedAudioSttStrategy.TranscribeAsync(TurnContext turn, CancellationToken cancellationToken) in /home/jake-dubin/JiboExperiments/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Audio/LocalWhisperCppBufferedAudioSttStrategy.cs:line 45\n at Jibo.Cloud.Application.Services.WebSocketTurnFinalizationService.ResolveTranscriptAsync(TurnContext turn, CloudSession session, CancellationToken cancellationToken) in /home/jake-dubin/JiboExperiments/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/WebSocketTurnFinalizationService.cs:line 226",
"message": "Error during STT processing"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,127 @@
{
"name": "neohubjibocom-neohublisten-tid52b6f46e3b6a11f191515cf821ea55ae",
"session": {
"hostName": "neo-hub.jibo.com",
"path": "/v1/listen",
"kind": "neo-hub-listen",
"token": "hub-usr_openjibo_owner-1776545569192"
},
"steps": [
{
"text": {
"type": "LISTEN",
"ts": 1776546327052,
"msgID": "mid-5303b5f6-3b6a-11f1-adc4-5cf821ea55ae",
"transID": "tid-52b6f46e-3b6a-11f1-9151-5cf821ea55ae",
"data": {
"lang": "en-US",
"hotphrase": true,
"rules": [
"launch",
"globals/global_commands_launch"
],
"mode": "CLIENT_ASR",
"asr": {
"hints": [],
"earlyEOS": [],
"encoding": "OGG_OPUS",
"sampleRate": 16000,
"sosTimeout": 7000,
"maxSpeechTimeout": 20000
}
}
},
"binary": null,
"expectedReplyTypes": [
"OPENJIBO_TURN_PENDING"
]
},
{
"text": {
"type": "CLIENT_ASR",
"ts": 1776546327052,
"msgID": "mid-5303bd76-3b6a-11f1-81d4-5cf821ea55ae",
"transID": "tid-52b6f46e-3b6a-11f1-9151-5cf821ea55ae",
"data": {
"text": "tell me about the news"
}
},
"binary": null,
"expectedReplyTypes": [
"LISTEN",
"EOS",
"SKILL_ACTION"
]
},
{
"text": {
"type": "CONTEXT",
"ts": 1776546327177,
"msgID": "mid-5316cf2e-3b6a-11f1-8aa7-5cf821ea55ae",
"transID": "tid-52b6f46e-3b6a-11f1-9151-5cf821ea55ae",
"data": {
"runtime": {
"character": {
"emotion": {
"name": "NEUTRAL",
"valence": 0.45,
"confidence": 0.2
},
"motivation": {
"social": 1,
"playful": 1
}
},
"perception": {
"speaker": null,
"peoplePresent": []
},
"location": {
"city": "Pleasant Hill",
"state": "Missouri",
"stateAbbr": "MO",
"country": "United States",
"countryCode": "US",
"lat": 38.8358494,
"lng": -94.1427229,
"iso": "2026-04-18T16:05:27.073-05:00"
},
"loop": {
"loopId": "5c0b221fdf9d450019c5e253",
"users": [
{
"firstName": "Erin",
"lastName": "Picone",
"phoneticName": "Erin",
"gender": "female",
"birthdate": 649209600000,
"id": "5c0b221fdf9d450019c5e255",
"accountId": "5c0b20547c46170019235759"
}
],
"jibo": {
"color": "WHITE",
"birthdate": 1544234645598,
"id": "5c0b221fdf9d450019c5e254"
},
"owner": "5c0b221fdf9d450019c5e255"
},
"dialog": {
"referent": null
}
},
"skill": {
"id": null
},
"general": {
"release": "1.9.2"
}
}
},
"binary": null,
"expectedReplyTypes": [
"OPENJIBO_CONTEXT_ACK"
]
}
]
}

View File

@@ -0,0 +1,174 @@
{
"name": "neohubjibocom-neohublisten-tida8165b823b9411f195545cf821ea55ae",
"session": {
"hostName": "neo-hub.jibo.com",
"path": "/v1/listen",
"kind": "neo-hub-listen",
"token": "hub-usr_openjibo_owner-1776563295273"
},
"steps": [
{
"text": {
"type": "LISTEN",
"ts": 1776564508900,
"msgID": "mid-a83d9076-3b94-11f1-978d-5cf821ea55ae",
"transID": "tid-a8165b82-3b94-11f1-9554-5cf821ea55ae",
"data": {
"lang": "en-US",
"hotphrase": true,
"rules": [
"launch",
"globals/global_commands_launch"
],
"mode": "",
"asr": {
"hints": [],
"earlyEOS": [],
"encoding": "OGG_OPUS",
"sampleRate": 16000,
"sosTimeout": 7000,
"maxSpeechTimeout": 20000
}
}
},
"binary": null,
"expectedReplyTypes": [
"LISTEN",
"EOS",
"SKILL_ACTION"
]
},
{
"text": null,
"binary": [
79,
103,
103,
83,
0,
2,
0,
0,
0,
0,
0,
0,
0,
0,
62,
200,
6,
48,
0,
0,
0,
0,
146,
142,
146,
101,
1,
19,
79,
112,
117,
115,
72,
101,
97,
100,
1,
1,
0,
0,
128,
62,
0,
0,
0,
0,
0
],
"expectedReplyTypes": [
"OPENJIBO_AUDIO_RECEIVED"
]
},
{
"text": {
"type": "CONTEXT",
"ts": 1776564510009,
"msgID": "mid-a8e6d640-3b94-11f1-b2b0-5cf821ea55ae",
"transID": "tid-a8165b82-3b94-11f1-9554-5cf821ea55ae",
"data": {
"runtime": {
"character": {
"emotion": {
"name": "NEUTRAL",
"valence": 0.45,
"confidence": 0.2
},
"motivation": {
"social": 1,
"playful": 1
}
},
"perception": {
"speaker": null,
"peoplePresent": [
{
"id": "NOT_TRAINED",
"entityId": 1282,
"type": "fused",
"confidence": 0.25
}
]
},
"location": {
"city": "Pleasant Hill",
"state": "Missouri",
"stateAbbr": "MO",
"country": "United States",
"countryCode": "US",
"lat": 38.8358494,
"lng": -94.1427229,
"iso": "2026-04-18T21:08:29.921-05:00"
},
"loop": {
"loopId": "5c0b221fdf9d450019c5e253",
"users": [
{
"firstName": "Erin",
"lastName": "Picone",
"phoneticName": "Erin",
"gender": "female",
"birthdate": 649209600000,
"id": "5c0b221fdf9d450019c5e255",
"accountId": "5c0b20547c46170019235759"
}
],
"jibo": {
"color": "WHITE",
"birthdate": 1544234645598,
"id": "5c0b221fdf9d450019c5e254"
},
"owner": "5c0b221fdf9d450019c5e255"
},
"dialog": {
"referent": null
}
},
"skill": {
"id": null
},
"general": {
"release": "1.9.2"
}
}
},
"binary": null,
"expectedReplyTypes": [
"OPENJIBO_CONTEXT_ACK"
]
}
]
}

View File

@@ -0,0 +1,95 @@
{
"name": "neohubjibocom-neohublisten-tidd2b591403b6811f1a5735cf821ea55ae",
"session": {
"hostName": "neo-hub.jibo.com",
"path": "/v1/listen",
"kind": "neo-hub-listen",
"token": "hub-usr_openjibo_owner-1776545569192"
},
"steps": [
{
"text": {
"type": "LISTEN",
"ts": 1776545682509,
"msgID": "mid-d2d657ea-3b68-11f1-985b-5cf821ea55ae",
"transID": "tid-d2b59140-3b68-11f1-a573-5cf821ea55ae",
"data": {
"lang": "en-US",
"hotphrase": true,
"rules": [
"launch",
"globals/global_commands_launch"
],
"mode": "",
"asr": {
"hints": [],
"earlyEOS": [],
"encoding": "OGG_OPUS",
"sampleRate": 16000,
"sosTimeout": 7000,
"maxSpeechTimeout": 20000
}
}
},
"binary": null,
"expectedReplyTypes": [
"OPENJIBO_TURN_PENDING"
]
},
{
"text": null,
"binary": [
79,
103,
103,
83,
0,
2,
0,
0,
0,
0,
0,
0,
0,
0,
94,
132,
99,
103,
0,
0,
0,
0,
234,
141,
12,
246,
1,
19,
79,
112,
117,
115,
72,
101,
97,
100,
1,
1,
0,
0,
128,
62,
0,
0,
0,
0,
0
],
"expectedReplyTypes": [
"OPENJIBO_AUDIO_RECEIVED"
]
}
]
}

File diff suppressed because it is too large Load Diff