Skip to content

Commit e0783a3

Browse files
authored
Merge branch 'develop' into 1223-fix-todos
2 parents 7fea444 + 99f4eca commit e0783a3

File tree

5 files changed

+70
-4
lines changed

5 files changed

+70
-4
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ packages/core/src/providers/cache
4545
packages/core/src/providers/cache/*
4646
cache/*
4747
packages/plugin-coinbase/src/plugins/transactions.csv
48-
packages/plugin-coinbase/package-lock.json
4948

5049
tsup.config.bundled_*.mjs
5150

agent/src/index.ts

+19
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,25 @@ export async function loadCharacters(
179179
const character = JSON.parse(content);
180180
validateCharacterConfig(character);
181181

182+
// .id isn't really valid
183+
const characterId = character.id || character.name;
184+
const characterPrefix = `CHARACTER.${characterId.toUpperCase().replace(/ /g, '_')}.`;
185+
186+
const characterSettings = Object.entries(process.env)
187+
.filter(([key]) => key.startsWith(characterPrefix))
188+
.reduce((settings, [key, value]) => {
189+
const settingKey = key.slice(characterPrefix.length);
190+
return { ...settings, [settingKey]: value };
191+
}, {});
192+
193+
if (Object.keys(characterSettings).length > 0) {
194+
character.settings = character.settings || {};
195+
character.settings.secrets = {
196+
...characterSettings,
197+
...character.settings.secrets
198+
};
199+
}
200+
182201
// Handle plugins
183202
if (isAllStrings(character.plugins)) {
184203
elizaLogger.info("Plugins are: ", character.plugins);

docs/docs/guides/secrets-management.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ A comprehensive guide for managing secrets, API keys, and sensitive configuratio
1212

1313
Eliza uses a hierarchical environment variable system:
1414

15-
1. Character-specific secrets (highest priority)
16-
2. Environment variables
17-
3. Default values (lowest priority)
15+
1. Character-specific namespaced environment variables (highest priority)
16+
2. Character-specific secrets
17+
3. Environment variables
18+
4. Default values (lowest priority)
1819

1920
### Secret Types
2021

@@ -96,6 +97,8 @@ Define secrets in character files:
9697
}
9798
```
9899

100+
Alternatively, you can use the `CHARACTER.YOUR_CHARACTER_NAME.SECRET_NAME` format inside your `.env` file.
101+
99102
Access secrets in code:
100103

101104
```typescript

docs/docs/packages/agent.md

+14
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,15 @@ export async function initializeClients(
160160

161161
### Token Management
162162

163+
Tokens can be configured in two ways:
164+
165+
1. Using namespaced environment variables:
166+
```env
167+
CHARACTER.YOUR_CHARACTER_NAME.OPENAI_API_KEY=sk-...
168+
CHARACTER.YOUR_CHARACTER_NAME.ANTHROPIC_API_KEY=sk-...
169+
```
170+
171+
2. Using character settings:
163172
```typescript
164173
export function getTokenForProvider(
165174
provider: ModelProviderName,
@@ -181,6 +190,11 @@ export function getTokenForProvider(
181190
}
182191
```
183192

193+
The system will check for tokens in the following order:
194+
1. Character-specific namespaced env variables
195+
2. Character settings from JSON
196+
3. Global environment variables
197+
184198
### Database Selection
185199

186200
```typescript

packages/core/src/settings.ts

+31
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ interface Settings {
2222
[key: string]: string | undefined;
2323
}
2424

25+
interface NamespacedSettings {
26+
[namespace: string]: Settings;
27+
}
28+
2529
let environmentSettings: Settings = {};
2630

2731
/**
@@ -91,6 +95,15 @@ export function loadEnvConfig(): Settings {
9195
if (!result.error) {
9296
console.log(`Loaded .env file from: ${envPath}`);
9397
}
98+
99+
// Parse namespaced settings
100+
const namespacedSettings = parseNamespacedSettings(process.env as Settings);
101+
102+
// Attach to process.env for backward compatibility
103+
Object.entries(namespacedSettings).forEach(([namespace, settings]) => {
104+
process.env[`__namespaced_${namespace}`] = JSON.stringify(settings);
105+
});
106+
94107
return process.env as Settings;
95108
}
96109

@@ -135,3 +148,21 @@ elizaLogger.info("Parsed settings:", {
135148
});
136149

137150
export default settings;
151+
152+
// Add this function to parse namespaced settings
153+
function parseNamespacedSettings(env: Settings): NamespacedSettings {
154+
const namespaced: NamespacedSettings = {};
155+
156+
for (const [key, value] of Object.entries(env)) {
157+
if (!value) continue;
158+
159+
const [namespace, ...rest] = key.split('.');
160+
if (!namespace || rest.length === 0) continue;
161+
162+
const settingKey = rest.join('.');
163+
namespaced[namespace] = namespaced[namespace] || {};
164+
namespaced[namespace][settingKey] = value;
165+
}
166+
167+
return namespaced;
168+
}

0 commit comments

Comments
 (0)