@@ -50,11 +50,19 @@ function normalizeCategory(category: string): ActivityCategory {
5050
5151/**
5252 * Convert a parsed classification to a classified activity.
53+ * Returns null if the activity has no action (invalid/incomplete classification).
5354 */
5455function toClassifiedActivity (
5556 response : ParsedClassification ,
5657 candidate : CandidateMessage
57- ) : ClassifiedActivity {
58+ ) : ClassifiedActivity | null {
59+ // Action is required - if empty, the classification is invalid
60+ if ( ! response . act || response . act . trim ( ) === '' ) {
61+ console . warn (
62+ `[classifier] Discarding activity with empty action: msg=${ response . msg } , title="${ response . title } "`
63+ )
64+ return null
65+ }
5866 // Capitalize first letter of title
5967 const title = response . title ?? candidate . content . slice ( 0 , 100 )
6068 const capitalizedTitle = title . charAt ( 0 ) . toUpperCase ( ) + title . slice ( 1 )
@@ -143,13 +151,16 @@ export async function classifyBatch(
143151 const expectedIds = candidates . map ( ( c ) => c . messageId )
144152 const parsed = parseClassificationResponse ( responseResult . value , expectedIds )
145153
146- // Map responses to candidates
154+ // Map responses to candidates, filtering out invalid classifications
147155 const suggestions : ClassifiedActivity [ ] = [ ]
148156
149157 for ( const response of parsed ) {
150158 const candidate = candidates . find ( ( c ) => c . messageId === response . msg )
151159 if ( candidate ) {
152- suggestions . push ( toClassifiedActivity ( response , candidate ) )
160+ const activity = toClassifiedActivity ( response , candidate )
161+ if ( activity ) {
162+ suggestions . push ( activity )
163+ }
153164 }
154165 }
155166
0 commit comments