Skip to content

Commit 4512dc2

Browse files
Fix indoor cycling detection - support both 'indoor cycling' and 'cycling indoor' word orders
1 parent 1f3d3ae commit 4512dc2

File tree

2 files changed

+327
-3
lines changed

2 files changed

+327
-3
lines changed

examples/whisper.android/app/src/main/java/com/whispercppdemo/intent/SlotExtractor.kt

Lines changed: 169 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,147 @@ data class SlotExtractionResult(
1515

1616
class SlotExtractor {
1717

18+
// Activity type to number mapping based on SportActivityName enum
19+
private val activityNumberMap = mapOf(
20+
"indoor running" to 3,
21+
"treadmill" to 66,
22+
"outdoor walking" to 2,
23+
"outdoor running" to 1,
24+
"trekking" to 4,
25+
"trail running" to 5,
26+
"hunting" to 15,
27+
"fishing" to 36,
28+
"skateboarding" to 17,
29+
"fencing" to 102,
30+
"boxing" to 56,
31+
"tai chi" to 59,
32+
"outdoor cycling" to 6,
33+
"indoor cycling" to 7,
34+
"bmx" to 14,
35+
"curling" to 37,
36+
"outdoor skating" to 19,
37+
"indoor skating" to 38,
38+
"archery" to 65,
39+
"equestrian" to 20,
40+
"cricket" to 217,
41+
"basketball" to 9,
42+
"badminton" to 12,
43+
"outdoor hiking" to 13,
44+
"golf" to 134,
45+
"football" to 10,
46+
"ballet" to 47,
47+
"square dance" to 49,
48+
"zumba" to 53,
49+
"mixed aerobics" to 24,
50+
"strength training" to 25,
51+
"stretching" to 26,
52+
"indoor fitness" to 30,
53+
"elliptical machine" to 34,
54+
"yoga" to 35,
55+
"climbing machine" to 27,
56+
"flexibility training" to 29,
57+
"stepper" to 31,
58+
"step training" to 32,
59+
"gymnastics" to 33,
60+
"freestyle" to 8,
61+
"core training" to 23,
62+
"sailing" to 16,
63+
"roller skating" to 18,
64+
"baseball" to 40,
65+
"bowling" to 41,
66+
"squash" to 42,
67+
"softball" to 43,
68+
"croquet" to 44,
69+
"volleyball" to 45,
70+
"handball" to 46,
71+
"pingpong" to 11,
72+
"belly dance" to 48,
73+
"street dance" to 50,
74+
"ballroom dancing" to 51,
75+
"dance" to 52,
76+
"cross training crossfit" to 84,
77+
"karate" to 55,
78+
"judo" to 57,
79+
"wrestling" to 58,
80+
"muay thai" to 60,
81+
"taekwondo" to 61,
82+
"martial arts" to 62,
83+
"free sparring" to 63,
84+
"pool swimming" to 200,
85+
"rope skipping" to 122,
86+
"rowing machine" to 121,
87+
"open water" to 201,
88+
"triathlon" to 123,
89+
"kendo" to 54,
90+
"pilates" to 28,
91+
"functional training" to 94,
92+
"sit ups" to 93,
93+
"dumbbell training" to 88,
94+
"barbell training" to 89,
95+
"weightlifting" to 90,
96+
"hiit" to 64,
97+
"deadlift" to 91,
98+
"darts" to 114,
99+
"frisbee" to 118,
100+
"kite flying" to 117,
101+
"tug of war" to 115,
102+
"paddleboard surfing" to 132,
103+
"double board skiing" to 130,
104+
"paddle board" to 67,
105+
"water polo" to 68,
106+
"water sports" to 69,
107+
"water skiing" to 70,
108+
"kayaking" to 71,
109+
"kayak rafting" to 72,
110+
"motorboat" to 73,
111+
"fin swimming" to 74,
112+
"diving" to 75,
113+
"synchronized swimming" to 76,
114+
"snorkeling" to 77,
115+
"kite surfing" to 78,
116+
"rock climbing" to 79,
117+
"parkour" to 80,
118+
"atv" to 81,
119+
"paraglider" to 82,
120+
"climb the stairs" to 83,
121+
"aerobics" to 85,
122+
"physical training" to 86,
123+
"wall ball" to 87,
124+
"bobby jump" to 92,
125+
"upper limb training" to 95,
126+
"lower limb training" to 96,
127+
"waist and abdomen training" to 97,
128+
"back training" to 98,
129+
"national dance" to 99,
130+
"jazz dance" to 100,
131+
"latin dance" to 101,
132+
"rugby" to 103,
133+
"hockey" to 104,
134+
"tennis" to 105,
135+
"billiards" to 106,
136+
"sepak takraw" to 108,
137+
"snow sports" to 109,
138+
"snowmobile" to 110,
139+
"puck" to 111,
140+
"snow car" to 112,
141+
"sled" to 113,
142+
"hula hoop" to 116,
143+
"track and field" to 119,
144+
"racing car" to 120,
145+
"mountain cycling" to 124,
146+
"kickboxing" to 125,
147+
"skiing" to 126,
148+
"cross country skiing" to 127,
149+
"snowboarding" to 128,
150+
"alpine skiing" to 129,
151+
"free exercise" to 131,
152+
"kabaddi" to 133,
153+
"indoor walking" to 135,
154+
"table football" to 136,
155+
"seven stones" to 137,
156+
"kho kho" to 138
157+
)
158+
18159
private val intentSlotTemplates = mapOf(
19160
"QueryPoint" to listOf("metric"), // time_ref, unit, and identifier can have defaults
20161
"SetGoal" to listOf("metric", "target"), // unit can be inferred
@@ -356,6 +497,7 @@ class SlotExtractor {
356497
"action" -> extractAction(originalText)
357498
"tool" -> extractTool(originalText)
358499
"activity_type" -> extractActivityType(originalText)
500+
"activity_number" -> extractActivityNumber(originalText)
359501
"app" -> extractApp(originalText)
360502
"contact" -> extractContact(originalText)
361503
"location" -> extractLocation(originalText)
@@ -1344,7 +1486,7 @@ class SlotExtractor {
13441486
val activities = mapOf(
13451487
"outdoor running" to "\\b(?<!indoor\\s)(?:outdoor\\s+)?(?:run|running|ran|jog|jogging|jogged|sprint|sprinting|sprinted|dash|dashing|race|racing|trail\\s+run|trail\\s+running|distance\\s+run|long\\s+run|short\\s+run|tempo\\s+run|interval\\s+run|fartlek|road\\s+run|cross\\s+country|marathon|half\\s+marathon|5k|10k|runner|runners|pace|pacing|stride|striding|gallop|galloping|bound|bounding|hurdle|hurdling|relay|relays|track\\s+running|road\\s+racing|fun\\s+run|charity\\s+run|morning\\s+run|evening\\s+run|daily\\s+run|weekly\\s+run|cardio\\s+run|fitness\\s+run|outdoor\\s+jog|park\\s+run|street\\s+running|pavement\\s+running|sidewalk\\s+running|neighborhood\\s+run|community\\s+run|group\\s+run|solo\\s+run|recreational\\s+running|competitive\\s+running|distance\\s+running|endurance\\s+running|speed\\s+work)\\b",
13461488

1347-
"indoor cycling" to "\\b(?<!outdoor\\s)indoor\\s+(?:cycling|cycle|cycled|bike|biking|biked|bicycle|bicycling|spin|spinning|spin\\s+class|stationary\\s+bike|exercise\\s+bike|bike\\s+ride|pedal|pedaling|pedalled|indoor\\s+bike|cycle\\s+class|RPM|cadence|peloton|zwift|virtual\\s+cycling|turbo\\s+trainer|trainer\\s+ride)\\b",
1489+
"indoor cycling" to "\\b(?<!outdoor\\s)indoor\\s+(?:cycling|cycle|cycled|bike|biking|biked|bicycle|bicycling|spin|spinning|spin\\s+class|stationary\\s+bike|exercise\\s+bike|bike\\s+ride|pedal|pedaling|pedalled|indoor\\s+bike|cycle\\s+class|RPM|cadence|peloton|zwift|virtual\\s+cycling|turbo\\s+trainer|trainer\\s+ride|cycling indoor)\\b",
13481490

13491491
"yoga" to "\\b(?:yoga|yogi|asana|asanas|meditation|meditate|meditating|meditated|stretch|stretching|stretched|flexibility|vinyasa|hatha|ashtanga|bikram|hot\\s+yoga|power\\s+yoga|yin\\s+yoga|restorative\\s+yoga|pranayama|breathing\\s+exercise|mindfulness|zen|namaste|downward\\s+dog|warrior\\s+pose|sun\\s+salutation|flow|yoga\\s+flow|kundalini|iyengar|anusara|kripalu|sivananda|gentle\\s+yoga|beginner\\s+yoga|advanced\\s+yoga|therapeutic\\s+yoga|chair\\s+yoga|wall\\s+yoga|aerial\\s+yoga|yoga\\s+nidra|relaxation\\s+yoga|spiritual\\s+yoga|classical\\s+yoga|modern\\s+yoga|fusion\\s+yoga|yoga\\s+therapy|yoga\\s+practice|yoga\\s+session|yoga\\s+class|yoga\\s+workout|yoga\\s+routine|morning\\s+yoga|evening\\s+yoga|bedtime\\s+yoga|wake\\s+up\\s+yoga|desk\\s+yoga|office\\s+yoga|travel\\s+yoga|outdoor\\s+yoga|beach\\s+yoga|park\\s+yoga|home\\s+yoga|studio\\s+yoga|group\\s+yoga|private\\s+yoga|online\\s+yoga|virtual\\s+yoga)\\b",
13501492

@@ -1358,13 +1500,13 @@ class SlotExtractor {
13581500

13591501
"outdoor walking" to "\\b(?<!indoor\\s)(?:outdoor\\s+walking|outdoor\\s+walk|outdoor\\s+hike|outdoor\\s+stroll|nature\\s+walk|trail\\s+walk|hill\\s+walk|forest\\s+walk|walk|walking|walked|walker|stroll|strolling|strolled|hike|hiking|hiked|hiker|trek|trekking|trekked|ramble|rambling|wander|wandering|wandered|amble|ambling|march|marching|power\\s+walk|brisk\\s+walk|leisurely\\s+walk|nature\\s+walk|trail\\s+walk|hill\\s+walk|speed\\s+walk|fitness\\s+walk|evening\\s+walk|morning\\s+walk)\\b",
13601502

1361-
"indoor walking" to "\\b(?:indoor\\s+walking|indoor\\s+walk|indoor\\s+stroll|treadmill\\s+walking|treadmill\\s+walk)\\b",
1503+
"indoor walking" to "\\b(?:indoor\\s+walking|indoor\\s+walk|indoor\\s+stroll|treadmill\\s+walking|treadmill\\s+walk|walk indoor|walking indoor)\\b",
13621504

13631505
"outdoor cycling" to "\\b(?<!indoor\\s)(?<!quad\\s)(?:outdoor\\s+cycling|outdoor\\s+bike|outdoor\\s+biking|road\\s+cycling|road\\s+bike|mountain\\s+bike|mountain\\s+biking|bike\\s+ride|cycle\\s+ride|bicycle\\s+ride|cycling|cycle|cycled|bike|biking|biked|bicycle|bicycling|pedal|pedaling|pedalled|two\\s+wheeler|pushbike|velocipede|touring\\s+bike|hybrid\\s+bike|commuter\\s+bike|recreational\\s+cycling|leisure\\s+cycling|weekend\\s+ride|group\\s+ride|solo\\s+ride|charity\\s+ride|bike\\s+tour|cycling\\s+tour|bike\\s+trip|cycling\\s+trip|bicycle\\s+tour|road\\s+biking|trail\\s+biking|cross\\s+country\\s+biking|endurance\\s+cycling|speed\\s+cycling|time\\s+trial|criterium|gran\\s+fondo|century\\s+ride|metric\\s+century|bike\\s+workout|cycling\\s+workout|outdoor\\s+pedaling|fresh\\s+air\\s+cycling|nature\\s+cycling|scenic\\s+ride|countryside\\s+cycling)\\b",
13641506

13651507
"bmx" to "\\b(?:bmx|bmx\\s+bike|bmx\\s+racing|bmx\\s+riding|bmx\\s+freestyle|bmx\\s+street|bmx\\s+park|bmx\\s+dirt|bmx\\s+vert|bmx\\s+flatland|bicycle\\s+motocross|bike\\s+motocross|twenty\\s+inch\\s+bike|small\\s+wheel\\s+bike|stunt\\s+bike|trick\\s+bike|jump\\s+bike|ramp\\s+bike|skate\\s+park\\s+bike|pump\\s+track|bmx\\s+track|bmx\\s+course|bmx\\s+trail|bmx\\s+session|recreational\\s+bmx|competitive\\s+bmx|professional\\s+bmx|amateur\\s+bmx|youth\\s+bmx|adult\\s+bmx|racing\\s+bmx|freestyle\\s+bmx|old\\s+school\\s+bmx|new\\s+school\\s+bmx|vintage\\s+bmx|modern\\s+bmx|single\\s+speed\\s+bmx|fixed\\s+gear\\s+bmx)\\b",
13661508

1367-
"pool swimming" to "\\b(?:pool\\s+swimming|pool\\s+swim|pool\\s+workout|lap\\s+swimming|lap\\s+swim|indoor\\s+swimming|indoor\\s+swim|chlorinated\\s+pool|swimming\\s+pool|olympic\\s+pool|competition\\s+pool|lane\\s+swimming|freestyle\\s+swimming|backstroke\\s+swimming|breaststroke\\s+swimming|butterfly\\s+swimming|individual\\s+medley|medley\\s+swimming|sprint\\s+swimming|distance\\s+swimming|endurance\\s+swimming|interval\\s+swimming|tempo\\s+swimming|technique\\s+swimming|stroke\\s+work|kick\\s+sets|pull\\s+sets|swim\\s+drills|swimming\\s+laps|length\\s+swimming|recreational\\s+pool\\s+swimming|competitive\\s+pool\\s+swimming|masters\\s+swimming|youth\\s+swimming|adult\\s+swimming|senior\\s+swimming|aquatic\\s+center|natatorium|swimming\\s+facility|heated\\s+pool)\\b",
1509+
"pool swimming" to "\\b(?:pool\\s+swimming|pool\\s+swim|swimming|pool\\s+workout|lap\\s+swimming|lap\\s+swim|indoor\\s+swimming|indoor\\s+swim|chlorinated\\s+pool|swimming\\s+pool|olympic\\s+pool|competition\\s+pool|lane\\s+swimming|freestyle\\s+swimming|backstroke\\s+swimming|breaststroke\\s+swimming|butterfly\\s+swimming|individual\\s+medley|medley\\s+swimming|sprint\\s+swimming|distance\\s+swimming|endurance\\s+swimming|interval\\s+swimming|tempo\\s+swimming|technique\\s+swimming|stroke\\s+work|kick\\s+sets|pull\\s+sets|swim\\s+drills|swimming\\s+laps|length\\s+swimming|recreational\\s+pool\\s+swimming|competitive\\s+pool\\s+swimming|masters\\s+swimming|youth\\s+swimming|adult\\s+swimming|senior\\s+swimming|aquatic\\s+center|natatorium|swimming\\s+facility|heated\\s+pool)\\b",
13681510

13691511
"open water" to "\\b(?:open\\s+water|open\\s+water\\s+swimming|open\\s+water\\s+swim|ocean\\s+swimming|ocean\\s+swim|lake\\s+swimming|lake\\s+swim|sea\\s+swimming|sea\\s+swim|river\\s+swimming|river\\s+swim|bay\\s+swimming|bay\\s+swim|pond\\s+swimming|pond\\s+swim|natural\\s+water\\s+swimming|wild\\s+swimming|cold\\s+water\\s+swimming|salt\\s+water\\s+swimming|fresh\\s+water\\s+swimming|tidal\\s+swimming|current\\s+swimming|wave\\s+swimming|surf\\s+swimming|channel\\s+swimming|crossing\\s+swimming|marathon\\s+swimming|ultra\\s+swimming|endurance\\s+open\\s+water|triathlon\\s+swimming|wetsuit\\s+swimming|skin\\s+swimming|outdoor\\s+swimming|natural\\s+swimming|adventure\\s+swimming|expedition\\s+swimming|recreational\\s+open\\s+water|competitive\\s+open\\s+water|mass\\s+start\\s+swimming|beach\\s+start\\s+swimming)\\b",
13701512

@@ -1629,6 +1771,22 @@ class SlotExtractor {
16291771
return null
16301772
}
16311773

1774+
private fun extractActivityNumber(text: String): Int? {
1775+
// First extract the activity type
1776+
val activityType = extractActivityType(text)
1777+
Log.d(LOG_TAG, "🔢 extractActivityNumber - activity_type: $activityType")
1778+
1779+
if (activityType == null) {
1780+
return null
1781+
}
1782+
1783+
// Then look up the activity number from the mapping
1784+
val activityNumber = activityNumberMap[activityType]
1785+
Log.d(LOG_TAG, "🔢 extractActivityNumber - activity_number: $activityNumber")
1786+
1787+
return activityNumber
1788+
}
1789+
16321790
private fun extractApp(text: String): String? {
16331791
val apps = mapOf(
16341792
"heart rate" to "\\b(?:heart\\s+rate|heartrate|heart\\s+beat|heartbeat|pulse|pulse\\s+rate|bpm|beats\\s+per\\s+minute|cardiac|cardiac\\s+rate|heart\\s+rhythm|resting\\s+heart\\s+rate|rhr|max\\s+heart\\s+rate|maximum\\s+heart\\s+rate|heart\\s+health|cardiovascular|cardio|ticker|heart\\s+monitor|heart\\s+sensor|hr|beat|beats|beating|palpitation|palpitations|tachycardia|bradycardia|heart\\s+zone|target\\s+heart\\s+rate|recovery\\s+heart\\s+rate)\\b",
@@ -2001,6 +2159,14 @@ class SlotExtractor {
20012159
val activityType = extractActivityType(text)
20022160
if (activityType != null) {
20032161
slots["activity_type"] = activityType
2162+
Log.d(LOG_TAG, " ✓ Added activity_type contextually: $activityType")
2163+
}
2164+
}
2165+
if (!slots.containsKey("activity_number")) {
2166+
val activityNumber = extractActivityNumber(text)
2167+
if (activityNumber != null) {
2168+
slots["activity_number"] = activityNumber
2169+
Log.d(LOG_TAG, " ✓ Added activity_number contextually: $activityNumber")
20042170
}
20052171
}
20062172
}

0 commit comments

Comments
 (0)