@elizaos/cli 1.0.8 → 1.0.10
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 +9 -16
- package/dist/assets/{index-CZAd5zm2.js → index-CmuPnu0u.js} +72 -89
- package/dist/assets/index-CmuPnu0u.js.br +0 -0
- package/dist/assets/index-CmuPnu0u.js.map +1 -0
- package/dist/assets/{index-CaEsCLCC.js → index-DDQnwxzL.js} +28798 -16391
- package/dist/assets/{index-CaEsCLCC.js.map → index-DDQnwxzL.js.map} +1 -1
- package/dist/assets/index-Df1AFSuJ.css +1 -0
- package/dist/assets/index-Df1AFSuJ.css.br +0 -0
- package/dist/assets/vendor-DSdxb8P-.js.map +1 -1
- package/dist/{chunk-REBZFQYE.js → chunk-7HYEGM5V.js} +967 -1597
- package/dist/{chunk-W3HS2NP6.js → chunk-B4KJXECB.js} +13 -18
- package/dist/{chunk-33BHGAF7.js → chunk-GWQB7PBK.js} +59 -32
- package/dist/{chunk-CVADLFW6.js → chunk-LQ6XHF53.js} +4543 -3043
- package/dist/{chunk-GYTAJJOD.js → chunk-RIAWNDYI.js} +16 -2
- package/dist/{chunk-IEKLJDUU.js → chunk-WS4DWCDZ.js} +54 -32
- package/dist/commands/agent/actions/index.d.ts +5 -1
- package/dist/commands/agent/actions/index.js +5 -4
- package/dist/commands/agent/index.js +3 -4
- package/dist/commands/create/actions/index.js +4 -5
- package/dist/commands/create/index.js +5 -6
- package/dist/{fileFromPath-DCRQMDLJ.js → fileFromPath-KB6XMTJ4.js} +1 -0
- package/dist/index.html +2 -2
- package/dist/index.js +9346 -102098
- package/dist/{migrator-KZLCVEIH.js → migrator-JREQPDN3.js} +42 -220
- package/dist/pglite.data +0 -0
- package/dist/pglite.wasm +0 -0
- package/dist/plugin-creator-T4K2673C.js +910 -0
- package/dist/{registry-XFOSZFU4.js → registry-CBMRMYCG.js} +3 -4
- package/dist/templates/plugin-starter/README.md +255 -0
- package/dist/templates/plugin-starter/bunfig.toml +6 -0
- package/dist/templates/plugin-starter/cypress.config.ts +18 -0
- package/dist/templates/plugin-starter/index.html +13 -0
- package/dist/templates/plugin-starter/package.json +95 -0
- package/dist/templates/plugin-starter/postcss.config.js +3 -0
- package/dist/templates/plugin-starter/scripts/test-e2e-manual.js +201 -0
- package/dist/templates/plugin-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +404 -0
- package/dist/templates/plugin-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +287 -0
- package/dist/templates/plugin-starter/src/__tests__/cypress/support/commands.ts +38 -0
- package/dist/templates/plugin-starter/src/__tests__/cypress/support/component-index.html +11 -0
- package/dist/templates/plugin-starter/src/__tests__/cypress/support/component.ts +33 -0
- package/dist/templates/plugin-starter/src/__tests__/cypress/support/e2e.ts +11 -0
- package/dist/templates/plugin-starter/src/__tests__/cypress/tsconfig.json +10 -0
- package/dist/templates/plugin-starter/src/__tests__/e2e/README.md +47 -0
- package/dist/templates/plugin-starter/src/__tests__/e2e/starter-plugin.ts +320 -0
- package/{templates/plugin-starter → dist/templates/plugin-starter/src}/__tests__/integration.test.ts +22 -17
- package/{templates/plugin-starter → dist/templates/plugin-starter/src}/__tests__/plugin.test.ts +8 -8
- package/{templates/plugin-starter → dist/templates/plugin-starter/src}/__tests__/test-utils.ts +17 -17
- package/dist/templates/plugin-starter/src/frontend/index.css +77 -0
- package/dist/templates/plugin-starter/src/frontend/index.tsx +164 -0
- package/dist/templates/plugin-starter/src/frontend/utils.ts +6 -0
- package/dist/templates/plugin-starter/src/index.ts +274 -0
- package/dist/templates/plugin-starter/src/tests.ts +6 -0
- package/dist/templates/plugin-starter/tailwind.config.js +62 -0
- package/dist/templates/plugin-starter/tsconfig.build.json +11 -0
- package/dist/templates/plugin-starter/tsconfig.json +28 -0
- package/dist/templates/plugin-starter/tsup.config.ts +20 -0
- package/dist/templates/plugin-starter/vite.config.ts +20 -0
- package/dist/templates/project-starter/.env.example +153 -0
- package/dist/templates/project-starter/README.md +109 -0
- package/dist/templates/project-starter/bunfig.toml +6 -0
- package/dist/templates/project-starter/cypress.config.ts +31 -0
- package/dist/templates/project-starter/index.html +13 -0
- package/dist/templates/project-starter/package.json +83 -0
- package/dist/templates/project-starter/postcss.config.js +3 -0
- package/dist/templates/project-starter/scripts/test-all.sh +101 -0
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/actions.test.ts +6 -6
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/character.test.ts +3 -3
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/config.test.ts +18 -18
- package/dist/templates/project-starter/src/__tests__/cypress/component/Accessibility.cy.tsx +271 -0
- package/dist/templates/project-starter/src/__tests__/cypress/component/ApiIntegration.cy.tsx +220 -0
- package/dist/templates/project-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +146 -0
- package/dist/templates/project-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +51 -0
- package/dist/templates/project-starter/src/__tests__/cypress/e2e/agent-chat.cy.ts +235 -0
- package/dist/templates/project-starter/src/__tests__/cypress/e2e/dashboard.cy.ts +146 -0
- package/dist/templates/project-starter/src/__tests__/cypress/e2e/user-workflow.cy.ts +257 -0
- package/dist/templates/project-starter/src/__tests__/cypress/support/commands.ts +44 -0
- package/dist/templates/project-starter/src/__tests__/cypress/support/component-index.html +11 -0
- package/dist/templates/project-starter/src/__tests__/cypress/support/component.ts +33 -0
- package/dist/templates/project-starter/src/__tests__/cypress/support/e2e.ts +179 -0
- package/dist/templates/project-starter/src/__tests__/e2e/index.ts +14 -0
- package/dist/templates/project-starter/src/__tests__/e2e/natural-language.test.ts +246 -0
- package/dist/templates/project-starter/src/__tests__/e2e/project.test.ts +155 -0
- package/dist/templates/project-starter/src/__tests__/e2e/starter-plugin.test.ts +421 -0
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/env.test.ts +2 -2
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/error-handling.test.ts +17 -17
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/events.test.ts +7 -7
- package/dist/templates/project-starter/src/__tests__/file-structure.test.ts +135 -0
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/integration.test.ts +25 -25
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/models.test.ts +6 -6
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/plugin.test.ts +9 -9
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/provider.test.ts +7 -7
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/routes.test.ts +3 -3
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/test-utils.ts +17 -17
- package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/utils/core-test-utils.ts +3 -3
- package/dist/templates/project-starter/src/frontend/index.css +77 -0
- package/dist/templates/project-starter/src/frontend/index.html +19 -0
- package/dist/templates/project-starter/src/frontend/index.tsx +98 -0
- package/dist/templates/project-starter/src/frontend/utils.ts +6 -0
- package/dist/templates/project-starter/src/index.ts +153 -0
- package/dist/templates/project-starter/src/plugin.ts +255 -0
- package/dist/templates/project-starter/tailwind.config.js +62 -0
- package/dist/templates/project-starter/tsconfig.build.json +20 -0
- package/dist/templates/project-starter/tsconfig.json +39 -0
- package/dist/templates/project-starter/tsup.config.ts +19 -0
- package/dist/templates/project-starter/vite.config.ts +39 -0
- package/dist/templates/project-tee-starter/.dockerignore +20 -0
- package/dist/templates/project-tee-starter/.env.example +55 -0
- package/dist/templates/project-tee-starter/Dockerfile +66 -0
- package/dist/templates/project-tee-starter/GUIDE.md +235 -0
- package/dist/templates/project-tee-starter/README.md +173 -0
- package/dist/templates/project-tee-starter/__tests__/actions.test.ts +9 -0
- package/dist/templates/project-tee-starter/__tests__/character.test.ts +86 -0
- package/dist/templates/project-tee-starter/__tests__/config.test.ts +31 -0
- package/dist/templates/project-tee-starter/__tests__/env.test.ts +87 -0
- package/dist/templates/project-tee-starter/__tests__/error-handling.test.ts +30 -0
- package/dist/templates/project-tee-starter/__tests__/events.test.ts +21 -0
- package/{templates/project-starter → dist/templates/project-tee-starter}/__tests__/file-structure.test.ts +6 -6
- package/dist/templates/project-tee-starter/__tests__/integration.test.ts +205 -0
- package/dist/templates/project-tee-starter/__tests__/models.test.ts +22 -0
- package/dist/templates/project-tee-starter/__tests__/plugin.test.ts +38 -0
- package/dist/templates/project-tee-starter/__tests__/provider.test.ts +189 -0
- package/dist/templates/project-tee-starter/__tests__/routes.test.ts +21 -0
- package/dist/templates/project-tee-starter/__tests__/test-utils.ts +121 -0
- package/dist/templates/project-tee-starter/__tests__/utils/core-test-utils.ts +167 -0
- package/dist/templates/project-tee-starter/assets/mr-tee-portrait.jpg +0 -0
- package/dist/templates/project-tee-starter/bunfig.toml +6 -0
- package/dist/templates/project-tee-starter/docker-compose.yaml +57 -0
- package/dist/templates/project-tee-starter/e2e/project.test.ts +38 -0
- package/dist/templates/project-tee-starter/e2e/starter-plugin.test.ts +92 -0
- package/dist/templates/project-tee-starter/package.json +74 -0
- package/dist/templates/project-tee-starter/src/character.ts +257 -0
- package/dist/templates/project-tee-starter/src/index.ts +33 -0
- package/dist/templates/project-tee-starter/src/plugin.ts +169 -0
- package/dist/templates/project-tee-starter/tsconfig.build.json +13 -0
- package/dist/templates/project-tee-starter/tsconfig.json +30 -0
- package/dist/templates/project-tee-starter/tsup.config.ts +19 -0
- package/dist/{utils-DIZZ3HNZ.js → utils-TIALZU53.js} +9 -8
- package/package.json +29 -12
- package/templates/plugin-starter/README.md +38 -13
- package/templates/plugin-starter/bunfig.toml +6 -0
- package/templates/plugin-starter/cypress.config.ts +18 -0
- package/templates/plugin-starter/index.html +13 -0
- package/templates/plugin-starter/package.json +19 -7
- package/templates/plugin-starter/postcss.config.js +3 -0
- package/templates/plugin-starter/scripts/test-e2e-manual.js +201 -0
- package/templates/plugin-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +404 -0
- package/templates/plugin-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +287 -0
- package/templates/plugin-starter/src/__tests__/cypress/support/commands.ts +38 -0
- package/templates/plugin-starter/src/__tests__/cypress/support/component-index.html +11 -0
- package/templates/plugin-starter/src/__tests__/cypress/support/component.ts +33 -0
- package/templates/plugin-starter/src/__tests__/cypress/support/e2e.ts +11 -0
- package/templates/plugin-starter/src/__tests__/cypress/tsconfig.json +10 -0
- package/templates/plugin-starter/src/__tests__/e2e/README.md +47 -0
- package/templates/plugin-starter/src/__tests__/e2e/starter-plugin.ts +320 -0
- package/templates/plugin-starter/src/__tests__/integration.test.ts +138 -0
- package/templates/plugin-starter/src/__tests__/plugin.test.ts +182 -0
- package/templates/plugin-starter/src/__tests__/test-utils.ts +162 -0
- package/templates/plugin-starter/src/frontend/index.css +77 -0
- package/templates/plugin-starter/src/frontend/index.tsx +164 -0
- package/templates/plugin-starter/src/frontend/utils.ts +6 -0
- package/templates/plugin-starter/src/index.ts +31 -8
- package/templates/plugin-starter/src/tests.ts +6 -0
- package/templates/plugin-starter/tailwind.config.js +62 -0
- package/templates/plugin-starter/tsconfig.json +8 -8
- package/templates/plugin-starter/vite.config.ts +20 -0
- package/templates/project-starter/bunfig.toml +6 -0
- package/templates/project-starter/cypress.config.ts +31 -0
- package/templates/project-starter/index.html +13 -0
- package/templates/project-starter/package.json +37 -14
- package/templates/project-starter/postcss.config.js +3 -0
- package/templates/project-starter/scripts/test-all.sh +101 -0
- package/templates/project-starter/src/__tests__/actions.test.ts +155 -0
- package/templates/project-starter/src/__tests__/character.test.ts +86 -0
- package/templates/project-starter/src/__tests__/config.test.ts +193 -0
- package/templates/project-starter/src/__tests__/cypress/component/Accessibility.cy.tsx +271 -0
- package/templates/project-starter/src/__tests__/cypress/component/ApiIntegration.cy.tsx +220 -0
- package/templates/project-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +146 -0
- package/templates/project-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +51 -0
- package/templates/project-starter/src/__tests__/cypress/e2e/agent-chat.cy.ts +235 -0
- package/templates/project-starter/src/__tests__/cypress/e2e/dashboard.cy.ts +146 -0
- package/templates/project-starter/src/__tests__/cypress/e2e/user-workflow.cy.ts +257 -0
- package/templates/project-starter/src/__tests__/cypress/support/commands.ts +44 -0
- package/templates/project-starter/src/__tests__/cypress/support/component-index.html +11 -0
- package/templates/project-starter/src/__tests__/cypress/support/component.ts +33 -0
- package/templates/project-starter/src/__tests__/cypress/support/e2e.ts +179 -0
- package/templates/project-starter/src/__tests__/e2e/index.ts +14 -0
- package/templates/project-starter/src/__tests__/e2e/natural-language.test.ts +246 -0
- package/templates/project-starter/src/__tests__/e2e/project.test.ts +155 -0
- package/templates/project-starter/src/__tests__/e2e/starter-plugin.test.ts +421 -0
- package/templates/project-starter/src/__tests__/env.test.ts +87 -0
- package/templates/project-starter/src/__tests__/error-handling.test.ts +177 -0
- package/templates/project-starter/src/__tests__/events.test.ts +144 -0
- package/templates/project-starter/src/__tests__/file-structure.test.ts +135 -0
- package/templates/project-starter/src/__tests__/integration.test.ts +209 -0
- package/templates/project-starter/src/__tests__/models.test.ts +152 -0
- package/templates/project-starter/src/__tests__/plugin.test.ts +393 -0
- package/templates/project-starter/src/__tests__/provider.test.ts +325 -0
- package/templates/project-starter/src/__tests__/routes.test.ts +79 -0
- package/templates/project-starter/src/__tests__/test-utils.ts +121 -0
- package/templates/project-starter/src/__tests__/utils/core-test-utils.ts +180 -0
- package/templates/project-starter/src/frontend/index.css +77 -0
- package/templates/project-starter/src/frontend/index.html +19 -0
- package/templates/project-starter/src/frontend/index.tsx +98 -0
- package/templates/project-starter/src/frontend/utils.ts +6 -0
- package/templates/project-starter/src/index.ts +9 -1
- package/templates/project-starter/tailwind.config.js +62 -0
- package/templates/project-starter/tsconfig.build.json +9 -2
- package/templates/project-starter/tsconfig.json +15 -6
- package/templates/project-starter/tsup.config.ts +1 -1
- package/templates/project-starter/vite.config.ts +39 -0
- package/templates/project-tee-starter/__tests__/actions.test.ts +1 -1
- package/templates/project-tee-starter/__tests__/character.test.ts +1 -1
- package/templates/project-tee-starter/__tests__/config.test.ts +1 -1
- package/templates/project-tee-starter/__tests__/env.test.ts +2 -2
- package/templates/project-tee-starter/__tests__/error-handling.test.ts +1 -1
- package/templates/project-tee-starter/__tests__/events.test.ts +1 -1
- package/templates/project-tee-starter/__tests__/file-structure.test.ts +5 -5
- package/templates/project-tee-starter/__tests__/integration.test.ts +22 -26
- package/templates/project-tee-starter/__tests__/models.test.ts +1 -1
- package/templates/project-tee-starter/__tests__/plugin.test.ts +6 -12
- package/templates/project-tee-starter/__tests__/provider.test.ts +6 -6
- package/templates/project-tee-starter/__tests__/routes.test.ts +1 -1
- package/templates/project-tee-starter/__tests__/test-utils.ts +15 -15
- package/templates/project-tee-starter/__tests__/utils/core-test-utils.ts +3 -3
- package/templates/project-tee-starter/bunfig.toml +6 -0
- package/templates/project-tee-starter/package.json +10 -12
- package/dist/assets/index-CZAd5zm2.js.br +0 -0
- package/dist/assets/index-CZAd5zm2.js.map +0 -1
- package/dist/assets/index-DyA-lndn.css +0 -1
- package/dist/assets/index-DyA-lndn.css.br +0 -0
- package/dist/chunk-CEE6RKN5.js +0 -2746
- package/dist/chunk-MA2ZXPG6.js +0 -260
- package/dist/chunk-TUAYJIF2.js +0 -3649
- package/dist/lib-NAGYZHVV.js +0 -9
- package/dist/plugin-creator-IC42XOHG.js +0 -29165
- package/templates/plugin-starter/e2e/starter-plugin.test.ts +0 -171
- package/templates/plugin-starter/images/README.md +0 -24
- package/templates/plugin-starter/vitest.config.ts +0 -16
- package/templates/project-starter/e2e/project.test.ts +0 -34
- package/templates/project-starter/e2e/starter-plugin.test.ts +0 -217
- package/templates/project-starter/vitest.config.ts +0 -16
- package/templates/project-tee-starter/vitest.config.ts +0 -19
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import { describe, expect, it, spyOn, beforeEach, afterEach, beforeAll, afterAll } from 'bun:test';
|
|
2
|
+
import plugin from '../plugin';
|
|
3
|
+
import { ModelType, logger } from '@elizaos/core';
|
|
4
|
+
import { StarterService } from '../plugin';
|
|
5
|
+
import dotenv from 'dotenv';
|
|
6
|
+
|
|
7
|
+
// Setup environment variables
|
|
8
|
+
dotenv.config();
|
|
9
|
+
|
|
10
|
+
// Need to spy on logger for documentation
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
spyOn(logger, 'info');
|
|
13
|
+
spyOn(logger, 'error');
|
|
14
|
+
spyOn(logger, 'warn');
|
|
15
|
+
spyOn(logger, 'debug');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
afterAll(() => {
|
|
19
|
+
// No global restore needed in bun:test;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Helper function to document test results
|
|
23
|
+
function documentTestResult(testName: string, result: any, error: Error | null = null) {
|
|
24
|
+
// Clean, useful test documentation for developers
|
|
25
|
+
logger.info(`✓ Testing: ${testName}`);
|
|
26
|
+
|
|
27
|
+
if (error) {
|
|
28
|
+
logger.error(`✗ Error: ${error.message}`);
|
|
29
|
+
if (error.stack) {
|
|
30
|
+
logger.error(`Stack: ${error.stack}`);
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (result) {
|
|
36
|
+
if (typeof result === 'string') {
|
|
37
|
+
if (result.trim() && result.length > 0) {
|
|
38
|
+
const preview = result.length > 60 ? `${result.substring(0, 60)}...` : result;
|
|
39
|
+
logger.info(` → ${preview}`);
|
|
40
|
+
}
|
|
41
|
+
} else if (typeof result === 'object') {
|
|
42
|
+
try {
|
|
43
|
+
// Show key information in a clean format
|
|
44
|
+
const keys = Object.keys(result);
|
|
45
|
+
if (keys.length > 0) {
|
|
46
|
+
const preview = keys.slice(0, 3).join(', ');
|
|
47
|
+
const more = keys.length > 3 ? ` +${keys.length - 3} more` : '';
|
|
48
|
+
logger.info(` → {${preview}${more}}`);
|
|
49
|
+
}
|
|
50
|
+
} catch (e) {
|
|
51
|
+
logger.info(` → [Complex object]`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Create a real runtime for testing
|
|
58
|
+
function createRealRuntime() {
|
|
59
|
+
const services = new Map();
|
|
60
|
+
|
|
61
|
+
// Create a real service instance if needed
|
|
62
|
+
const createService = (serviceType: string) => {
|
|
63
|
+
if (serviceType === StarterService.serviceType) {
|
|
64
|
+
return new StarterService({
|
|
65
|
+
character: {
|
|
66
|
+
name: 'Test Character',
|
|
67
|
+
system: 'You are a helpful assistant for testing.',
|
|
68
|
+
},
|
|
69
|
+
} as any);
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
character: {
|
|
76
|
+
name: 'Test Character',
|
|
77
|
+
system: 'You are a helpful assistant for testing.',
|
|
78
|
+
plugins: [],
|
|
79
|
+
settings: {},
|
|
80
|
+
},
|
|
81
|
+
getSetting: (key: string) => null,
|
|
82
|
+
models: plugin.models,
|
|
83
|
+
db: {
|
|
84
|
+
get: async (key: string) => null,
|
|
85
|
+
set: async (key: string, value: any) => true,
|
|
86
|
+
delete: async (key: string) => true,
|
|
87
|
+
getKeys: async (pattern: string) => [],
|
|
88
|
+
},
|
|
89
|
+
getService: (serviceType: string) => {
|
|
90
|
+
// Get from cache or create new
|
|
91
|
+
if (!services.has(serviceType)) {
|
|
92
|
+
services.set(serviceType, createService(serviceType));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return services.get(serviceType);
|
|
96
|
+
},
|
|
97
|
+
registerService: (serviceType: string, service: any) => {
|
|
98
|
+
services.set(serviceType, service);
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
describe('Plugin Configuration', () => {
|
|
104
|
+
it('should have correct plugin metadata', () => {
|
|
105
|
+
expect(plugin.name).toBe('starter');
|
|
106
|
+
expect(plugin.description).toBe('A starter plugin for Eliza');
|
|
107
|
+
expect(plugin.config).toBeDefined();
|
|
108
|
+
|
|
109
|
+
documentTestResult('Plugin metadata check', {
|
|
110
|
+
name: plugin.name,
|
|
111
|
+
description: plugin.description,
|
|
112
|
+
hasConfig: !!plugin.config,
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should include the EXAMPLE_PLUGIN_VARIABLE in config', () => {
|
|
117
|
+
expect(plugin.config).toHaveProperty('EXAMPLE_PLUGIN_VARIABLE');
|
|
118
|
+
|
|
119
|
+
documentTestResult('Plugin config check', {
|
|
120
|
+
hasExampleVariable: plugin.config ? 'EXAMPLE_PLUGIN_VARIABLE' in plugin.config : false,
|
|
121
|
+
configKeys: Object.keys(plugin.config || {}),
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should initialize properly', async () => {
|
|
126
|
+
const originalEnv = process.env.EXAMPLE_PLUGIN_VARIABLE;
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
process.env.EXAMPLE_PLUGIN_VARIABLE = 'test-value';
|
|
130
|
+
|
|
131
|
+
// Initialize with config - using real runtime
|
|
132
|
+
const runtime = createRealRuntime();
|
|
133
|
+
|
|
134
|
+
let error: Error | null = null;
|
|
135
|
+
try {
|
|
136
|
+
await plugin.init?.({ EXAMPLE_PLUGIN_VARIABLE: 'test-value' }, runtime as any);
|
|
137
|
+
expect(true).toBe(true); // If we got here, init succeeded
|
|
138
|
+
} catch (e) {
|
|
139
|
+
error = e as Error;
|
|
140
|
+
logger.error('Plugin initialization error:', e);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
documentTestResult(
|
|
144
|
+
'Plugin initialization',
|
|
145
|
+
{
|
|
146
|
+
success: !error,
|
|
147
|
+
configValue: process.env.EXAMPLE_PLUGIN_VARIABLE,
|
|
148
|
+
},
|
|
149
|
+
error
|
|
150
|
+
);
|
|
151
|
+
} finally {
|
|
152
|
+
process.env.EXAMPLE_PLUGIN_VARIABLE = originalEnv;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should throw an error on invalid config', async () => {
|
|
157
|
+
// Test with empty string (less than min length 1)
|
|
158
|
+
if (plugin.init) {
|
|
159
|
+
const runtime = createRealRuntime();
|
|
160
|
+
let error: Error | null = null;
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
await plugin.init({ EXAMPLE_PLUGIN_VARIABLE: '' }, runtime as any);
|
|
164
|
+
// Should not reach here
|
|
165
|
+
expect(true).toBe(false);
|
|
166
|
+
} catch (e) {
|
|
167
|
+
error = e as Error;
|
|
168
|
+
// This is expected - test passes
|
|
169
|
+
expect(error).toBeTruthy();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
documentTestResult(
|
|
173
|
+
'Plugin invalid config',
|
|
174
|
+
{
|
|
175
|
+
errorThrown: !!error,
|
|
176
|
+
errorMessage: error?.message || 'No error message',
|
|
177
|
+
},
|
|
178
|
+
error
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('should have a valid config', () => {
|
|
184
|
+
expect(plugin.config).toBeDefined();
|
|
185
|
+
if (plugin.config) {
|
|
186
|
+
// Check if the config has expected EXAMPLE_PLUGIN_VARIABLE property
|
|
187
|
+
expect(Object.keys(plugin.config)).toContain('EXAMPLE_PLUGIN_VARIABLE');
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
describe('Plugin Models', () => {
|
|
193
|
+
it('should have TEXT_SMALL model defined', () => {
|
|
194
|
+
if (plugin.models) {
|
|
195
|
+
expect(plugin.models).toHaveProperty(ModelType.TEXT_SMALL);
|
|
196
|
+
expect(typeof plugin.models[ModelType.TEXT_SMALL]).toBe('function');
|
|
197
|
+
|
|
198
|
+
documentTestResult('TEXT_SMALL model check', {
|
|
199
|
+
defined: ModelType.TEXT_SMALL in plugin.models,
|
|
200
|
+
isFunction: typeof plugin.models[ModelType.TEXT_SMALL] === 'function',
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('should have TEXT_LARGE model defined', () => {
|
|
206
|
+
if (plugin.models) {
|
|
207
|
+
expect(plugin.models).toHaveProperty(ModelType.TEXT_LARGE);
|
|
208
|
+
expect(typeof plugin.models[ModelType.TEXT_LARGE]).toBe('function');
|
|
209
|
+
|
|
210
|
+
documentTestResult('TEXT_LARGE model check', {
|
|
211
|
+
defined: ModelType.TEXT_LARGE in plugin.models,
|
|
212
|
+
isFunction: typeof plugin.models[ModelType.TEXT_LARGE] === 'function',
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should return a response from TEXT_SMALL model', async () => {
|
|
218
|
+
if (plugin.models && plugin.models[ModelType.TEXT_SMALL]) {
|
|
219
|
+
const runtime = createRealRuntime();
|
|
220
|
+
|
|
221
|
+
let result = '';
|
|
222
|
+
let error: Error | null = null;
|
|
223
|
+
|
|
224
|
+
try {
|
|
225
|
+
logger.info('Using OpenAI for TEXT_SMALL model');
|
|
226
|
+
result = await plugin.models[ModelType.TEXT_SMALL](runtime as any, { prompt: 'test' });
|
|
227
|
+
|
|
228
|
+
// Check that we get a non-empty string response
|
|
229
|
+
expect(result).toBeTruthy();
|
|
230
|
+
expect(typeof result).toBe('string');
|
|
231
|
+
expect(result.length).toBeGreaterThan(10);
|
|
232
|
+
} catch (e) {
|
|
233
|
+
error = e as Error;
|
|
234
|
+
logger.error('TEXT_SMALL model test failed:', e);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
documentTestResult('TEXT_SMALL model plugin test', result, error);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
describe('StarterService', () => {
|
|
243
|
+
it('should start the service', async () => {
|
|
244
|
+
const runtime = createRealRuntime();
|
|
245
|
+
let startResult;
|
|
246
|
+
let error: Error | null = null;
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
logger.info('Using OpenAI for TEXT_SMALL model');
|
|
250
|
+
startResult = await StarterService.start(runtime as any);
|
|
251
|
+
|
|
252
|
+
expect(startResult).toBeDefined();
|
|
253
|
+
expect(startResult.constructor.name).toBe('StarterService');
|
|
254
|
+
|
|
255
|
+
// Test real functionality - check stop method is available
|
|
256
|
+
expect(typeof startResult.stop).toBe('function');
|
|
257
|
+
} catch (e) {
|
|
258
|
+
error = e as Error;
|
|
259
|
+
logger.error('Service start error:', e);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
documentTestResult(
|
|
263
|
+
'StarterService start',
|
|
264
|
+
{
|
|
265
|
+
success: !!startResult,
|
|
266
|
+
serviceType: startResult?.constructor.name,
|
|
267
|
+
},
|
|
268
|
+
error
|
|
269
|
+
);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('should throw an error on startup if the service is already registered', async () => {
|
|
273
|
+
const runtime = createRealRuntime();
|
|
274
|
+
|
|
275
|
+
// First registration should succeed
|
|
276
|
+
const result1 = await StarterService.start(runtime as any);
|
|
277
|
+
expect(result1).toBeTruthy();
|
|
278
|
+
|
|
279
|
+
let startupError: Error | null = null;
|
|
280
|
+
|
|
281
|
+
try {
|
|
282
|
+
// Second registration should fail
|
|
283
|
+
await StarterService.start(runtime as any);
|
|
284
|
+
expect(true).toBe(false); // Should not reach here
|
|
285
|
+
} catch (e) {
|
|
286
|
+
startupError = e as Error;
|
|
287
|
+
expect(e).toBeTruthy();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
documentTestResult(
|
|
291
|
+
'StarterService double start',
|
|
292
|
+
{
|
|
293
|
+
errorThrown: !!startupError,
|
|
294
|
+
errorMessage: startupError?.message || 'No error message',
|
|
295
|
+
},
|
|
296
|
+
startupError
|
|
297
|
+
);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('should stop the service', async () => {
|
|
301
|
+
const runtime = createRealRuntime();
|
|
302
|
+
let error: Error | null = null;
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
// Register a real service first
|
|
306
|
+
const service = new StarterService(runtime as any);
|
|
307
|
+
runtime.registerService(StarterService.serviceType, service);
|
|
308
|
+
|
|
309
|
+
// Spy on the real service's stop method
|
|
310
|
+
const stopSpy = spyOn(service, 'stop');
|
|
311
|
+
|
|
312
|
+
// Call the static stop method
|
|
313
|
+
await StarterService.stop(runtime as any);
|
|
314
|
+
|
|
315
|
+
// Verify the service's stop method was called
|
|
316
|
+
expect(stopSpy).toHaveBeenCalled();
|
|
317
|
+
} catch (e) {
|
|
318
|
+
error = e as Error;
|
|
319
|
+
logger.error('Service stop error:', e);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
documentTestResult(
|
|
323
|
+
'StarterService stop',
|
|
324
|
+
{
|
|
325
|
+
success: !error,
|
|
326
|
+
},
|
|
327
|
+
error
|
|
328
|
+
);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it('should throw an error when stopping a non-existent service', async () => {
|
|
332
|
+
const runtime = createRealRuntime();
|
|
333
|
+
// Don't register a service, so getService will return null
|
|
334
|
+
|
|
335
|
+
let error: Error | null = null;
|
|
336
|
+
|
|
337
|
+
try {
|
|
338
|
+
// We'll patch the getService function to ensure it returns null
|
|
339
|
+
const originalGetService = runtime.getService;
|
|
340
|
+
runtime.getService = () => null;
|
|
341
|
+
|
|
342
|
+
await StarterService.stop(runtime as any);
|
|
343
|
+
// Should not reach here
|
|
344
|
+
expect(true).toBe(false);
|
|
345
|
+
} catch (e) {
|
|
346
|
+
error = e as Error;
|
|
347
|
+
// This is expected - verify it's the right error
|
|
348
|
+
expect(error).toBeTruthy();
|
|
349
|
+
if (error instanceof Error) {
|
|
350
|
+
expect(error.message).toContain('Starter service not found');
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
documentTestResult(
|
|
355
|
+
'StarterService non-existent stop',
|
|
356
|
+
{
|
|
357
|
+
errorThrown: !!error,
|
|
358
|
+
errorMessage: error?.message || 'No error message',
|
|
359
|
+
},
|
|
360
|
+
error
|
|
361
|
+
);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it('should stop a registered service', async () => {
|
|
365
|
+
const runtime = createRealRuntime();
|
|
366
|
+
|
|
367
|
+
// First start the service
|
|
368
|
+
const startResult = await StarterService.start(runtime as any);
|
|
369
|
+
expect(startResult).toBeTruthy();
|
|
370
|
+
|
|
371
|
+
let stopError: Error | unknown = null;
|
|
372
|
+
let stopSuccess = false;
|
|
373
|
+
|
|
374
|
+
try {
|
|
375
|
+
// Then stop it
|
|
376
|
+
await StarterService.stop(runtime as any);
|
|
377
|
+
stopSuccess = true;
|
|
378
|
+
} catch (e) {
|
|
379
|
+
stopError = e;
|
|
380
|
+
expect(true).toBe(false); // Should not reach here
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
documentTestResult(
|
|
384
|
+
'StarterService stop',
|
|
385
|
+
{
|
|
386
|
+
success: stopSuccess,
|
|
387
|
+
errorThrown: !!stopError,
|
|
388
|
+
errorMessage: stopError instanceof Error ? stopError.message : String(stopError),
|
|
389
|
+
},
|
|
390
|
+
stopError instanceof Error ? stopError : null
|
|
391
|
+
);
|
|
392
|
+
});
|
|
393
|
+
});
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { describe, expect, it, spyOn, beforeAll, afterAll } from 'bun:test';
|
|
2
|
+
import plugin from '../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
|
+
|
|
8
|
+
// Setup environment variables
|
|
9
|
+
dotenv.config();
|
|
10
|
+
|
|
11
|
+
// Set up logging to capture issues
|
|
12
|
+
beforeAll(() => {
|
|
13
|
+
spyOn(logger, 'info');
|
|
14
|
+
spyOn(logger, 'error');
|
|
15
|
+
spyOn(logger, 'warn');
|
|
16
|
+
spyOn(logger, 'debug');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
afterAll(() => {
|
|
20
|
+
// No global restore needed in bun:test;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Helper function to document test results
|
|
24
|
+
function documentTestResult(testName: string, result: any, error: Error | null = null) {
|
|
25
|
+
// Clean, useful test documentation for developers
|
|
26
|
+
logger.info(`✓ Testing: ${testName}`);
|
|
27
|
+
|
|
28
|
+
if (error) {
|
|
29
|
+
logger.error(`✗ Error: ${error.message}`);
|
|
30
|
+
if (error.stack) {
|
|
31
|
+
logger.error(`Stack: ${error.stack}`);
|
|
32
|
+
}
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (result) {
|
|
37
|
+
if (typeof result === 'string') {
|
|
38
|
+
if (result.trim() && result.length > 0) {
|
|
39
|
+
const preview = result.length > 60 ? `${result.substring(0, 60)}...` : result;
|
|
40
|
+
logger.info(` → ${preview}`);
|
|
41
|
+
}
|
|
42
|
+
} else if (typeof result === 'object') {
|
|
43
|
+
try {
|
|
44
|
+
// Show key information in a clean format
|
|
45
|
+
const keys = Object.keys(result);
|
|
46
|
+
if (keys.length > 0) {
|
|
47
|
+
const preview = keys.slice(0, 3).join(', ');
|
|
48
|
+
const more = keys.length > 3 ? ` +${keys.length - 3} more` : '';
|
|
49
|
+
logger.info(` → {${preview}${more}}`);
|
|
50
|
+
}
|
|
51
|
+
} catch (e) {
|
|
52
|
+
logger.info(` → [Complex object]`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Create a realistic runtime for testing
|
|
59
|
+
function createRealRuntime(): IAgentRuntime {
|
|
60
|
+
return {
|
|
61
|
+
character: {
|
|
62
|
+
name: 'Test Character',
|
|
63
|
+
system: 'You are a helpful assistant for testing.',
|
|
64
|
+
plugins: [],
|
|
65
|
+
settings: {},
|
|
66
|
+
},
|
|
67
|
+
getSetting: (key: string) => null,
|
|
68
|
+
models: plugin.models,
|
|
69
|
+
db: {
|
|
70
|
+
get: async (key: string) => {
|
|
71
|
+
return null;
|
|
72
|
+
},
|
|
73
|
+
set: async (key: string, value: any) => {
|
|
74
|
+
return true;
|
|
75
|
+
},
|
|
76
|
+
delete: async (key: string) => {
|
|
77
|
+
return true;
|
|
78
|
+
},
|
|
79
|
+
getKeys: async (pattern: string) => {
|
|
80
|
+
return [];
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
memory: {
|
|
84
|
+
add: async (memory: any) => {
|
|
85
|
+
// Memory operations for testing
|
|
86
|
+
},
|
|
87
|
+
get: async (id: string) => {
|
|
88
|
+
return null;
|
|
89
|
+
},
|
|
90
|
+
getByEntityId: async (entityId: string) => {
|
|
91
|
+
return [];
|
|
92
|
+
},
|
|
93
|
+
getLatest: async (entityId: string) => {
|
|
94
|
+
return null;
|
|
95
|
+
},
|
|
96
|
+
getRecentMessages: async (options: any) => {
|
|
97
|
+
return [];
|
|
98
|
+
},
|
|
99
|
+
search: async (query: string) => {
|
|
100
|
+
return [];
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
getService: (serviceType: string) => {
|
|
104
|
+
return null;
|
|
105
|
+
},
|
|
106
|
+
} as unknown as IAgentRuntime;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Create realistic memory object
|
|
110
|
+
function createRealMemory(): Memory {
|
|
111
|
+
const entityId = uuidv4();
|
|
112
|
+
const roomId = uuidv4();
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
id: uuidv4(),
|
|
116
|
+
entityId,
|
|
117
|
+
roomId,
|
|
118
|
+
timestamp: Date.now(),
|
|
119
|
+
content: {
|
|
120
|
+
text: 'What can you provide?',
|
|
121
|
+
source: 'test',
|
|
122
|
+
actions: [],
|
|
123
|
+
},
|
|
124
|
+
metadata: {
|
|
125
|
+
type: 'custom',
|
|
126
|
+
sessionId: uuidv4(),
|
|
127
|
+
conversationId: uuidv4(),
|
|
128
|
+
},
|
|
129
|
+
} as Memory;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
describe('Provider Tests', () => {
|
|
133
|
+
// Find the HELLO_WORLD_PROVIDER from the providers array
|
|
134
|
+
const helloWorldProvider = plugin.providers?.find(
|
|
135
|
+
(provider) => provider.name === 'HELLO_WORLD_PROVIDER'
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
describe('HELLO_WORLD_PROVIDER', () => {
|
|
139
|
+
it('should exist in the plugin', () => {
|
|
140
|
+
expect(plugin.providers).toBeDefined();
|
|
141
|
+
expect(Array.isArray(plugin.providers)).toBe(true);
|
|
142
|
+
|
|
143
|
+
if (plugin.providers) {
|
|
144
|
+
expect(plugin.providers.length).toBeGreaterThan(0);
|
|
145
|
+
const result = plugin.providers.find((p) => p.name === 'HELLO_WORLD_PROVIDER');
|
|
146
|
+
expect(result).toBeDefined();
|
|
147
|
+
documentTestResult('Provider exists check', {
|
|
148
|
+
found: !!result,
|
|
149
|
+
providers: plugin.providers.map((p) => p.name),
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('should have the correct structure', () => {
|
|
155
|
+
if (helloWorldProvider) {
|
|
156
|
+
expect(helloWorldProvider).toHaveProperty('name', 'HELLO_WORLD_PROVIDER');
|
|
157
|
+
expect(helloWorldProvider).toHaveProperty('description');
|
|
158
|
+
expect(helloWorldProvider).toHaveProperty('get');
|
|
159
|
+
expect(typeof helloWorldProvider.get).toBe('function');
|
|
160
|
+
|
|
161
|
+
documentTestResult('Provider structure check', {
|
|
162
|
+
name: helloWorldProvider.name,
|
|
163
|
+
description: helloWorldProvider.description,
|
|
164
|
+
hasGetMethod: typeof helloWorldProvider.get === 'function',
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('should have a description explaining its purpose', () => {
|
|
170
|
+
if (helloWorldProvider && helloWorldProvider.description) {
|
|
171
|
+
expect(typeof helloWorldProvider.description).toBe('string');
|
|
172
|
+
expect(helloWorldProvider.description.length).toBeGreaterThan(0);
|
|
173
|
+
|
|
174
|
+
documentTestResult('Provider description check', {
|
|
175
|
+
description: helloWorldProvider.description,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should return provider data from the get method', async () => {
|
|
181
|
+
if (helloWorldProvider) {
|
|
182
|
+
const runtime = createRealRuntime();
|
|
183
|
+
const message = createRealMemory();
|
|
184
|
+
const state = {
|
|
185
|
+
values: { example: 'test value' },
|
|
186
|
+
data: { additionalContext: 'some context' },
|
|
187
|
+
text: 'Current state context',
|
|
188
|
+
} as State;
|
|
189
|
+
|
|
190
|
+
let result: any = null;
|
|
191
|
+
let error: Error | null = null;
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
logger.info('Calling provider.get with real implementation');
|
|
195
|
+
result = await helloWorldProvider.get(runtime, message, state);
|
|
196
|
+
|
|
197
|
+
expect(result).toBeDefined();
|
|
198
|
+
expect(result).toHaveProperty('text');
|
|
199
|
+
expect(result).toHaveProperty('values');
|
|
200
|
+
expect(result).toHaveProperty('data');
|
|
201
|
+
|
|
202
|
+
// Look for potential issues in the result
|
|
203
|
+
if (result && (!result.text || result.text.length === 0)) {
|
|
204
|
+
logger.warn('Provider returned empty text');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (result && Object.keys(result.values).length === 0) {
|
|
208
|
+
logger.warn('Provider returned empty values object');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (result && Object.keys(result.data).length === 0) {
|
|
212
|
+
logger.warn('Provider returned empty data object');
|
|
213
|
+
}
|
|
214
|
+
} catch (e) {
|
|
215
|
+
error = e as Error;
|
|
216
|
+
logger.error('Error in provider.get:', e);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
documentTestResult('Provider get method', result, error);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('should handle error conditions gracefully', async () => {
|
|
224
|
+
if (helloWorldProvider) {
|
|
225
|
+
const runtime = createRealRuntime();
|
|
226
|
+
// Create an invalid memory object to simulate an error scenario
|
|
227
|
+
const invalidMemory = {
|
|
228
|
+
// Missing properties that would be required
|
|
229
|
+
id: uuidv4(),
|
|
230
|
+
} as unknown as Memory;
|
|
231
|
+
|
|
232
|
+
const state = {
|
|
233
|
+
values: {},
|
|
234
|
+
data: {},
|
|
235
|
+
text: '',
|
|
236
|
+
} as State;
|
|
237
|
+
|
|
238
|
+
let result: any = null;
|
|
239
|
+
let error: Error | null = null;
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
logger.info('Calling provider.get with invalid memory object');
|
|
243
|
+
result = await helloWorldProvider.get(runtime, invalidMemory, state);
|
|
244
|
+
|
|
245
|
+
// Even with invalid input, it should not throw errors
|
|
246
|
+
expect(result).toBeDefined();
|
|
247
|
+
|
|
248
|
+
// Log what actual implementation does with invalid input
|
|
249
|
+
logger.info('Provider handled invalid input without throwing');
|
|
250
|
+
} catch (e) {
|
|
251
|
+
error = e as Error;
|
|
252
|
+
logger.error('Provider threw an error with invalid input:', e);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
documentTestResult('Provider error handling', result, error);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
describe('Provider Registration', () => {
|
|
261
|
+
it('should include providers in the plugin definition', () => {
|
|
262
|
+
expect(plugin).toHaveProperty('providers');
|
|
263
|
+
expect(Array.isArray(plugin.providers)).toBe(true);
|
|
264
|
+
|
|
265
|
+
documentTestResult('Plugin providers check', {
|
|
266
|
+
hasProviders: !!plugin.providers,
|
|
267
|
+
providersCount: plugin.providers?.length || 0,
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('should correctly initialize providers array', () => {
|
|
272
|
+
// Providers should be an array with at least one provider
|
|
273
|
+
if (plugin.providers) {
|
|
274
|
+
expect(plugin.providers.length).toBeGreaterThan(0);
|
|
275
|
+
|
|
276
|
+
let allValid = true;
|
|
277
|
+
const invalidProviders: string[] = [];
|
|
278
|
+
|
|
279
|
+
// Each provider should have the required structure
|
|
280
|
+
plugin.providers.forEach((provider: Provider) => {
|
|
281
|
+
const isValid =
|
|
282
|
+
provider.name !== undefined &&
|
|
283
|
+
provider.description !== undefined &&
|
|
284
|
+
typeof provider.get === 'function';
|
|
285
|
+
|
|
286
|
+
if (!isValid) {
|
|
287
|
+
allValid = false;
|
|
288
|
+
invalidProviders.push(provider.name || 'unnamed');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
expect(provider).toHaveProperty('name');
|
|
292
|
+
expect(provider).toHaveProperty('description');
|
|
293
|
+
expect(provider).toHaveProperty('get');
|
|
294
|
+
expect(typeof provider.get).toBe('function');
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
documentTestResult('Provider initialization check', {
|
|
298
|
+
providersCount: plugin.providers.length,
|
|
299
|
+
allValid,
|
|
300
|
+
invalidProviders,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('should have unique provider names', () => {
|
|
306
|
+
if (plugin.providers) {
|
|
307
|
+
const providerNames = plugin.providers.map((provider) => provider.name);
|
|
308
|
+
const uniqueNames = new Set(providerNames);
|
|
309
|
+
|
|
310
|
+
const duplicates = providerNames.filter(
|
|
311
|
+
(name, index) => providerNames.indexOf(name) !== index
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
// There should be no duplicate provider names
|
|
315
|
+
expect(providerNames.length).toBe(uniqueNames.size);
|
|
316
|
+
|
|
317
|
+
documentTestResult('Provider uniqueness check', {
|
|
318
|
+
totalProviders: providerNames.length,
|
|
319
|
+
uniqueProviders: uniqueNames.size,
|
|
320
|
+
duplicates,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
});
|