@elizaos/cli 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/assets/{index-BQEpBB33.js → index-BaWElBml.js} +65713 -67371
- package/dist/assets/{index-BQEpBB33.js.map → index-BaWElBml.js.map} +1 -1
- package/dist/assets/{index-eRnFTOEM.js → index-Bs4IloEa.js} +2 -2
- package/dist/assets/index-Bs4IloEa.js.br +0 -0
- package/dist/assets/{index-eRnFTOEM.js.map → index-Bs4IloEa.js.map} +1 -1
- package/dist/{chunk-QC5MM66L.js → chunk-246Q3Y5O.js} +3 -3
- package/dist/chunk-2GXSCVA2.js +2057 -0
- package/dist/chunk-67L4I5S7.js +80 -0
- package/dist/chunk-7HDCC22V.js +771 -0
- package/dist/{chunk-F3WZNGHX.js → chunk-BZIUA2KE.js} +6 -0
- package/dist/{chunk-QU55ROKN.js → chunk-GE5HMHU5.js} +12 -6
- package/dist/{chunk-URANH3OS.js → chunk-JT3O6PBU.js} +3867 -529
- package/dist/{chunk-XVN7DK3U.js → chunk-KNZMV4HH.js} +4 -4
- package/dist/{chunk-QPXAVEMR.js → chunk-NQ5HAYUQ.js} +40 -2
- package/dist/{chunk-XF2FQZM2.js → chunk-OF5WHPTG.js} +105 -798
- package/dist/{chunk-ENUVIKE2.js → chunk-OG4OJUNA.js} +2 -2
- package/dist/{chunk-SOL3WRAY.js → chunk-OJMVYUOU.js} +1 -1
- package/dist/{chunk-XLCI6Y5F.js → chunk-QGZZVGE5.js} +2 -2
- package/dist/{chunk-PJJS5DFB.js → chunk-WAJ5RHPK.js} +1 -1
- package/dist/commands/agent.js +2 -1
- package/dist/commands/create.js +4 -3
- package/dist/commands/dev.js +4 -3
- package/dist/commands/env.js +3 -2
- package/dist/commands/plugins.js +4 -3
- package/dist/commands/publish.js +5 -4
- package/dist/commands/setup-monorepo.js +3 -2
- package/dist/commands/start.js +7 -5
- package/dist/commands/test.js +8 -6
- package/dist/commands/update.js +4 -3
- package/dist/fileFromPath-DCRQMDLJ.js +132 -0
- package/dist/index.html +1 -1
- package/dist/index.js +14 -12
- package/dist/migrator-7EYGXTDW.js +29035 -0
- package/dist/{registry-YU4WBPLU.js → registry-RGSXW4LO.js} +2 -1
- package/package.json +10 -4
- package/templates/plugin-starter/package.json +1 -1
- package/templates/project-starter/.env.example +1 -0
- package/templates/project-starter/package.json +4 -4
- package/templates/project-tee-starter/.dockerignore +20 -0
- package/templates/project-tee-starter/.env.example +55 -0
- package/templates/project-tee-starter/Dockerfile +66 -0
- package/templates/project-tee-starter/GUIDE.md +235 -0
- package/templates/project-tee-starter/README.md +173 -0
- package/templates/project-tee-starter/__tests__/actions.test.ts +9 -0
- package/templates/project-tee-starter/__tests__/character.test.ts +86 -0
- package/templates/project-tee-starter/__tests__/config.test.ts +31 -0
- package/templates/project-tee-starter/__tests__/env.test.ts +87 -0
- package/templates/project-tee-starter/__tests__/error-handling.test.ts +30 -0
- package/templates/project-tee-starter/__tests__/events.test.ts +21 -0
- package/templates/project-tee-starter/__tests__/file-structure.test.ts +135 -0
- package/templates/project-tee-starter/__tests__/integration.test.ts +209 -0
- package/templates/project-tee-starter/__tests__/models.test.ts +22 -0
- package/templates/project-tee-starter/__tests__/plugin.test.ts +44 -0
- package/templates/project-tee-starter/__tests__/provider.test.ts +189 -0
- package/templates/project-tee-starter/__tests__/routes.test.ts +21 -0
- package/templates/project-tee-starter/__tests__/test-utils.ts +121 -0
- package/templates/project-tee-starter/__tests__/utils/core-test-utils.ts +167 -0
- package/templates/project-tee-starter/assets/mr-tee-portrait.jpg +0 -0
- package/templates/project-tee-starter/docker-compose.yaml +57 -0
- package/templates/project-tee-starter/e2e/project.test.ts +38 -0
- package/templates/project-tee-starter/e2e/starter-plugin.test.ts +92 -0
- package/templates/project-tee-starter/package.json +76 -0
- package/templates/project-tee-starter/src/character.ts +257 -0
- package/templates/project-tee-starter/src/index.ts +33 -0
- package/templates/project-tee-starter/src/plugin.ts +169 -0
- package/templates/project-tee-starter/tsconfig.build.json +13 -0
- package/templates/project-tee-starter/tsconfig.json +30 -0
- package/templates/project-tee-starter/tsup.config.ts +19 -0
- package/templates/project-tee-starter/vitest.config.ts +19 -0
- package/dist/assets/index-eRnFTOEM.js.br +0 -0
- package/dist/eliza-J3ANDQXN.js +0 -13
- /package/dist/{chunk-YX7JHUJ5.js → chunk-BDPGXNHU.js} +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { describe, expect, it, vi, beforeAll, afterAll } from 'vitest';
|
|
2
|
+
import plugin from '../src/plugin';
|
|
3
|
+
import type { IAgentRuntime, Memory, State, Provider } from '@elizaos/core';
|
|
4
|
+
import { logger } from '@elizaos/core';
|
|
5
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
6
|
+
import dotenv from 'dotenv';
|
|
7
|
+
import teeStarterPlugin from '../src/plugin';
|
|
8
|
+
|
|
9
|
+
// Setup environment variables
|
|
10
|
+
dotenv.config();
|
|
11
|
+
|
|
12
|
+
// Set up logging to capture issues
|
|
13
|
+
beforeAll(() => {
|
|
14
|
+
vi.spyOn(logger, 'info');
|
|
15
|
+
vi.spyOn(logger, 'error');
|
|
16
|
+
vi.spyOn(logger, 'warn');
|
|
17
|
+
vi.spyOn(logger, 'debug');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterAll(() => {
|
|
21
|
+
vi.restoreAllMocks();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Helper function to document test results
|
|
25
|
+
function documentTestResult(testName: string, result: any, error: Error | null = null) {
|
|
26
|
+
logger.info(`TEST: ${testName}`);
|
|
27
|
+
if (result) {
|
|
28
|
+
if (typeof result === 'string') {
|
|
29
|
+
logger.info(`RESULT: ${result.substring(0, 100)}${result.length > 100 ? '...' : ''}`);
|
|
30
|
+
} else {
|
|
31
|
+
try {
|
|
32
|
+
logger.info(`RESULT: ${JSON.stringify(result, null, 2).substring(0, 200)}...`);
|
|
33
|
+
} catch (e) {
|
|
34
|
+
logger.info(`RESULT: [Complex object that couldn't be stringified]`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (error) {
|
|
39
|
+
logger.error(`ERROR: ${error.message}`);
|
|
40
|
+
if (error.stack) {
|
|
41
|
+
logger.error(`STACK: ${error.stack}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Create a realistic runtime for testing
|
|
47
|
+
function createRealRuntime(): IAgentRuntime {
|
|
48
|
+
return {
|
|
49
|
+
character: {
|
|
50
|
+
name: 'Test Character',
|
|
51
|
+
system: 'You are a helpful assistant for testing.',
|
|
52
|
+
plugins: [],
|
|
53
|
+
settings: {},
|
|
54
|
+
},
|
|
55
|
+
getSetting: (key: string) => null,
|
|
56
|
+
models: plugin.models,
|
|
57
|
+
db: {
|
|
58
|
+
get: async (key: string) => {
|
|
59
|
+
logger.info(`DB Get: ${key}`);
|
|
60
|
+
return null;
|
|
61
|
+
},
|
|
62
|
+
set: async (key: string, value: any) => {
|
|
63
|
+
logger.info(`DB Set: ${key} = ${JSON.stringify(value)}`);
|
|
64
|
+
return true;
|
|
65
|
+
},
|
|
66
|
+
delete: async (key: string) => {
|
|
67
|
+
logger.info(`DB Delete: ${key}`);
|
|
68
|
+
return true;
|
|
69
|
+
},
|
|
70
|
+
getKeys: async (pattern: string) => {
|
|
71
|
+
logger.info(`DB GetKeys: ${pattern}`);
|
|
72
|
+
return [];
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
memory: {
|
|
76
|
+
add: async (memory: any) => {
|
|
77
|
+
logger.info(`Memory Add: ${JSON.stringify(memory).substring(0, 100)}`);
|
|
78
|
+
},
|
|
79
|
+
get: async (id: string) => {
|
|
80
|
+
logger.info(`Memory Get: ${id}`);
|
|
81
|
+
return null;
|
|
82
|
+
},
|
|
83
|
+
getByEntityId: async (entityId: string) => {
|
|
84
|
+
logger.info(`Memory GetByEntityId: ${entityId}`);
|
|
85
|
+
return [];
|
|
86
|
+
},
|
|
87
|
+
getLatest: async (entityId: string) => {
|
|
88
|
+
logger.info(`Memory GetLatest: ${entityId}`);
|
|
89
|
+
return null;
|
|
90
|
+
},
|
|
91
|
+
getRecentMessages: async (options: any) => {
|
|
92
|
+
logger.info(`Memory GetRecentMessages: ${JSON.stringify(options)}`);
|
|
93
|
+
return [];
|
|
94
|
+
},
|
|
95
|
+
search: async (query: string) => {
|
|
96
|
+
logger.info(`Memory Search: ${query}`);
|
|
97
|
+
return [];
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
getService: (serviceType: string) => {
|
|
101
|
+
logger.info(`GetService: ${serviceType}`);
|
|
102
|
+
return null;
|
|
103
|
+
},
|
|
104
|
+
} as unknown as IAgentRuntime;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Create realistic memory object
|
|
108
|
+
function createRealMemory(): Memory {
|
|
109
|
+
const entityId = uuidv4();
|
|
110
|
+
const roomId = uuidv4();
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
id: uuidv4(),
|
|
114
|
+
entityId,
|
|
115
|
+
roomId,
|
|
116
|
+
timestamp: Date.now(),
|
|
117
|
+
content: {
|
|
118
|
+
text: 'What can you provide?',
|
|
119
|
+
source: 'test',
|
|
120
|
+
actions: [],
|
|
121
|
+
},
|
|
122
|
+
metadata: {
|
|
123
|
+
sessionId: uuidv4(),
|
|
124
|
+
conversationId: uuidv4(),
|
|
125
|
+
},
|
|
126
|
+
} as Memory;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
describe('Provider Tests', () => {
|
|
130
|
+
describe('HELLO_WORLD_PROVIDER', () => {
|
|
131
|
+
it('should exist in the plugin', () => {
|
|
132
|
+
const plugin = teeStarterPlugin;
|
|
133
|
+
expect(plugin).toBeDefined();
|
|
134
|
+
|
|
135
|
+
// Our plugin has no providers
|
|
136
|
+
expect(plugin.providers).toBeDefined();
|
|
137
|
+
expect(plugin.providers.length).toBe(0);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should have the correct structure', () => {
|
|
141
|
+
// Skip this test as we have no providers
|
|
142
|
+
expect(true).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should have a description explaining its purpose', () => {
|
|
146
|
+
// Skip this test as we have no providers
|
|
147
|
+
expect(true).toBe(true);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('should return provider data from the get method', async () => {
|
|
151
|
+
// Skip this test as we have no providers
|
|
152
|
+
expect(true).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('should handle error conditions gracefully', async () => {
|
|
156
|
+
// Skip this test as we have no providers
|
|
157
|
+
expect(true).toBe(true);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe('Provider Registration', () => {
|
|
162
|
+
it('should include providers in the plugin definition', () => {
|
|
163
|
+
const plugin = teeStarterPlugin;
|
|
164
|
+
expect(plugin.providers).toBeDefined();
|
|
165
|
+
expect(Array.isArray(plugin.providers)).toBe(true);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should correctly initialize providers array', () => {
|
|
169
|
+
const plugin = teeStarterPlugin;
|
|
170
|
+
|
|
171
|
+
// Providers should be an empty array
|
|
172
|
+
expect(plugin.providers).toBeDefined();
|
|
173
|
+
expect(plugin.providers.length).toBe(0);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('should have unique provider names', () => {
|
|
177
|
+
const plugin = teeStarterPlugin;
|
|
178
|
+
|
|
179
|
+
// No providers, so this test passes
|
|
180
|
+
if (plugin.providers && plugin.providers.length > 0) {
|
|
181
|
+
const providerNames = plugin.providers.map((p) => p.name);
|
|
182
|
+
const uniqueNames = new Set(providerNames);
|
|
183
|
+
expect(uniqueNames.size).toBe(providerNames.length);
|
|
184
|
+
} else {
|
|
185
|
+
expect(true).toBe(true);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import teeStarterPlugin from '../src/plugin';
|
|
3
|
+
|
|
4
|
+
describe('Plugin Routes', () => {
|
|
5
|
+
it('should not have custom routes (relies on other plugins for HTTP endpoints)', () => {
|
|
6
|
+
// Our plugin actually has a route defined
|
|
7
|
+
expect(teeStarterPlugin.routes).toBeDefined();
|
|
8
|
+
expect(teeStarterPlugin.routes?.length).toBe(1);
|
|
9
|
+
expect(teeStarterPlugin.routes?.[0].name).toBe('mr-tee-status-route');
|
|
10
|
+
expect(teeStarterPlugin.routes?.[0].path).toBe('/mr-tee-status');
|
|
11
|
+
expect(teeStarterPlugin.routes?.[0].type).toBe('GET');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should have correct plugin configuration', () => {
|
|
15
|
+
expect(teeStarterPlugin).toBeDefined();
|
|
16
|
+
expect(teeStarterPlugin.name).toBe('mr-tee-starter-plugin');
|
|
17
|
+
expect(teeStarterPlugin.description).toBe(
|
|
18
|
+
"Mr. TEE's starter plugin - using plugin-tee for attestation"
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { vi } from 'vitest';
|
|
2
|
+
import { type Content, type IAgentRuntime, type Memory, type State, logger } from '@elizaos/core';
|
|
3
|
+
import {
|
|
4
|
+
createMockRuntime as createCoreMockRuntime,
|
|
5
|
+
createMockMessage as createCoreMockMessage,
|
|
6
|
+
createMockState as createCoreMockState,
|
|
7
|
+
documentTestResult,
|
|
8
|
+
runCoreActionTests,
|
|
9
|
+
} from './utils/core-test-utils';
|
|
10
|
+
import { mrTeeCharacter } from '../src/character';
|
|
11
|
+
import plugin from '../src/plugin';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates an enhanced mock runtime for testing that includes the project's
|
|
15
|
+
* character and plugin
|
|
16
|
+
*
|
|
17
|
+
* @param overrides - Optional overrides for the default mock methods and properties
|
|
18
|
+
* @returns A mock runtime for testing
|
|
19
|
+
*/
|
|
20
|
+
export function createMockRuntime(overrides: Partial<IAgentRuntime> = {}): IAgentRuntime {
|
|
21
|
+
// Create base mock runtime with default core utilities
|
|
22
|
+
const baseRuntime = createCoreMockRuntime();
|
|
23
|
+
|
|
24
|
+
// Enhance with project-specific configuration
|
|
25
|
+
const mockRuntime = {
|
|
26
|
+
...baseRuntime,
|
|
27
|
+
character: mrTeeCharacter,
|
|
28
|
+
plugins: [plugin],
|
|
29
|
+
registerPlugin: vi.fn(),
|
|
30
|
+
initialize: vi.fn(),
|
|
31
|
+
getService: vi.fn(),
|
|
32
|
+
getSetting: vi.fn().mockReturnValue(null),
|
|
33
|
+
useModel: vi.fn().mockResolvedValue('Test model response'),
|
|
34
|
+
getProviderResults: vi.fn().mockResolvedValue([]),
|
|
35
|
+
evaluateProviders: vi.fn().mockResolvedValue([]),
|
|
36
|
+
evaluate: vi.fn().mockResolvedValue([]),
|
|
37
|
+
...overrides,
|
|
38
|
+
} as unknown as IAgentRuntime;
|
|
39
|
+
|
|
40
|
+
return mockRuntime;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Creates a mock Message object for testing
|
|
45
|
+
*
|
|
46
|
+
* @param text - The message text
|
|
47
|
+
* @param overrides - Optional overrides for the default memory properties
|
|
48
|
+
* @returns A mock memory object
|
|
49
|
+
*/
|
|
50
|
+
export function createMockMessage(text: string, overrides: Partial<Memory> = {}): Memory {
|
|
51
|
+
const baseMessage = createCoreMockMessage(text);
|
|
52
|
+
return {
|
|
53
|
+
...baseMessage,
|
|
54
|
+
...overrides,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Creates a mock State object for testing
|
|
60
|
+
*
|
|
61
|
+
* @param overrides - Optional overrides for the default state properties
|
|
62
|
+
* @returns A mock state object
|
|
63
|
+
*/
|
|
64
|
+
export function createMockState(overrides: Partial<State> = {}): State {
|
|
65
|
+
const baseState = createCoreMockState();
|
|
66
|
+
return {
|
|
67
|
+
...baseState,
|
|
68
|
+
...overrides,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Creates a standardized setup for testing with consistent mock objects
|
|
74
|
+
*
|
|
75
|
+
* @param overrides - Optional overrides for default mock implementations
|
|
76
|
+
* @returns An object containing mockRuntime, mockMessage, mockState, and callbackFn
|
|
77
|
+
*/
|
|
78
|
+
export function setupTest(
|
|
79
|
+
options: {
|
|
80
|
+
messageText?: string;
|
|
81
|
+
messageOverrides?: Partial<Memory>;
|
|
82
|
+
runtimeOverrides?: Partial<IAgentRuntime>;
|
|
83
|
+
stateOverrides?: Partial<State>;
|
|
84
|
+
} = {}
|
|
85
|
+
) {
|
|
86
|
+
// Create mock callback function
|
|
87
|
+
const callbackFn = vi.fn();
|
|
88
|
+
|
|
89
|
+
// Create a message
|
|
90
|
+
const mockMessage = createMockMessage(
|
|
91
|
+
options.messageText || 'Test message',
|
|
92
|
+
options.messageOverrides || {}
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// Create a state object
|
|
96
|
+
const mockState = createMockState(options.stateOverrides || {});
|
|
97
|
+
|
|
98
|
+
// Create a mock runtime
|
|
99
|
+
const mockRuntime = createMockRuntime(options.runtimeOverrides || {});
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
mockRuntime,
|
|
103
|
+
mockMessage,
|
|
104
|
+
mockState,
|
|
105
|
+
callbackFn,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Export other utility functions
|
|
110
|
+
export { documentTestResult, runCoreActionTests };
|
|
111
|
+
|
|
112
|
+
// Add spy on logger for common usage in tests
|
|
113
|
+
export function setupLoggerSpies() {
|
|
114
|
+
vi.spyOn(logger, 'info').mockImplementation(() => {});
|
|
115
|
+
vi.spyOn(logger, 'error').mockImplementation(() => {});
|
|
116
|
+
vi.spyOn(logger, 'warn').mockImplementation(() => {});
|
|
117
|
+
vi.spyOn(logger, 'debug').mockImplementation(() => {});
|
|
118
|
+
|
|
119
|
+
// allow tests to restore originals
|
|
120
|
+
return () => vi.restoreAllMocks();
|
|
121
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { vi } from 'vitest';
|
|
2
|
+
import { composeActionExamples, formatActionNames, formatActions } from '@elizaos/core';
|
|
3
|
+
import type { Action, Content, IAgentRuntime, Memory, State } from '@elizaos/core';
|
|
4
|
+
import { logger } from '@elizaos/core';
|
|
5
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Utility functions for reusing core package tests in project-starter tests
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Runs core package action tests against the provided actions
|
|
13
|
+
* @param actions The actions to test
|
|
14
|
+
*/
|
|
15
|
+
export const runCoreActionTests = (actions: Action[]) => {
|
|
16
|
+
// Validate action structure (similar to core tests)
|
|
17
|
+
for (const action of actions) {
|
|
18
|
+
if (!action.name) {
|
|
19
|
+
throw new Error('Action missing name property');
|
|
20
|
+
}
|
|
21
|
+
if (!action.description) {
|
|
22
|
+
throw new Error(`Action ${action.name} missing description property`);
|
|
23
|
+
}
|
|
24
|
+
if (!action.examples || !Array.isArray(action.examples)) {
|
|
25
|
+
throw new Error(`Action ${action.name} missing examples array`);
|
|
26
|
+
}
|
|
27
|
+
if (!action.similes || !Array.isArray(action.similes)) {
|
|
28
|
+
throw new Error(`Action ${action.name} missing similes array`);
|
|
29
|
+
}
|
|
30
|
+
if (typeof action.handler !== 'function') {
|
|
31
|
+
throw new Error(`Action ${action.name} missing handler function`);
|
|
32
|
+
}
|
|
33
|
+
if (typeof action.validate !== 'function') {
|
|
34
|
+
throw new Error(`Action ${action.name} missing validate function`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Validate example structure
|
|
39
|
+
for (const action of actions) {
|
|
40
|
+
for (const example of action.examples ?? []) {
|
|
41
|
+
for (const message of example) {
|
|
42
|
+
if (!message.name) {
|
|
43
|
+
throw new Error(`Example message in action ${action.name} missing name property`);
|
|
44
|
+
}
|
|
45
|
+
if (!message.content) {
|
|
46
|
+
throw new Error(`Example message in action ${action.name} missing content property`);
|
|
47
|
+
}
|
|
48
|
+
if (!message.content.text) {
|
|
49
|
+
throw new Error(`Example message in action ${action.name} missing content.text property`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Validate uniqueness of action names
|
|
56
|
+
const names = actions.map((action) => action.name);
|
|
57
|
+
const uniqueNames = new Set(names);
|
|
58
|
+
if (names.length !== uniqueNames.size) {
|
|
59
|
+
throw new Error('Duplicate action names found');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Test action formatting
|
|
63
|
+
const formattedNames = formatActionNames(actions);
|
|
64
|
+
if (!formattedNames && actions.length > 0) {
|
|
65
|
+
throw new Error('formatActionNames failed to produce output');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const formattedActions = formatActions(actions);
|
|
69
|
+
if (!formattedActions && actions.length > 0) {
|
|
70
|
+
throw new Error('formatActions failed to produce output');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const composedExamples = composeActionExamples(actions, 1);
|
|
74
|
+
if (!composedExamples && actions.length > 0) {
|
|
75
|
+
throw new Error('composeActionExamples failed to produce output');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
formattedNames,
|
|
80
|
+
formattedActions,
|
|
81
|
+
composedExamples,
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Creates a mock runtime for testing
|
|
87
|
+
*/
|
|
88
|
+
export const createMockRuntime = (): IAgentRuntime => {
|
|
89
|
+
return {
|
|
90
|
+
character: {
|
|
91
|
+
name: 'Test Character',
|
|
92
|
+
system: 'You are a helpful assistant for testing.',
|
|
93
|
+
},
|
|
94
|
+
getSetting: (key: string) => null,
|
|
95
|
+
// Include real model functionality
|
|
96
|
+
models: {},
|
|
97
|
+
// Add real database functionality
|
|
98
|
+
db: {
|
|
99
|
+
get: async () => null,
|
|
100
|
+
set: async () => true,
|
|
101
|
+
delete: async () => true,
|
|
102
|
+
getKeys: async () => [],
|
|
103
|
+
},
|
|
104
|
+
// Add real memory functionality
|
|
105
|
+
memory: {
|
|
106
|
+
add: async () => {},
|
|
107
|
+
get: async () => null,
|
|
108
|
+
getByEntityId: async () => [],
|
|
109
|
+
getLatest: async () => null,
|
|
110
|
+
getRecentMessages: async () => [],
|
|
111
|
+
search: async () => [],
|
|
112
|
+
},
|
|
113
|
+
actions: [],
|
|
114
|
+
providers: [],
|
|
115
|
+
getService: vi.fn(),
|
|
116
|
+
processActions: vi.fn(),
|
|
117
|
+
} as any as IAgentRuntime;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Documents test results for logging and debugging
|
|
122
|
+
*/
|
|
123
|
+
export const documentTestResult = (testName: string, result: any, error: Error | null = null) => {
|
|
124
|
+
logger.info(`TEST: ${testName}`);
|
|
125
|
+
if (result) {
|
|
126
|
+
if (typeof result === 'string') {
|
|
127
|
+
logger.info(`RESULT: ${result.substring(0, 100)}${result.length > 100 ? '...' : ''}`);
|
|
128
|
+
} else {
|
|
129
|
+
try {
|
|
130
|
+
logger.info(`RESULT: ${JSON.stringify(result, null, 2).substring(0, 200)}...`);
|
|
131
|
+
} catch (e) {
|
|
132
|
+
logger.info(`RESULT: [Complex object that couldn't be stringified]`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (error) {
|
|
137
|
+
logger.error(`ERROR: ${error.message}`);
|
|
138
|
+
if (error.stack) {
|
|
139
|
+
logger.error(`STACK: ${error.stack}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Creates a mock message for testing
|
|
146
|
+
*/
|
|
147
|
+
export const createMockMessage = (text: string): Memory => {
|
|
148
|
+
return {
|
|
149
|
+
entityId: uuidv4(),
|
|
150
|
+
roomId: uuidv4(),
|
|
151
|
+
content: {
|
|
152
|
+
text,
|
|
153
|
+
source: 'test',
|
|
154
|
+
},
|
|
155
|
+
} as Memory;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Creates a mock state for testing
|
|
160
|
+
*/
|
|
161
|
+
export const createMockState = (): State => {
|
|
162
|
+
return {
|
|
163
|
+
values: {},
|
|
164
|
+
data: {},
|
|
165
|
+
text: '',
|
|
166
|
+
};
|
|
167
|
+
};
|
|
Binary file
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
services:
|
|
3
|
+
postgres:
|
|
4
|
+
image: ankane/pgvector:latest
|
|
5
|
+
environment:
|
|
6
|
+
- POSTGRES_PASSWORD=postgres
|
|
7
|
+
- POSTGRES_USER=postgres
|
|
8
|
+
- POSTGRES_DB=eliza
|
|
9
|
+
- PGDATA=/var/lib/postgresql/data/pgdata
|
|
10
|
+
volumes:
|
|
11
|
+
- postgres-data:/var/lib/postgresql/data:rw
|
|
12
|
+
ports:
|
|
13
|
+
- '127.0.0.1:5432:5432'
|
|
14
|
+
healthcheck:
|
|
15
|
+
test: ['CMD-SHELL', 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}']
|
|
16
|
+
interval: 5s
|
|
17
|
+
timeout: 5s
|
|
18
|
+
retries: 5
|
|
19
|
+
restart: always
|
|
20
|
+
networks:
|
|
21
|
+
- eliza-network
|
|
22
|
+
elizaos:
|
|
23
|
+
image: ${DOCKER_IMAGE}
|
|
24
|
+
container_name: elizaos
|
|
25
|
+
command: sh -c "bun run start"
|
|
26
|
+
volumes:
|
|
27
|
+
- /var/run/tappd.sock:/var/run/tappd.sock
|
|
28
|
+
environment:
|
|
29
|
+
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
|
30
|
+
- SERVER_PORT=${SERVER_PORT}
|
|
31
|
+
- POSTGRES_URL=${POSTGRES_URL}
|
|
32
|
+
- EVM_CHAINS=${EVM_CHAINS}
|
|
33
|
+
- BIRDEYE_API_KEY=${BIRDEYE_API_KEY}
|
|
34
|
+
- DISCORD_APPLICATION_ID=${DISCORD_APPLICATION_ID}
|
|
35
|
+
- DISCORD_API_TOKEN=${DISCORD_API_TOKEN}
|
|
36
|
+
- TEE_MODE=${TEE_MODE:-PRODUCTION}
|
|
37
|
+
- TEE_VENDOR=${TEE_VENDOR:-phala}
|
|
38
|
+
- WALLET_SECRET_SALT=${WALLET_SECRET_SALT}
|
|
39
|
+
- REDPILL_API_KEY=${REDPILL_API_KEY}
|
|
40
|
+
- ELEVENLABS_API_KEY=${ELEVENLABS_API_KEY}
|
|
41
|
+
- ELEVENLABS_VOICE_ID=${ELEVENLABS_VOICE_ID}
|
|
42
|
+
ports:
|
|
43
|
+
- '3000:3000'
|
|
44
|
+
- '50000-50100:50000-50100/udp'
|
|
45
|
+
depends_on:
|
|
46
|
+
postgres:
|
|
47
|
+
condition: service_healthy
|
|
48
|
+
restart: always
|
|
49
|
+
networks:
|
|
50
|
+
- eliza-network
|
|
51
|
+
|
|
52
|
+
networks:
|
|
53
|
+
eliza-network:
|
|
54
|
+
driver: bridge
|
|
55
|
+
|
|
56
|
+
volumes:
|
|
57
|
+
postgres-data:
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { TestSuite, IAgentRuntime } from '@elizaos/core';
|
|
2
|
+
import { mrTeeCharacter } from '../src/character';
|
|
3
|
+
|
|
4
|
+
export class MrTeeProjectTestSuite implements TestSuite {
|
|
5
|
+
name = 'mr-tee-project';
|
|
6
|
+
description = 'E2E tests for Mr. TEE project-specific features';
|
|
7
|
+
|
|
8
|
+
tests = [
|
|
9
|
+
{
|
|
10
|
+
name: 'Mr. TEE Project runtime environment test',
|
|
11
|
+
fn: async (runtime: IAgentRuntime) => {
|
|
12
|
+
try {
|
|
13
|
+
if (!runtime.character) {
|
|
14
|
+
throw new Error('Character not loaded in runtime');
|
|
15
|
+
}
|
|
16
|
+
if (runtime.character.name !== mrTeeCharacter.name) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Expected character name to be ${mrTeeCharacter.name}, got ${runtime.character.name}`
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
if (!runtime.character.system?.includes('Mr. TEE')) {
|
|
22
|
+
throw new Error('Character system prompt does not contain "Mr. TEE"');
|
|
23
|
+
}
|
|
24
|
+
const hasTeePlugin = runtime.character.plugins?.some(
|
|
25
|
+
(p) => typeof p === 'string' && p.includes('tee')
|
|
26
|
+
);
|
|
27
|
+
if (!hasTeePlugin) {
|
|
28
|
+
throw new Error('Character does not have TEE plugin');
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
throw new Error(`Mr. TEE Project runtime environment test failed: ${error.message}`);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default new MrTeeProjectTestSuite();
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { character } from '../src/index';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
|
|
4
|
+
// Define a minimal TestSuite interface that matches what's needed
|
|
5
|
+
interface TestSuite {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
tests: Array<{
|
|
9
|
+
name: string;
|
|
10
|
+
fn: (runtime: any) => Promise<any>;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Define minimal interfaces for the types we need
|
|
15
|
+
type UUID = `${string}-${string}-${string}-${string}-${string}`;
|
|
16
|
+
|
|
17
|
+
interface Memory {
|
|
18
|
+
entityId: UUID;
|
|
19
|
+
roomId: UUID;
|
|
20
|
+
content: {
|
|
21
|
+
text: string;
|
|
22
|
+
source: string;
|
|
23
|
+
actions?: string[];
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface State {
|
|
28
|
+
values: Record<string, any>;
|
|
29
|
+
data: Record<string, any>;
|
|
30
|
+
text: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface Content {
|
|
34
|
+
text: string;
|
|
35
|
+
source?: string;
|
|
36
|
+
actions?: string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class StarterTestSuite implements TestSuite {
|
|
40
|
+
name = 'starter';
|
|
41
|
+
description = 'E2E tests for the starter project';
|
|
42
|
+
|
|
43
|
+
tests = [
|
|
44
|
+
{
|
|
45
|
+
name: 'Character configuration test',
|
|
46
|
+
fn: async (runtime: any) => {
|
|
47
|
+
const requiredFields = ['name', 'bio', 'plugins', 'system', 'messageExamples'];
|
|
48
|
+
const missingFields = requiredFields.filter((field) => !(field in character));
|
|
49
|
+
|
|
50
|
+
if (missingFields.length > 0) {
|
|
51
|
+
throw new Error(`Missing required fields: ${missingFields.join(', ')}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Additional character property validations
|
|
55
|
+
if (character.name !== 'Mr. TEE') {
|
|
56
|
+
throw new Error(`Expected character name to be 'Mr. TEE', got '${character.name}'`);
|
|
57
|
+
}
|
|
58
|
+
if (!Array.isArray(character.plugins)) {
|
|
59
|
+
throw new Error('Character plugins should be an array');
|
|
60
|
+
}
|
|
61
|
+
if (!character.system) {
|
|
62
|
+
throw new Error('Character system prompt is required');
|
|
63
|
+
}
|
|
64
|
+
if (!Array.isArray(character.bio)) {
|
|
65
|
+
throw new Error('Character bio should be an array');
|
|
66
|
+
}
|
|
67
|
+
if (!Array.isArray(character.messageExamples)) {
|
|
68
|
+
throw new Error('Character message examples should be an array');
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'Plugin initialization test',
|
|
74
|
+
fn: async (runtime: any) => {
|
|
75
|
+
// Test plugin initialization with empty config
|
|
76
|
+
try {
|
|
77
|
+
await runtime.registerPlugin({
|
|
78
|
+
name: 'starter',
|
|
79
|
+
description: 'A starter plugin for Eliza',
|
|
80
|
+
init: async () => {},
|
|
81
|
+
config: {},
|
|
82
|
+
});
|
|
83
|
+
} catch (error) {
|
|
84
|
+
throw new Error(`Failed to register plugin: ${error.message}`);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Export a default instance of the test suite for the E2E test runner
|
|
92
|
+
export default new StarterTestSuite();
|