Skip to content

Commit 4a1a5b8

Browse files
authored
Merge branch 'develop' into odi-fix
2 parents 1f8b51e + 94daffc commit 4a1a5b8

File tree

6 files changed

+78
-43
lines changed

6 files changed

+78
-43
lines changed

agent/src/index.ts

+56-26
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,61 @@ function tryLoadFile(filePath: string): string | null {
148148
return null;
149149
}
150150
}
151+
function mergeCharacters(base: Character, child: Character): Character {
152+
const mergeObjects = (baseObj: any, childObj: any) => {
153+
const result: any = {};
154+
const keys = new Set([...Object.keys(baseObj || {}), ...Object.keys(childObj || {})]);
155+
keys.forEach(key => {
156+
if (typeof baseObj[key] === 'object' && typeof childObj[key] === 'object' && !Array.isArray(baseObj[key]) && !Array.isArray(childObj[key])) {
157+
result[key] = mergeObjects(baseObj[key], childObj[key]);
158+
} else if (Array.isArray(baseObj[key]) || Array.isArray(childObj[key])) {
159+
result[key] = [...(baseObj[key] || []), ...(childObj[key] || [])];
160+
} else {
161+
result[key] = childObj[key] !== undefined ? childObj[key] : baseObj[key];
162+
}
163+
});
164+
return result;
165+
};
166+
return mergeObjects(base, child);
167+
}
168+
async function loadCharacter(filePath: string): Promise<Character> {
169+
const content = tryLoadFile(filePath);
170+
if (!content) {
171+
throw new Error(`Character file not found: ${filePath}`);
172+
}
173+
let character = JSON.parse(content);
174+
validateCharacterConfig(character);
175+
176+
// .id isn't really valid
177+
const characterId = character.id || character.name;
178+
const characterPrefix = `CHARACTER.${characterId.toUpperCase().replace(/ /g, "_")}.`;
179+
const characterSettings = Object.entries(process.env)
180+
.filter(([key]) => key.startsWith(characterPrefix))
181+
.reduce((settings, [key, value]) => {
182+
const settingKey = key.slice(characterPrefix.length);
183+
return { ...settings, [settingKey]: value };
184+
}, {});
185+
if (Object.keys(characterSettings).length > 0) {
186+
character.settings = character.settings || {};
187+
character.settings.secrets = {
188+
...characterSettings,
189+
...character.settings.secrets,
190+
};
191+
}
192+
// Handle plugins
193+
character.plugins = await handlePluginImporting(
194+
character.plugins
195+
);
196+
if (character.extends) {
197+
elizaLogger.info(`Merging ${character.name} character with parent characters`);
198+
for (const extendPath of character.extends) {
199+
const baseCharacter = await loadCharacter(path.resolve(path.dirname(filePath), extendPath));
200+
character = mergeCharacters(baseCharacter, character);
201+
elizaLogger.info(`Merged ${character.name} with ${baseCharacter.name}`);
202+
}
203+
}
204+
return character;
205+
}
151206

