@@ -91,19 +91,61 @@ export const continueAction: Action = {
91
91
options : any ,
92
92
callback : HandlerCallback
93
93
) => {
94
- if (
95
- message . content . text . endsWith ( "?" ) ||
96
- message . content . text . endsWith ( "!" )
97
- ) {
98
- return ;
99
- }
100
-
101
94
if ( ! state ) {
102
95
state = ( await runtime . composeState ( message ) ) as State ;
103
96
}
104
-
105
97
state = await runtime . updateRecentMessageState ( state ) ;
106
98
99
+ // Get the agent's recent messages
100
+ const agentMessages = state . recentMessagesData
101
+ . filter ( ( m : { userId : any } ) => m . userId === runtime . agentId )
102
+ . sort ( ( a : Memory , b : Memory ) => {
103
+ // Sort by timestamp if available, assuming newer messages have higher timestamps
104
+ const aTime = a . createdAt || 0 ;
105
+ const bTime = b . createdAt || 0 ;
106
+ return bTime - aTime ;
107
+ } ) ;
108
+
109
+ // Check for immediate double response (responding twice in a row to the same message)
110
+ const lastAgentMessage = agentMessages [ 0 ] ;
111
+
112
+ if ( lastAgentMessage ?. content ?. inReplyTo === message . id ) {
113
+ // If our last message was already a response to this message, only allow continue if:
114
+ // 1. The last message had a CONTINUE action
115
+ // 2. We haven't hit the maxContinuesInARow limit
116
+ const continueCount = agentMessages
117
+ . filter ( ( m : Memory ) => m . content ?. inReplyTo === message . id )
118
+ . filter ( ( m : Memory ) => m . content ?. action === 'CONTINUE' )
119
+ . length ;
120
+
121
+ if ( continueCount >= maxContinuesInARow ) {
122
+ elizaLogger . log ( `[CONTINUE] Max continues (${ maxContinuesInARow } ) reached for this message chain` ) ;
123
+ return ;
124
+ }
125
+
126
+ if ( lastAgentMessage . content ?. action !== 'CONTINUE' ) {
127
+ elizaLogger . log ( `[CONTINUE] Last message wasn't a CONTINUE, preventing double response` ) ;
128
+ return ;
129
+ }
130
+ }
131
+
132
+ // Check if our last message or message ended with a question/exclamation and warrants a stop
133
+ if ( ( lastAgentMessage && lastAgentMessage . content . text &&
134
+ ( lastAgentMessage . content . text . endsWith ( "?" ) ||
135
+ lastAgentMessage . content . text . endsWith ( "!" ) ) ) || ( message . content . text . endsWith ( "?" ) || message . content . text . endsWith ( "!" ) ) ) {
136
+ elizaLogger . log ( `[CONTINUE] Last message had question/exclamation. Not proceeding.` ) ;
137
+ return ;
138
+ }
139
+
140
+ // Prevent exact duplicate messages
141
+ const messageExists = agentMessages
142
+ . slice ( 0 , maxContinuesInARow + 1 )
143
+ . some ( ( m : { content : any } ) => m . content . text === message . content . text ) ;
144
+
145
+ if ( messageExists ) {
146
+ return ;
147
+ }
148
+
107
149
async function _shouldContinue ( state : State ) : Promise < boolean > {
108
150
// If none of the above conditions are met, use the generateText to decide
109
151
const shouldRespondContext = composeContext ( {
@@ -120,12 +162,14 @@ export const continueAction: Action = {
120
162
return response ;
121
163
}
122
164
165
+ // Use AI to determine if we should continue
123
166
const shouldContinue = await _shouldContinue ( state ) ;
124
167
if ( ! shouldContinue ) {
125
- elizaLogger . log ( "Not elaborating, returning" ) ;
168
+ elizaLogger . log ( "[CONTINUE] Not elaborating, returning" ) ;
126
169
return ;
127
170
}
128
171
172
+ // Generate and send response
129
173
const context = composeContext ( {
130
174
state,
131
175
template :
@@ -150,32 +194,17 @@ export const continueAction: Action = {
150
194
type : "continue" ,
151
195
} ) ;
152
196
153
- // prevent repetition
154
- const messageExists = state . recentMessagesData
155
- . filter ( ( m : { userId : any } ) => m . userId === runtime . agentId )
156
- . slice ( 0 , maxContinuesInARow + 1 )
157
- . some ( ( m : { content : any } ) => m . content === message . content ) ;
158
-
159
- if ( messageExists ) {
160
- return ;
161
- }
162
-
163
197
await callback ( response ) ;
164
198
165
- // if the action is CONTINUE, check if we are over maxContinuesInARow
199
+ // Check if we need to clear the CONTINUE action
166
200
if ( response . action === "CONTINUE" ) {
167
- const agentMessages = state . recentMessagesData
168
- . filter ( ( m : { userId : any } ) => m . userId === runtime . agentId )
169
- . map ( ( m : { content : any } ) => ( m . content as Content ) . action ) ;
201
+ const continueCount = agentMessages
202
+ . slice ( 0 , maxContinuesInARow )
203
+ . filter ( ( m : Memory ) => m . content ?. action === 'CONTINUE' )
204
+ . length ;
170
205
171
- const lastMessages = agentMessages . slice ( 0 , maxContinuesInARow ) ;
172
- if ( lastMessages . length >= maxContinuesInARow ) {
173
- const allContinues = lastMessages . every (
174
- ( m : string | undefined ) => m === "CONTINUE"
175
- ) ;
176
- if ( allContinues ) {
177
- response . action = null ;
178
- }
206
+ if ( continueCount >= maxContinuesInARow - 1 ) { // -1 because we're about to add another
207
+ response . action = null ;
179
208
}
180
209
}
181
210
@@ -598,4 +627,4 @@ export const continueAction: Action = {
598
627
} ,
599
628
] ,
600
629
] as ActionExample [ ] [ ] ,
601
- } as Action ;
630
+ } as Action ;
0 commit comments