Skip to content

Commit 94823e1

Browse files
authored
Merge pull request elizaOS#2248 from augchan42/feature/echochamber-conversation-starter
feat: (echochambers) add dead room detection and conversation starter
2 parents 60116c5 + 7067272 commit 94823e1

File tree

6 files changed

+469
-240
lines changed

6 files changed

+469
-240
lines changed

.env.example

+193-191
Large diffs are not rendered by default.

packages/plugin-echochambers/src/echoChamberClient.ts

+60-34
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ export class EchoChamberClient {
1818
private config: EchoChamberConfig;
1919
private apiUrl: string;
2020
private modelInfo: ModelInfo;
21-
private pollInterval: NodeJS.Timeout | null = null;
22-
private watchedRoom: string | null = null;
21+
private watchedRooms: Set<string> = new Set();
2322

2423
constructor(runtime: IAgentRuntime, config: EchoChamberConfig) {
2524
this.runtime = runtime;
@@ -50,28 +49,30 @@ export class EchoChamberClient {
5049
};
5150
}
5251

53-
public async setWatchedRoom(roomId: string): Promise<void> {
52+
public async addWatchedRoom(roomId: string): Promise<void> {
5453
try {
55-
// Verify room exists
5654
const rooms = await this.listRooms();
5755
const room = rooms.find((r) => r.id === roomId);
5856

5957
if (!room) {
6058
throw new Error(`Room ${roomId} not found`);
6159
}
6260

63-
// Set new watched room
64-
this.watchedRoom = roomId;
65-
61+
this.watchedRooms.add(roomId);
6662
elizaLogger.success(`Now watching room: ${room.name}`);
6763
} catch (error) {
68-
elizaLogger.error("Error setting watched room:", error);
64+
elizaLogger.error("Error adding watched room:", error);
6965
throw error;
7066
}
7167
}
7268

73-
public getWatchedRoom(): string | null {
74-
return this.watchedRoom;
69+
public removeWatchedRoom(roomId: string): void {
70+
this.watchedRooms.delete(roomId);
71+
elizaLogger.success(`Stopped watching room: ${roomId}`);
72+
}
73+
74+
public getWatchedRooms(): string[] {
75+
return Array.from(this.watchedRooms);
7576
}
7677

7778
private async retryOperation<T>(
@@ -94,40 +95,26 @@ export class EchoChamberClient {
9495
public async start(): Promise<void> {
9596
elizaLogger.log("🚀 Starting EchoChamber client...");
9697
try {
97-
// Verify connection by listing rooms
9898
await this.retryOperation(() => this.listRooms());
99-
elizaLogger.success(
100-
`✅ EchoChamber client successfully started for ${this.modelInfo.username}`
101-
);
10299

103-
// Join default room if specified and no specific room is being watched
104-
if (this.config.defaultRoom && !this.watchedRoom) {
105-
await this.setWatchedRoom(this.config.defaultRoom);
100+
for (const room of this.config.rooms) {
101+
await this.addWatchedRoom(room);
106102
}
103+
104+
elizaLogger.success(
105+
`✅ EchoChamber client started for ${this.modelInfo.username}`
106+
);
107+
elizaLogger.info(
108+
`Watching rooms: ${Array.from(this.watchedRooms).join(", ")}`
109+
);
107110
} catch (error) {
108111
elizaLogger.error("❌ Failed to start EchoChamber client:", error);
109112
throw error;
110113
}
111114
}
112115

113116
public async stop(): Promise<void> {
114-
if (this.pollInterval) {
115-
clearInterval(this.pollInterval);
116-
this.pollInterval = null;
117-
}
118-
119-
// Leave watched room if any
120-
if (this.watchedRoom) {
121-
try {
122-
this.watchedRoom = null;
123-
} catch (error) {
124-
elizaLogger.error(
125-
`Error leaving room ${this.watchedRoom}:`,
126-
error
127-
);
128-
}
129-
}
130-
117+
this.watchedRooms.clear();
131118
elizaLogger.log("Stopping EchoChamber client...");
132119
}
133120

@@ -189,4 +176,43 @@ export class EchoChamberClient {
189176
return data.message;
190177
});
191178
}
179+
180+
public async shouldInitiateConversation(room: ChatRoom): Promise<boolean> {
181+
try {
182+
const history = await this.getRoomHistory(room.id);
183+
if (!history?.length) return true; // Empty room is good to start
184+
185+
const recentMessages = history
186+
.filter((msg) => msg != null) // Filter out null messages
187+
.sort(
188+
(a, b) =>
189+
new Date(b.timestamp).getTime() -
190+
new Date(a.timestamp).getTime()
191+
);
192+
193+
if (!recentMessages.length) return true; // No valid messages
194+
195+
const lastMessageTime = new Date(
196+
recentMessages[0].timestamp
197+
).getTime();
198+
const timeSinceLastMessage = Date.now() - lastMessageTime;
199+
200+
const quietPeriodSeconds = Number(
201+
this.runtime.getSetting("ECHOCHAMBERS_QUIET_PERIOD") || 300 // 5 minutes in seconds
202+
);
203+
const quietPeriod = quietPeriodSeconds * 1000; // Convert to milliseconds
204+
205+
if (timeSinceLastMessage < quietPeriod) {
206+
elizaLogger.debug(
207+
`Room ${room.name} active recently, skipping`
208+
);
209+
return false;
210+
}
211+
212+
return true;
213+
} catch (error) {
214+
elizaLogger.error(`Error checking conversation state: ${error}`);
215+
return false;
216+
}
217+
}
192218
}

packages/plugin-echochambers/src/environment.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ export async function validateEchoChamberConfig(
3434
const username =
3535
runtime.getSetting("ECHOCHAMBERS_USERNAME") ||
3636
`agent-${runtime.agentId}`;
37-
const defaultRoom =
38-
runtime.getSetting("ECHOCHAMBERS_DEFAULT_ROOM") || "general";
37+
// Change from DEFAULT_ROOM to ROOMS
38+
const rooms = runtime.getSetting("ECHOCHAMBERS_ROOMS")?.split(",").map(r => r.trim()) || ["general"];
39+
3940
const pollInterval = Number(
4041
runtime.getSetting("ECHOCHAMBERS_POLL_INTERVAL") || 120
4142
);
@@ -50,6 +51,6 @@ export async function validateEchoChamberConfig(
5051
elizaLogger.log("EchoChambers configuration validated successfully");
5152
elizaLogger.log(`API URL: ${apiUrl}`);
5253
elizaLogger.log(`Username: ${username}`);
53-
elizaLogger.log(`Default Room: ${defaultRoom}`);
54+
elizaLogger.log(`Watching Rooms: ${rooms.join(", ")}`);
5455
elizaLogger.log(`Poll Interval: ${pollInterval}s`);
5556
}

packages/plugin-echochambers/src/index.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ export const EchoChamberClientInterface: Client = {
2626
runtime.getSetting("ECHOCHAMBERS_USERNAME") ||
2727
`agent-${runtime.agentId}`,
2828
model: runtime.modelProvider,
29-
defaultRoom:
30-
runtime.getSetting("ECHOCHAMBERS_DEFAULT_ROOM") ||
31-
"general",
29+
rooms: runtime
30+
.getSetting("ECHOCHAMBERS_ROOMS")
31+
?.split(",")
32+
.map((r) => r.trim()) || ["general"],
3233
};
3334

3435
elizaLogger.log("Starting EchoChambers client...");

0 commit comments

Comments
 (0)