152207
export async function loadCharacters(
153208
charactersArg: string
@@ -211,32 +266,7 @@ export async function loadCharacters(
211266
}
212267

213268
try {
214-
const character = JSON.parse(content);
215-
validateCharacterConfig(character);
216-
217-
// .id isn't really valid
218-
const characterId = character.id || character.name;
219-
const characterPrefix = `CHARACTER.${characterId.toUpperCase().replace(/ /g, "_")}.`;
220-
221-
const characterSettings = Object.entries(process.env)
222-
.filter(([key]) => key.startsWith(characterPrefix))
223-
.reduce((settings, [key, value]) => {
224-
const settingKey = key.slice(characterPrefix.length);
225-
return { ...settings, [settingKey]: value };
226-
}, {});
227-
228-
if (Object.keys(characterSettings).length > 0) {
229-
character.settings = character.settings || {};
230-
character.settings.secrets = {
231-
...characterSettings,
232-
...character.settings.secrets,
233-
};
234-
}
235-
236-
// Handle plugins
237-
character.plugins = await handlePluginImporting(
238-
character.plugins
239-
);
269+
const character: Character = await loadCharacter(resolvedPath);
240270

241271
loadedCharacters.push(character);
242272
elizaLogger.info(

packages/client-discord/src/actions/joinvoice.ts

+16-16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
IAgentRuntime,
99
Memory,
1010
State,
11+
generateText,
12+
ModelClass,
1113
} from "@elizaos/core";
1214
import {
1315
Channel,
@@ -17,6 +19,7 @@ import {
1719
Guild,
1820
GuildMember,
1921
} from "discord.js";
22+
import { joinVoiceChannel } from "@discordjs/voice";
2023

2124
export default {
2225
name: "JOIN_VOICE",
@@ -66,12 +69,7 @@ export default {
6669
return false;
6770
}
6871

69-
const client = state.discordClient as Client;
70-
71-
// Check if the client is connected to any voice channel
72-
const isConnectedToVoice = client.voice.adapters.size === 0;
73-
74-
return isConnectedToVoice;
72+
return true;
7573
},
7674
description: "Join a voice channel to participate in voice chat.",
7775
handler: async (
@@ -115,31 +113,30 @@ export default {
115113
);
116114
});
117115

118-
if (!state.voiceManager) {
119-
state.voiceManager = new VoiceManager({
120-
client: state.discordClient,
121-
runtime: runtime,
122-
});
123-
}
124-
125116
if (targetChannel) {
126-
state.voiceManager.joinVoiceChannel({
117+
joinVoiceChannel({
127118
channelId: targetChannel.id,
128119
guildId: (discordMessage as DiscordMessage).guild?.id as string,
129120
adapterCreator: (client.guilds.cache.get(id) as Guild)
130121
.voiceAdapterCreator,
122+
selfDeaf: false,
123+
selfMute: false,
124+
group: client.user.id,
131125
});
132126
return true;
133127
} else {
134128
const member = (discordMessage as DiscordMessage)
135129
.member as GuildMember;
136130
if (member?.voice?.channel) {
137-
state.voiceManager.joinVoiceChannel({
131+
joinVoiceChannel({
138132
channelId: member.voice.channel.id,
139133
guildId: (discordMessage as DiscordMessage).guild
140134
?.id as string,
141135
adapterCreator: (client.guilds.cache.get(id) as Guild)
142136
.voiceAdapterCreator,
137+
selfDeaf: false,
138+
selfMute: false,
139+
group: client.user.id,
143140
});
144141
return true;
145142
}
@@ -204,12 +201,15 @@ You should only respond with the name of the voice channel or none, no commentar
204201
});
205202

206203
if (targetChannel) {
207-
state.voiceManager.joinVoiceChannel({
204+
joinVoiceChannel({
208205
channelId: targetChannel.id,
209206
guildId: (discordMessage as DiscordMessage).guild
210207
?.id as string,
211208
adapterCreator: (client.guilds.cache.get(id) as Guild)
212209
.voiceAdapterCreator,
210+
selfDeaf: false,
211+
selfMute: false,
212+
group: client.user.id,
213213
});
214214
return true;
215215
}

packages/core/src/defaultCharacter.ts

+1
Original file line numberDiff line numberDiff line change
@@ -527,4 +527,5 @@ export const defaultCharacter: Character = {
527527
"meticulous",
528528
"provocative",
529529
],
530+
extends: [],
530531
};

packages/core/src/environment.ts

+1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ export const CharacterSchema = z.object({
135135
prompt: z.string().optional(),
136136
})
137137
.optional(),
138+
extends: z.array(z.string()).optional(),
138139
});
139140

140141
// Type inference

packages/core/src/types.ts

+3
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ export enum Clients {
647647
LENS = "lens",
648648
AUTO = "auto",
649649
SLACK = "slack",
650+
GITHUB = "github",
650651
}
651652

652653
export interface IAgentConfig {
@@ -871,6 +872,8 @@ export type Character = {
871872
nft?: {
872873
prompt: string;
873874
};
875+
/**Optinal Parent characters to inherit information from */
876+
extends?: string[];
874877
};
875878

876879
/**

packages/plugin-sui/src/providers/wallet.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ export class WalletProvider {
181181
}
182182
);
183183
const prices: Prices = {
184-
sui: { usd: suiPriceData.pair.priceUsd },
184+
sui: { usd: (1 / suiPriceData.pair.priceNative).toString() },
185185
};
186186
this.setCachedData(cacheKey, prices);
187187
return prices;

0 commit comments

Comments
 (0)