more version 18 test fixes
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"name": "neohubjibocom-neohubproactive-tidd36da4d442a611f1aba45cf821ea55ae",
|
||||
"session": {
|
||||
"hostName": "neo-hub.jibo.com",
|
||||
"path": "/v1/proactive",
|
||||
"kind": "neo-hub-proactive",
|
||||
"token": "hub-usr_openjibo_owner-1777340189867"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"text": {
|
||||
"type": "TRIGGER",
|
||||
"ts": 1777341970615,
|
||||
"msgID": "mid-d388c070-42a6-11f1-a414-5cf821ea55ae",
|
||||
"transID": "tid-d36da4d4-42a6-11f1-aba4-5cf821ea55ae",
|
||||
"data": {
|
||||
"triggerSource": "SURPRISE",
|
||||
"triggerData": {
|
||||
"looperID": "5c0b221fdf9d450019c5e255"
|
||||
}
|
||||
}
|
||||
},
|
||||
"binary": null,
|
||||
"expectedReplyTypes": []
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"type": "CONTEXT",
|
||||
"ts": 1777341970702,
|
||||
"msgID": "mid-d395f790-42a6-11f1-95f4-5cf821ea55ae",
|
||||
"transID": "tid-d36da4d4-42a6-11f1-aba4-5cf821ea55ae",
|
||||
"data": {
|
||||
"runtime": {
|
||||
"character": {
|
||||
"emotion": {
|
||||
"name": "NEUTRAL",
|
||||
"valence": 0.45,
|
||||
"confidence": 0.2
|
||||
},
|
||||
"motivation": {
|
||||
"social": 1,
|
||||
"playful": 0.5152989351851469
|
||||
}
|
||||
},
|
||||
"perception": {
|
||||
"speaker": "5c0b221fdf9d450019c5e255",
|
||||
"peoplePresent": [
|
||||
{
|
||||
"id": "NOT_TRAINED",
|
||||
"entityId": 16085,
|
||||
"type": "fused",
|
||||
"confidence": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"city": "Pleasant Hill",
|
||||
"state": "Missouri",
|
||||
"stateAbbr": "MO",
|
||||
"country": "United States",
|
||||
"countryCode": "US",
|
||||
"lat": 38.8358494,
|
||||
"lng": -94.1427229,
|
||||
"iso": "2026-04-27T21:06:10.626-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": []
|
||||
}
|
||||
]
|
||||
}
|
||||
5513
OpenJibo/artifact-output/jibo-test-26/jibo test 26.txt
Normal file
5513
OpenJibo/artifact-output/jibo-test-26/jibo test 26.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -21,14 +21,14 @@ Release `1.0.18` is now in feature-hardening. Its main bug-fix theme is alarm an
|
||||
|
||||
## Latest Live Evidence
|
||||
|
||||
`jibo test 25` was captured as a broader `1.0.18` regression pass after the `jibo test 24` alarm/photo fixes and the stop/volume feature slice.
|
||||
`jibo test 26` was captured as the next focused regression pass after the Test 25 stop/gallery/settings fixes.
|
||||
|
||||
- Cloud version, good night, good morning, time, joke, radio, news, Word of the Day, and several expressive/personality paths were still reachable. `good day` routed to date, which is acceptable unless a distinct good-day behavior is chosen later.
|
||||
- Backup-in-progress still appears at the start of every live session and blocks the settings update menu. The Test 25 HTTP capture again did not show `Backup_*` calls; observed cloud traffic was mostly log upload, ASR binary upload, and one `Update_20160301.GetUpdateFrom`. Treat this as a robot-local backup scheduler/status or log/upload load issue until a capture proves a hosted backup API path is involved.
|
||||
- Timer and alarm remain the riskiest current-release paths. Test 25 showed a timer prompt accepting partial speech, a stale 10-second timer state after reset, a `9:02` alarm being interpreted as the next local PM occurrence, and voice delete reporting success while the robot menu still retained an alarm. Current source fixes some prompt-tail and context handling issues from this run, but alarm set/delete/menu agreement still needs another focused live pass.
|
||||
- Photo/gallery blue-ring cleanup improved compared with earlier tests, but gallery yes/no could still hang. Test 25 showed `open the photogal` as the observed transcript and active `shared/yes_no` prompts under `@be/gallery`; current source now recognizes the gallery alias and keeps active local prompts live instead of treating that gallery context as passive noise.
|
||||
- Stop and volume first-pass behavior mostly reached the stock local paths, but exposed cleanup bugs. `Never mind.` included punctuation and mapped to generic chat; current source normalizes punctuation before stop/cancel matching. `Set Volume 2-6.` could pick the wrong number; current source treats that homophone shape as level `6`. `show volume controls` opened settings, then a passive local audio tail caused generic `I heard you`; current source treats `@be/settings` and `settings/volume_control` as local cleanup paths.
|
||||
- No dominant `ffmpeg` / `whisper.cpp` decode failure emerged from Test 25. Remaining short-answer failures should be split between cloud turn-state bugs, robot-local backup/load interference, and true STT misses.
|
||||
- Good morning worked, and the Test 25 stop fix was live-proven: `Never mind.` now mapped to stock stop instead of generic chat. The Test 25 volume homophone fix was also visible: `Set Volume 2-6.` mapped to `volume_to_value`.
|
||||
- Backup-in-progress still appeared during the test. Robot logs show the warning came from `@be/surprises-ota` (`hey since i'm doing a backup right now, I might be a little slow`), while the HTTP capture again had no `Backup_*` calls. Keep treating this as robot-local backup scheduler/status or log/upload load until a capture proves hosted backup involvement.
|
||||
- Photo/gallery mostly worked: `Open Photo Galerum.` launched gallery, empty-gallery `shared/yes_no` `Yes.` handed into create, the photo was taken, keeper `Yes.` saved it, and gallery reopened. The remaining gallery quirk was after cleanup: context-only or post-skill audio tails could keep buffering without a fresh `LISTEN`, producing a long blue ring and later generic fallback.
|
||||
- Alarm replacement/delete is still the main risky release path. Test 26 showed an existing `9:02 PM` alarm replacement prompt, but later `yes` turns arrived under `clock/alarm_set_value` rather than `clock/alarm_timer_change`, which pushed the robot toward the manual/value screen. The run eventually set a `7:35 PM` alarm, then repeated delete attempts such as `Delete along.`, `So, delete the alarm.`, and `So, delete the along.` fell to generic chat.
|
||||
- The blue-ring/listen-loop concern is real in the capture. Several transactions buffered binary audio for 15-50 seconds with no useful turn completion, especially when a context arrived without a new `LISTEN` or after a chat fallback kept follow-up open. Current source now blocks that no-`LISTEN` buffering path and clears blank-audio hotphrase state more aggressively.
|
||||
- No dominant `ffmpeg` / `whisper.cpp` decode failure emerged from Test 26. The remaining failures are mostly robot-local backup/load, short-answer STT quality, and alarm replacement/menu agreement.
|
||||
|
||||
## Release Rhythm
|
||||
|
||||
@@ -75,6 +75,8 @@ Current websocket scope:
|
||||
- passive local context cleanup for gallery/create/settings contexts after stock local skills take ownership
|
||||
- no-input local completion for constrained prompts, clock value prompts, gallery preview prompts, and settings volume-control prompts
|
||||
- active local prompt preservation so `shared/yes_no`, clock, gallery, and settings prompts can still consume transcript-bearing short replies even when the stock skill reports a local context
|
||||
- binary audio ignored for an existing transID until a fresh `LISTEN` has been seen, preventing context-only or post-speech tails from reopening an endless buffered turn
|
||||
- blank-audio hotphrase turns clear pending listen state and install a short late-audio ignore window
|
||||
- unknown inbound websocket types dropped silently instead of echoing stock-OS-unknown OpenJibo events
|
||||
- file telemetry and fixture export for HTTP, websocket, and turn captures
|
||||
|
||||
@@ -98,6 +100,8 @@ The following behavior is present in source and covered by focused tests:
|
||||
- volume commands emit stock `global_commands` volume intents: `volumeUp`, `volumeDown`, and `volumeToValue` with `volumeLevel`; `show volume controls` redirects to `@be/settings` `volumeQuery`
|
||||
- volume-to-value parsing handles the observed stock ASR homophone shape `Set Volume 2-6.` as level `6`
|
||||
- stock-shaped clock handoffs cover time, date, day, clock open, timer/alarm menu, timer/alarm value, timer/alarm clarification, and timer/alarm delete
|
||||
- alarm delete parsing handles `delete the alarm` plus the observed stock ASR mishears `delete along` / `delete the along`
|
||||
- clock delete/cancel handoffs do not keep a generic chat follow-up mic open or emit extra cloud speech after the local clock redirect
|
||||
- alarm parsing covers forms such as `7:30 am`, `830`, `8 30`, `7, 44`, `10-25`, `10:25 pm`, and `10 25 p m`
|
||||
- ambiguous alarm times can prefer the next local occurrence when the robot context includes `runtime.location.iso`
|
||||
- short clock value follow-up transcripts are accepted under `clock/alarm_set_value` and `clock/timer_set_value` instead of being dropped before parsing
|
||||
@@ -150,12 +154,12 @@ Before calling `1.0.18` complete, prove or explicitly defer these:
|
||||
- Run the focused `.NET` cloud test suite after the last feature slice.
|
||||
- Run the current-release live checklist in [regression-test-plan.md](regression-test-plan.md).
|
||||
- Confirm the running robot build reports cloud version `1.0.18`.
|
||||
- Regression test alarm flows again after the `jibo test 25` fixes: set with explicit time, set with compact/spoken/comma-separated time, clarify missing time, replace an existing alarm, cancel/delete by voice, cancel out of a value prompt, and verify the menu agrees.
|
||||
- Regression test alarm flows again after the `jibo test 26` fixes: set with explicit time, set with compact/spoken/comma-separated time, clarify missing time, replace an existing alarm, cancel/delete by voice including `delete the alarm`, cancel out of a value prompt, and verify the menu agrees.
|
||||
- Regression test timer flows after the Test 25 stale-timer observation: set a 10-second timer, let it fire, reset by gesture only after recording state, and verify a new timer prompt does not see an already-expired timer as still active.
|
||||
- Regression test photo/gallery flows again after the `jibo test 25` fixes: open gallery, answer the stock `shared/yes_no` prompt with a transcript-bearing `yes`, hand into create, take one photo, keep it, and avoid blue-ring or `I heard you` stale turns.
|
||||
- Regression test photo/gallery flows again after the `jibo test 26` fixes: open gallery, answer the stock `shared/yes_no` prompt with a transcript-bearing `yes`, hand into create, take one photo, keep it, and avoid blue-ring, `I heard you`, or `that's` stale turns after gallery cleanup.
|
||||
- Live-test radio launch: `open the radio` passed in `jibo test 22`; re-run `play country music` if that exact phrase was not captured.
|
||||
- Treat basic news as live-proven by `jibo test 23`; defer provider-backed or category-expanded news unless it is chosen as an optional feature slice.
|
||||
- Regression test the added stop and volume slices after the Test 25 fixes: `stop that`, `never mind`, `turn it up`, `turn it down`, `set volume to six`, `set volume to 6`, and `show volume controls`.
|
||||
- Regression test the added stop and volume slices after the Test 26 fixes: `stop that`, `never mind`, `turn it up`, `turn it down`, `set volume to six`, `set volume to 6`, and `show volume controls`.
|
||||
- Recheck constrained yes/no prompts for update/backup/share/gallery/alarm replacement without leaking global rules.
|
||||
- Recheck that stock OS no longer logs OpenJibo-only websocket events such as synthetic pending/context/ack packets from the current build.
|
||||
- Recheck backup/update behavior with explicit attention to robot-local `jibo.scheduler.backupStatus`, CPU/load, log/upload activity, and whether the deployed cloud is involved at all.
|
||||
@@ -169,12 +173,12 @@ These are not blockers for calling `1.0.18` complete unless the live test shows
|
||||
- media upload/body handling is not binary-safe enough for final gallery originals and thumbnails
|
||||
- state persistence is local JSON, not Azure SQL / Blob Storage
|
||||
- update, backup, and restore are not end-to-end proven, and the `jibo test 22` sluggishness appears tied to robot-local backup status/load
|
||||
- Test 25 still showed repeated backup-in-progress behavior and update-menu blockage without corresponding `Backup_*` HTTP traffic
|
||||
- Test 26 still showed repeated backup-in-progress behavior without corresponding `Backup_*` HTTP traffic
|
||||
- deployed-build verification needs to prove that synthetic OpenJibo websocket events are gone from the hosted artifact, not just from source
|
||||
- news content is synthetic; `jibo test 23` proved the path but not live provider-backed headlines
|
||||
- gallery `shared/yes_no`, settings volume-control cleanup, and punctuated `never mind` still need successful live proof after the Test 25 source fixes
|
||||
- alarm replacement yes/no, alarm voice delete/menu agreement, and long blue-ring cleanup still need successful live proof after the Test 26 source fixes
|
||||
- weather, calendar, commute, personal report, identity, memory, and proactivity are still mostly discovery or placeholder content paths
|
||||
- stop and volume are implemented but still need live stock-OS proof; robot age and command-versus-question personality routing are not implemented yet
|
||||
- remaining stop/volume variants still need live stock-OS proof beyond Test 26's `Never mind.` and `Set Volume 2-6.` passes; robot age and command-versus-question personality routing are not implemented yet
|
||||
|
||||
## `1.0.19` Direction
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ Current release theme:
|
||||
- `jibo test 23` validated basic news, proved one alarm set/fire path at `7:43 AM`, exposed comma-separated/short alarm follow-up parsing risk, showed stock alarm replacement yes/no rules that needed cloud handling, and showed photo gallery still failing when `shared/yes_no` ASR came back empty
|
||||
- `jibo test 24` showed alarm replacement yes/no working, but exposed empty `clock/alarm_set_value` and `gallery/gallery_preview` turns falling into generic `I heard you` fallback speech; it also showed `CLIENT_NLU cancel` inside `clock/alarm_set_value` re-asking for an alarm value instead of closing the prompt
|
||||
- `jibo test 25` proved a broader regression path but exposed repeated backup-in-progress/update-menu blockage, timer/alarm stale state and delete/menu disagreement, gallery `shared/yes_no` hangs under `@be/gallery`, punctuated `Never mind.` falling through to chat, volume homophone parsing (`Set Volume 2-6.`), and settings volume-control cleanup falling into `I heard you`
|
||||
- `jibo test 26` live-proved punctuated stop, volume homophone parsing, gallery launch/yes/create/save, and good morning; it still exposed robot-local backup warnings, long blue-ring buffering without a fresh `LISTEN`, alarm replacement drifting into the value/manual screen, and alarm delete phrases/mishears falling to chat
|
||||
|
||||
## Immediate `1.0.18` Queue
|
||||
|
||||
@@ -101,10 +102,12 @@ Current release theme:
|
||||
- Latest evidence:
|
||||
- `jibo test 22` did not show `Backup_*` HTTP traffic during the backup complaint
|
||||
- `jibo test 25` again showed backup-in-progress/update-menu blockage without `Backup_*` HTTP traffic; observed cloud traffic was log upload, ASR binary upload, and update check traffic
|
||||
- `jibo test 26` again had the robot announce backup-in-progress from `@be/surprises-ota`, with no `Backup_*` HTTP target in the capture
|
||||
- stock `@be/surprises-ota` drives the backup notification from robot-local `jibo.scheduler.backupStatus`
|
||||
- original `surprises-ota` tests make backup and OTA notifications contextual-priority prompts, with repeat suppression through last-notification timestamps
|
||||
- a spoken `take a backup` command currently routes as generic chat and is not the same as proving the local backup scheduler path
|
||||
- `jibo test 23` and `jibo test 25` showed backup-in-progress sluggishness and update-menu blockage while backups were active; explicit backup voice launch remains unwired
|
||||
- `jibo test 23`, `jibo test 25`, and `jibo test 26` showed backup-in-progress sluggishness or warnings while backups were active; explicit backup voice launch remains unwired
|
||||
- Test 26 suggests this should be investigated beside robot-local scheduler status and log/upload load rather than only hosted backup APIs
|
||||
- Exit criteria:
|
||||
- spoken `yes` and `no` work on update, backup, share/offer, and gallery/create prompts
|
||||
- empty or missed short replies retry locally instead of relaunching Nimbus or generic chat
|
||||
@@ -129,6 +132,8 @@ Current release theme:
|
||||
- empty `gallery/gallery_preview` turns complete locally as no-input instead of relaunching Nimbus fallback speech
|
||||
- passive gallery/create/settings context no longer reopens stale cloud turns
|
||||
- active local prompts under gallery/settings contexts are preserved so real short replies are not suppressed as passive context
|
||||
- context-only or post-skill binary audio tails are ignored until a fresh `LISTEN`, preventing no-`LISTEN` blue-ring buffering loops
|
||||
- blank-audio hotphrase turns clear pending listen state and install a short late-audio ignore window
|
||||
- `shared/yes_no` no-input fallback and repeated create keeper cleanup were added after `jibo test 22`
|
||||
- Latest evidence:
|
||||
- gallery opened and handed into create, but repeated `create/is_it_a_keeper` prompts could leave the blue ring/listening state
|
||||
@@ -140,6 +145,8 @@ Current release theme:
|
||||
- `jibo test 24` showed photo/gallery blue-ring cleanup improved and create keeper completion working, but empty `gallery/gallery_preview` produced `I heard you`; current source now keeps that as local no-input
|
||||
- `jibo test 25` showed gallery launching from the observed phrase `open the photogal`, but active `shared/yes_no` prompts under `@be/gallery` could hang; current source now recognizes the alias and preserves active gallery prompts even while ignoring passive gallery tails
|
||||
- `jibo test 25` showed timer/alarm still needs live follow-up for stale timer state, alarm replacement/PM ambiguity, and voice delete versus robot menu agreement
|
||||
- `jibo test 26` showed gallery success through empty-gallery yes, create, keep, save, and reopen, but also showed a post-gallery blue-ring/fallback tail now addressed by the no-`LISTEN` binary guard
|
||||
- `jibo test 26` showed alarm replacement still drifting into value/manual-screen behavior and alarm delete phrases/mishears falling to chat; current source now maps `delete the alarm`, `delete along`, and `delete the along` to local clock delete without keeping follow-up open
|
||||
- original clock tests confirm cancel inside the alarm value prompt must close without scheduling, existing-alarm `keep` must preserve KB/scheduler state, and existing-alarm `delete` or `cancel` must clear it
|
||||
- original gallery tests confirm empty-gallery `yes` redirects to `@be/create`, empty-gallery `no` exits, media-load failure exits, and delete confirmation only deletes on a positive `yes`
|
||||
- Exit criteria:
|
||||
@@ -166,10 +173,12 @@ Current release theme:
|
||||
- stop/cancel matching now normalizes stock ASR punctuation, so `Never mind.` is still a stop command
|
||||
- absolute volume parsing now treats the observed homophone shape `Set Volume 2-6.` as level `6`
|
||||
- passive settings context and `settings/volume_control` no-input cleanup now avoid post-panel `I heard you` fallback speech
|
||||
- local clock delete/cancel commands now settle without a generic follow-up mic
|
||||
- Evidence:
|
||||
- Pegasus `globals/global_commands_launch.rule` defines `stop`, `volumeUp`, `volumeDown`, and `volumeToValue`
|
||||
- stock Jibo `VolumePlugin` subscribes to global volume events and uses the same intent/entity names
|
||||
- stock `@be/settings` exposes `volumeQuery` and opens the volume panel
|
||||
- `jibo test 26` live-proved punctuated `Never mind.` and the `Set Volume 2-6.` homophone path
|
||||
- Exit criteria:
|
||||
- live stop settles the robot without a generic chat reply
|
||||
- live volume up/down audibly changes volume or logs a local volume event
|
||||
@@ -225,7 +234,7 @@ Current release theme:
|
||||
- Follow-up:
|
||||
- live regression remains in the immediate queue
|
||||
- add fixture coverage for original clock-test branches that are not yet mirrored in `.NET`: no-alarm query `yes`/`no`, existing-alarm `keep` versus `delete`, and cross-domain `OtherSet` behavior
|
||||
- Test 25 still requires a focused live check for timer stale state and alarm voice delete versus menu state
|
||||
- Test 26 still requires a focused live check for alarm replacement, voice delete versus menu state, and whether the no-`LISTEN` guard removes the long blue-ring loop
|
||||
|
||||
### Photo / Gallery / Create Family
|
||||
|
||||
@@ -352,6 +361,7 @@ Current release theme:
|
||||
- original OTA surprise tests treat backup/download status as robot-local scheduler state, not as a direct cloud backup command path
|
||||
- no-op update fabrication has been removed from `.NET`
|
||||
- Test 25 still showed repeated backup-in-progress/update-menu blockage without `Backup_*` HTTP traffic
|
||||
- Test 26 repeated the backup-in-progress warning from robot-local `@be/surprises-ota` without `Backup_*` HTTP traffic
|
||||
- Exit criteria:
|
||||
- no phantom "always has updates" behavior
|
||||
- one controlled update can be staged and delivered
|
||||
@@ -369,6 +379,7 @@ Current release theme:
|
||||
- `jibo test 23` did not show the same decode failure pattern, but gallery yes/no turns still produced empty ASR
|
||||
- `jibo test 24` still had collapsed or empty transcripts in alarm/gallery paths, including `Sudden alarm.`, `I'm setting alarm for seven.`, empty clock value input, and empty gallery preview input
|
||||
- `jibo test 25` still had short-answer failures, but several were cloud turn-state issues now patched rather than pure STT failures
|
||||
- `jibo test 26` had long no-`LISTEN` binary buffering and alarm-delete mishears now patched; remaining short-answer failures still need STT/noise work
|
||||
- current source now skips local whisper when buffered audio does not contain an Opus identification header
|
||||
- yes/no and alarm flows are especially sensitive to short or collapsed transcripts
|
||||
- Implementation notes:
|
||||
|
||||
@@ -15,7 +15,7 @@ Run this plan:
|
||||
- after the last code change before calling a release complete
|
||||
- after any fix that touches websocket turn finalization, local skill redirects, constrained yes/no, or STT
|
||||
- before moving from `1.0.18` bug-fix closeout into `1.0.19` feature work
|
||||
- after the Test 25 fixes, run at least the focused alarm/timer, photo/gallery, stop, and volume sections before deciding whether `1.0.18` is ready to freeze
|
||||
- after the Test 26 fixes, run at least the focused alarm/timer, photo/gallery, stop, volume, and blue-ring cleanup sections before deciding whether `1.0.18` is ready to freeze
|
||||
|
||||
For small feature slices, run the automated `.NET` tests plus the smoke checks and only the live sections that share the same machinery. Before release closeout, run the full current-release suite.
|
||||
|
||||
@@ -93,6 +93,7 @@ Goal: prove constrained yes/no prompts stay local and do not leak global launch
|
||||
- Observe backup-in-progress behavior separately from explicit voice commands.
|
||||
- Do not treat a spoken `take a backup` failure as proof of the backup scheduler path; that command is not currently wired as a hosted-cloud voice feature.
|
||||
- If the update menu reports backup-in-progress, record whether HTTP captures include any `Backup_*` targets; current evidence points to robot-local scheduler/status or log/upload load unless those calls appear.
|
||||
- If Jibo announces backup-in-progress without update-menu interaction, note the local skill in robot logs; Test 26 showed `@be/surprises-ota`.
|
||||
- Expected: short `yes`/`no` replies map locally, empty replies no-input locally, and backup/download notifications are not repeatedly re-announced once acknowledged.
|
||||
- Capture check: active rule remains the constrained rule such as `surprises-ota/want_to_download_now`, `settings/download_now_later`, `shared/yes_no`, or another stock prompt rule.
|
||||
|
||||
@@ -110,6 +111,7 @@ Test these paths:
|
||||
- replacement: with an alarm already set, set a different alarm and answer the replacement prompt; verify whether the answer kept or replaced the old alarm
|
||||
- value-prompt cancel: `set an alarm`, then say `cancel`
|
||||
- voice delete: `delete my alarm` or `cancel alarm`
|
||||
- voice delete variants from Test 26: `delete the alarm`, `delete alarm`, and, if ASR mishears it, record whether `delete along` maps to local clock delete
|
||||
- no-input cleanup: allow one value prompt to miss or time out when practical
|
||||
- timer sanity: `set a timer for 10 seconds`, let it fire or record the exact remaining state, then verify a second timer request does not report a stale already-running timer
|
||||
|
||||
@@ -119,6 +121,7 @@ Expected:
|
||||
- replacement prompt answer changes or preserves the alarm consistently with the robot's question
|
||||
- `cancel` inside the value prompt closes without scheduling
|
||||
- voice delete clears the robot menu state
|
||||
- local clock delete/cancel settles without generic chat speech or an open follow-up blue ring
|
||||
- timer state agrees with what just happened on the robot; a reset gesture should not leave a phantom active timer in the next prompt
|
||||
- empty value prompt turns complete locally instead of generic `I heard you` speech
|
||||
|
||||
@@ -147,6 +150,7 @@ Expected:
|
||||
- empty gallery `yes` redirects to `@be/create`
|
||||
- empty gallery `no` exits cleanly when tested
|
||||
- keeper `yes` completes and Jibo settles without a stale blue ring
|
||||
- after gallery settles, context-only tails do not produce delayed generic replies such as `that's` or `I didn't hear you`
|
||||
- transcript-bearing `yes` under gallery `shared/yes_no` is consumed even when the robot reports `@be/gallery` context
|
||||
- empty `shared/yes_no`, `create/is_it_a_keeper`, and `gallery/gallery_preview` turns no-input locally instead of generic `I heard you`
|
||||
- delete confirmation only deletes on a positive `yes`
|
||||
@@ -157,6 +161,7 @@ Capture check:
|
||||
- create photo redirects to `@be/create/createOnePhoto`
|
||||
- local no-input replies keep the active constrained rule and strip unrelated global launch rules
|
||||
- active `shared/yes_no` is not suppressed merely because the current context is `@be/gallery`
|
||||
- post-gallery binary audio does not continue buffering unless a fresh `LISTEN` appears
|
||||
|
||||
### STT And Audio Quality
|
||||
|
||||
@@ -208,6 +213,15 @@ Capture check:
|
||||
- volume controls redirects to `@be/settings` with `nlu.intent = volumeQuery`
|
||||
- passive `@be/settings` / `settings/volume_control` audio tails complete locally and do not reopen Nimbus fallback speech
|
||||
|
||||
### Blue-Ring Cleanup
|
||||
|
||||
Goal: catch the Test 26 no-`LISTEN` buffering regression quickly.
|
||||
|
||||
- After any local skill redirect or generic chat reply, wait five to ten seconds before issuing the next phrase.
|
||||
- If the blue ring remains open, record the active transID and whether the websocket capture shows a new `LISTEN`.
|
||||
- Expected: binary audio for an existing transID is ignored until a fresh `LISTEN` appears; blank hotphrase turns clear instead of buffering indefinitely.
|
||||
- Capture check: long-running context-only transactions should not accumulate buffered audio chunks or stay `AwaitingTurnCompletion = true`.
|
||||
|
||||
## Optional Feature Slice Checks
|
||||
|
||||
When a new feature is added before a release closes:
|
||||
|
||||
@@ -86,6 +86,10 @@ public sealed class DemoConversationBroker(JiboInteractionService interactionSer
|
||||
"clock_menu" => false,
|
||||
"timer_menu" => false,
|
||||
"alarm_menu" => false,
|
||||
"timer_delete" => false,
|
||||
"alarm_delete" => false,
|
||||
"timer_cancel" => false,
|
||||
"alarm_cancel" => false,
|
||||
"timer_value" => false,
|
||||
"alarm_value" => false,
|
||||
"photo_gallery" => false,
|
||||
|
||||
@@ -350,13 +350,7 @@ public sealed class JiboInteractionService(
|
||||
return "alarm_menu";
|
||||
}
|
||||
|
||||
if (MatchesAny(
|
||||
loweredTranscript,
|
||||
"cancel alarm",
|
||||
"delete alarm",
|
||||
"remove alarm",
|
||||
"stop alarm",
|
||||
"turn off alarm"))
|
||||
if (IsAlarmDeleteRequest(loweredTranscript))
|
||||
{
|
||||
return "alarm_delete";
|
||||
}
|
||||
@@ -1214,6 +1208,12 @@ public sealed class JiboInteractionService(
|
||||
"how s your volume");
|
||||
}
|
||||
|
||||
private static bool IsAlarmDeleteRequest(string loweredTranscript)
|
||||
{
|
||||
var normalizedTranscript = NormalizeCommandPhrase(loweredTranscript);
|
||||
return AlarmDeletePattern.IsMatch(normalizedTranscript);
|
||||
}
|
||||
|
||||
private static bool IsVolumeUpRequest(string loweredTranscript)
|
||||
{
|
||||
return MatchesAny(
|
||||
@@ -1521,6 +1521,10 @@ public sealed class JiboInteractionService(
|
||||
@"\s+",
|
||||
RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex AlarmDeletePattern = new(
|
||||
@"\b(?:cancel|delete|remove|stop|turn\s+off)\s+(?:the\s+)?(?:alarm|along|elo)\b",
|
||||
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
||||
|
||||
private static readonly (string Phrase, string Station)[] RadioGenreAliases =
|
||||
[
|
||||
("country music", "Country"),
|
||||
|
||||
@@ -37,10 +37,7 @@ public sealed partial class WebSocketTurnFinalizationService(
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var turnState = session.TurnState;
|
||||
if (ShouldIgnoreLateAudio(session) || !turnState.AwaitingTurnCompletion &&
|
||||
!session.FollowUpOpen &&
|
||||
!turnState.SawListen &&
|
||||
!string.IsNullOrWhiteSpace(turnState.TransId))
|
||||
if (ShouldIgnoreLateAudio(session) || ShouldIgnoreAudioWithoutListen(turnState))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
@@ -334,7 +331,11 @@ public sealed partial class WebSocketTurnFinalizationService(
|
||||
if (ShouldIgnoreBlankAudioHotphraseTurn(turn))
|
||||
{
|
||||
session.TurnState.AwaitingTurnCompletion = false;
|
||||
session.TurnState.IgnoreAdditionalAudioUntilUtc = DateTimeOffset.UtcNow.Add(WebSocketTurnState.DefaultLateAudioIgnoreWindow);
|
||||
session.FollowUpExpiresUtc = null;
|
||||
ResetBufferedAudio(session);
|
||||
session.TurnState.SawListen = false;
|
||||
session.TurnState.SawContext = false;
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -502,6 +503,8 @@ public sealed partial class WebSocketTurnFinalizationService(
|
||||
!string.Equals(plan.IntentName, "clock_menu", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.Equals(plan.IntentName, "timer_menu", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.Equals(plan.IntentName, "alarm_menu", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.Equals(plan.IntentName, "timer_delete", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.Equals(plan.IntentName, "alarm_delete", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.Equals(plan.IntentName, "timer_cancel", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.Equals(plan.IntentName, "alarm_cancel", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.Equals(plan.IntentName, "timer_clarify", StringComparison.OrdinalIgnoreCase) &&
|
||||
@@ -544,6 +547,12 @@ public sealed partial class WebSocketTurnFinalizationService(
|
||||
ignoreUntilUtc.Value > DateTimeOffset.UtcNow;
|
||||
}
|
||||
|
||||
private static bool ShouldIgnoreAudioWithoutListen(WebSocketTurnState turnState)
|
||||
{
|
||||
return !turnState.SawListen &&
|
||||
!string.IsNullOrWhiteSpace(turnState.TransId);
|
||||
}
|
||||
|
||||
private static bool ShouldIgnorePassiveLocalSkillContext(CloudSession session, string? text)
|
||||
{
|
||||
if (session.FollowUpOpen)
|
||||
|
||||
@@ -697,6 +697,27 @@ public sealed class JiboInteractionServiceTests
|
||||
Assert.Equal("delete", decision.SkillPayload["clockIntent"]);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("delete the alarm")]
|
||||
[InlineData("so, delete the alarm")]
|
||||
[InlineData("delete along")]
|
||||
[InlineData("so, delete the along")]
|
||||
public async Task BuildDecisionAsync_DeleteAlarmVariants_MapsToClockDeleteIntent(string transcript)
|
||||
{
|
||||
var service = CreateService();
|
||||
|
||||
var decision = await service.BuildDecisionAsync(new TurnContext
|
||||
{
|
||||
RawTranscript = transcript,
|
||||
NormalizedTranscript = transcript
|
||||
});
|
||||
|
||||
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_ClientNluSetAlarmWithoutTime_AsksForClarification()
|
||||
{
|
||||
|
||||
@@ -730,7 +730,7 @@ public sealed class JiboWebSocketServiceTests
|
||||
Text = """{"type":"CLIENT_ASR","transID":"trans-clock-cancel-alarm","data":{"text":"cancel alarm"}}"""
|
||||
});
|
||||
|
||||
Assert.Equal(5, replies.Count);
|
||||
Assert.Equal(4, replies.Count);
|
||||
|
||||
using var listenPayload = JsonDocument.Parse(replies[0].Text!);
|
||||
Assert.Equal("delete", listenPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("intent").GetString());
|
||||
@@ -739,6 +739,10 @@ public sealed class JiboWebSocketServiceTests
|
||||
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());
|
||||
|
||||
var session = _store.FindSessionByToken("hub-clock-cancel-alarm-token");
|
||||
Assert.NotNull(session);
|
||||
Assert.False(session.FollowUpOpen);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -2264,6 +2268,102 @@ public sealed class JiboWebSocketServiceTests
|
||||
});
|
||||
|
||||
Assert.Empty(replies);
|
||||
|
||||
var session = _store.FindSessionByToken("hub-blank-audio-token");
|
||||
Assert.NotNull(session);
|
||||
Assert.False(session.TurnState.AwaitingTurnCompletion);
|
||||
Assert.False(session.TurnState.SawListen);
|
||||
Assert.True(session.TurnState.IgnoreAdditionalAudioUntilUtc.HasValue);
|
||||
|
||||
var binaryReplies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||
{
|
||||
HostName = "neo-hub.jibo.com",
|
||||
Path = "/listen",
|
||||
Kind = "neo-hub-listen",
|
||||
Token = "hub-blank-audio-token",
|
||||
Binary = new byte[4096]
|
||||
});
|
||||
|
||||
Assert.Empty(binaryReplies);
|
||||
Assert.Equal(0, session.TurnState.BufferedAudioBytes);
|
||||
Assert.Equal(0, session.TurnState.BufferedAudioChunkCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ContextWithoutListen_DuringFollowUp_DoesNotBufferAudio()
|
||||
{
|
||||
var helloReplies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||
{
|
||||
HostName = "neo-hub.jibo.com",
|
||||
Path = "/listen",
|
||||
Kind = "neo-hub-listen",
|
||||
Token = "hub-context-no-listen-token",
|
||||
Text = """{"type":"LISTEN","transID":"trans-context-no-listen-hello","data":{"text":"hello","rules":["launch","globals/global_commands_launch"]}}"""
|
||||
});
|
||||
|
||||
Assert.Equal(3, helloReplies.Count);
|
||||
|
||||
var session = _store.FindSessionByToken("hub-context-no-listen-token");
|
||||
Assert.NotNull(session);
|
||||
Assert.True(session.FollowUpOpen);
|
||||
|
||||
var contextReplies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||
{
|
||||
HostName = "neo-hub.jibo.com",
|
||||
Path = "/listen",
|
||||
Kind = "neo-hub-listen",
|
||||
Token = "hub-context-no-listen-token",
|
||||
Text = """{"type":"CONTEXT","transID":"trans-context-no-listen-tail","data":{"skill":{"id":null}}}"""
|
||||
});
|
||||
|
||||
Assert.Empty(contextReplies);
|
||||
Assert.False(session.TurnState.SawListen);
|
||||
|
||||
for (var index = 0; index < 6; index += 1)
|
||||
{
|
||||
var binaryReplies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||
{
|
||||
HostName = "neo-hub.jibo.com",
|
||||
Path = "/listen",
|
||||
Kind = "neo-hub-listen",
|
||||
Token = "hub-context-no-listen-token",
|
||||
Binary = new byte[4096]
|
||||
});
|
||||
|
||||
Assert.Empty(binaryReplies);
|
||||
}
|
||||
|
||||
Assert.False(session.TurnState.AwaitingTurnCompletion);
|
||||
Assert.Equal(0, session.TurnState.BufferedAudioBytes);
|
||||
Assert.Equal(0, session.TurnState.BufferedAudioChunkCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Listen_DeleteTheAlarm_UsesLocalClockWithoutKeepingFollowUpOpen()
|
||||
{
|
||||
var replies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||
{
|
||||
HostName = "neo-hub.jibo.com",
|
||||
Path = "/listen",
|
||||
Kind = "neo-hub-listen",
|
||||
Token = "hub-delete-the-alarm-token",
|
||||
Text = """{"type":"LISTEN","transID":"trans-delete-the-alarm","data":{"text":"So, delete the alarm.","rules":["launch","globals/global_commands_launch"]}}"""
|
||||
});
|
||||
|
||||
Assert.Equal(4, replies.Count);
|
||||
Assert.Equal("LISTEN", ReadReplyType(replies[0]));
|
||||
Assert.Equal("EOS", ReadReplyType(replies[1]));
|
||||
Assert.Equal("SKILL_REDIRECT", ReadReplyType(replies[2]));
|
||||
Assert.Equal("SKILL_ACTION", ReadReplyType(replies[3]));
|
||||
|
||||
using var listenPayload = JsonDocument.Parse(replies[0].Text!);
|
||||
Assert.Equal("delete", listenPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("intent").GetString());
|
||||
Assert.Equal("@be/clock", listenPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("skill").GetString());
|
||||
Assert.Equal("alarm", listenPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("entities").GetProperty("domain").GetString());
|
||||
|
||||
var session = _store.FindSessionByToken("hub-delete-the-alarm-token");
|
||||
Assert.NotNull(session);
|
||||
Assert.False(session.FollowUpOpen);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -2695,7 +2795,7 @@ public sealed class JiboWebSocketServiceTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task NewTransId_OnContext_ResetsStaleBufferedAudioBeforeFollowUpTurn()
|
||||
public async Task NewTransId_OnContext_LeavesNoStaleBufferedAudioBeforeFollowUpTurn()
|
||||
{
|
||||
await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||
{
|
||||
@@ -2744,7 +2844,7 @@ public sealed class JiboWebSocketServiceTests
|
||||
|
||||
var session = _store.FindSessionByToken("hub-context-reset-token");
|
||||
Assert.NotNull(session);
|
||||
Assert.Equal(4, session.TurnState.BufferedAudioBytes);
|
||||
Assert.Equal(0, session.TurnState.BufferedAudioBytes);
|
||||
|
||||
var contextReplies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user