-
Notifications
You must be signed in to change notification settings - Fork 0
Fix 5 runtime bugs found during debug pass #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c438619
a809941
2407087
b6f3efa
104e4a4
ab10289
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ export class AutonomousAgent { | |
| private grokService: GrokService; | ||
| private config: AgentConfig; | ||
| private processedMentions: Set<string> = new Set(); | ||
| private static readonly MAX_PROCESSED_MENTIONS = 10000; | ||
| private isRunning: boolean = false; | ||
| private pollingIntervalId: NodeJS.Timeout | null = null; | ||
| private isProcessing: boolean = false; | ||
|
|
@@ -95,6 +96,19 @@ export class AutonomousAgent { | |
| await this.processMention(mention); | ||
| this.processedMentions.add(mention.post.id); | ||
| } | ||
|
|
||
| // Prune oldest entries to prevent unbounded memory growth | ||
| if (this.processedMentions.size > AutonomousAgent.MAX_PROCESSED_MENTIONS) { | ||
| const excess = this.processedMentions.size - AutonomousAgent.MAX_PROCESSED_MENTIONS; | ||
| const iter = this.processedMentions.values(); | ||
| for (let i = 0; i < excess; i++) { | ||
| const { value, done } = iter.next(); | ||
| if (done) { | ||
| break; | ||
| } | ||
| this.processedMentions.delete(value); | ||
| } | ||
|
Comment on lines
100
to
110
|
||
| } | ||
| } catch (error) { | ||
| console.error('❌ Error in processing loop:', error); | ||
| } finally { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -44,17 +44,26 @@ export class XAPIClient { | |||||||||||||
| throw new Error('Failed to get user ID from response'); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| const mentionsResponse = await this.makeXAPIRequest( | ||||||||||||||
| `https://api.twitter.com/2/users/${userId}/mentions?max_results=10&expansions=author_id&tweet.fields=created_at,conversation_id,in_reply_to_user_id,referenced_tweets`, | ||||||||||||||
| 'GET' | ||||||||||||||
| ); | ||||||||||||||
| let mentionsUrl = `https://api.twitter.com/2/users/${userId}/mentions?max_results=10&expansions=author_id&tweet.fields=created_at,conversation_id,in_reply_to_user_id,referenced_tweets`; | ||||||||||||||
| if (this.lastMentionId) { | ||||||||||||||
| mentionsUrl += `&since_id=${this.lastMentionId}`; | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+47
to
+50
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Building URLs via string concatenation can be fragile and hard to read. Using const params = new URLSearchParams({
max_results: '10',
expansions: 'author_id',
'tweet.fields': 'created_at,conversation_id,in_reply_to_user_id,referenced_tweets',
});
if (this.lastMentionId) {
params.set('since_id', this.lastMentionId);
}
const mentionsUrl = `https://api.twitter.com/2/users/${userId}/mentions?${params.toString()}`; |
||||||||||||||
|
|
||||||||||||||
| const mentionsResponse = await this.makeXAPIRequest(mentionsUrl, 'GET'); | ||||||||||||||
|
|
||||||||||||||
| if (!mentionsResponse || !Array.isArray(mentionsResponse.data)) { | ||||||||||||||
| console.warn('Invalid response from X API (mentions)'); | ||||||||||||||
| return []; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| return this.parseMentions(mentionsResponse.data); | ||||||||||||||
| const mentions = this.parseMentions(mentionsResponse.data); | ||||||||||||||
|
|
||||||||||||||
| // Track the newest mention ID for pagination on the next poll | ||||||||||||||
| if (mentionsResponse.data.length > 0) { | ||||||||||||||
| this.lastMentionId = mentionsResponse.data[0].id; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| return mentions; | ||||||||||||||
| } catch (error) { | ||||||||||||||
| console.error('Error fetching mentions:', error); | ||||||||||||||
| return []; | ||||||||||||||
|
|
@@ -77,7 +86,17 @@ export class XAPIClient { | |||||||||||||
| 'GET' | ||||||||||||||
| ); | ||||||||||||||
|
|
||||||||||||||
| return this.parseThread(response.data || []); | ||||||||||||||
| if (!response || !response.data) { | ||||||||||||||
| console.warn('Invalid response from X API (thread)'); | ||||||||||||||
| return null; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
||||||||||||||
| if (!Array.isArray(response.data)) { | |
| console.warn('Unexpected response shape from X API (thread): data is not an array'); | |
| return null; | |
| } |
Copilot
AI
Feb 6, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fetchThread() now only checks response.data for truthiness, but parseThread() expects an array and will still throw if response.data is a non-array object (which can happen with unexpected API shapes). Consider guarding with Array.isArray(response.data) (and returning null otherwise) before calling parseThread().
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parseThread’s parameter type still uses an index signature with any, which weakens type safety under strict mode and makes it easier for unexpected shapes to slip through (especially since this method assumes an array-like input). Consider using unknown instead of any for the extra fields (or define a minimal tweet shape type) to avoid accidentally relying on untyped properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
origLogis assigned but never used. Either remove it to avoid dead code, or use it to restoreconsole.logduring shutdown/after MCP server init (depending on the intended lifecycle).