openclaw-overlay-plugin 0.7.34 → 0.7.35
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 -1
- package/dist/index.js +13 -2
- package/dist/src/scripts/config.d.ts +1 -1
- package/dist/src/scripts/config.js +1 -1
- package/index.ts +15 -2
- package/openclaw.plugin.json +2 -1
- package/package.json +1 -1
- package/src/scripts/config.ts +1 -1
- package/dist/cli-main.d.ts +0 -7
- package/dist/cli-main.js +0 -192
- package/dist/cli.d.ts +0 -8
- package/dist/cli.js +0 -14
- package/dist/core/config.d.ts +0 -11
- package/dist/core/config.js +0 -13
- package/dist/core/index.d.ts +0 -25
- package/dist/core/index.js +0 -26
- package/dist/core/payment.d.ts +0 -16
- package/dist/core/payment.js +0 -94
- package/dist/core/types.d.ts +0 -94
- package/dist/core/types.js +0 -4
- package/dist/core/verify.d.ts +0 -28
- package/dist/core/verify.js +0 -104
- package/dist/core/wallet.d.ts +0 -99
- package/dist/core/wallet.js +0 -219
- package/dist/scripts/baemail/commands.d.ts +0 -64
- package/dist/scripts/baemail/commands.js +0 -259
- package/dist/scripts/baemail/handler.d.ts +0 -36
- package/dist/scripts/baemail/handler.js +0 -284
- package/dist/scripts/baemail/index.d.ts +0 -5
- package/dist/scripts/baemail/index.js +0 -5
- package/dist/scripts/config.d.ts +0 -48
- package/dist/scripts/config.js +0 -68
- package/dist/scripts/index.d.ts +0 -7
- package/dist/scripts/index.js +0 -7
- package/dist/scripts/messaging/connect.d.ts +0 -8
- package/dist/scripts/messaging/connect.js +0 -114
- package/dist/scripts/messaging/handlers.d.ts +0 -21
- package/dist/scripts/messaging/handlers.js +0 -334
- package/dist/scripts/messaging/inbox.d.ts +0 -11
- package/dist/scripts/messaging/inbox.js +0 -51
- package/dist/scripts/messaging/index.d.ts +0 -8
- package/dist/scripts/messaging/index.js +0 -8
- package/dist/scripts/messaging/poll.d.ts +0 -7
- package/dist/scripts/messaging/poll.js +0 -52
- package/dist/scripts/messaging/send.d.ts +0 -7
- package/dist/scripts/messaging/send.js +0 -43
- package/dist/scripts/output.d.ts +0 -12
- package/dist/scripts/output.js +0 -19
- package/dist/scripts/overlay/discover.d.ts +0 -7
- package/dist/scripts/overlay/discover.js +0 -72
- package/dist/scripts/overlay/index.d.ts +0 -7
- package/dist/scripts/overlay/index.js +0 -7
- package/dist/scripts/overlay/registration.d.ts +0 -19
- package/dist/scripts/overlay/registration.js +0 -176
- package/dist/scripts/overlay/services.d.ts +0 -29
- package/dist/scripts/overlay/services.js +0 -167
- package/dist/scripts/overlay/transaction.d.ts +0 -42
- package/dist/scripts/overlay/transaction.js +0 -103
- package/dist/scripts/payment/build.d.ts +0 -24
- package/dist/scripts/payment/build.js +0 -54
- package/dist/scripts/payment/commands.d.ts +0 -15
- package/dist/scripts/payment/commands.js +0 -73
- package/dist/scripts/payment/index.d.ts +0 -6
- package/dist/scripts/payment/index.js +0 -6
- package/dist/scripts/payment/types.d.ts +0 -56
- package/dist/scripts/payment/types.js +0 -4
- package/dist/scripts/services/index.d.ts +0 -6
- package/dist/scripts/services/index.js +0 -6
- package/dist/scripts/services/queue.d.ts +0 -11
- package/dist/scripts/services/queue.js +0 -28
- package/dist/scripts/services/request.d.ts +0 -7
- package/dist/scripts/services/request.js +0 -82
- package/dist/scripts/services/respond.d.ts +0 -11
- package/dist/scripts/services/respond.js +0 -132
- package/dist/scripts/types.d.ts +0 -107
- package/dist/scripts/types.js +0 -4
- package/dist/scripts/utils/index.d.ts +0 -6
- package/dist/scripts/utils/index.js +0 -6
- package/dist/scripts/utils/merkle.d.ts +0 -12
- package/dist/scripts/utils/merkle.js +0 -47
- package/dist/scripts/utils/storage.d.ts +0 -66
- package/dist/scripts/utils/storage.js +0 -211
- package/dist/scripts/utils/woc.d.ts +0 -26
- package/dist/scripts/utils/woc.js +0 -91
- package/dist/scripts/wallet/balance.d.ts +0 -22
- package/dist/scripts/wallet/balance.js +0 -240
- package/dist/scripts/wallet/identity.d.ts +0 -70
- package/dist/scripts/wallet/identity.js +0 -151
- package/dist/scripts/wallet/index.d.ts +0 -6
- package/dist/scripts/wallet/index.js +0 -6
- package/dist/scripts/wallet/setup.d.ts +0 -15
- package/dist/scripts/wallet/setup.js +0 -105
- package/dist/scripts/x-verification/commands.d.ts +0 -27
- package/dist/scripts/x-verification/commands.js +0 -222
- package/dist/scripts/x-verification/index.d.ts +0 -4
- package/dist/scripts/x-verification/index.js +0 -4
- package/dist/services/built-in/api-proxy/index.d.ts +0 -6
- package/dist/services/built-in/api-proxy/index.js +0 -23
- package/dist/services/built-in/code-develop/index.d.ts +0 -6
- package/dist/services/built-in/code-develop/index.js +0 -23
- package/dist/services/built-in/code-review/index.d.ts +0 -10
- package/dist/services/built-in/code-review/index.js +0 -51
- package/dist/services/built-in/image-analysis/index.d.ts +0 -6
- package/dist/services/built-in/image-analysis/index.js +0 -33
- package/dist/services/built-in/memory-store/index.d.ts +0 -6
- package/dist/services/built-in/memory-store/index.js +0 -22
- package/dist/services/built-in/roulette/index.d.ts +0 -6
- package/dist/services/built-in/roulette/index.js +0 -27
- package/dist/services/built-in/summarize/index.d.ts +0 -6
- package/dist/services/built-in/summarize/index.js +0 -21
- package/dist/services/built-in/tell-joke/handler.d.ts +0 -7
- package/dist/services/built-in/tell-joke/handler.js +0 -122
- package/dist/services/built-in/tell-joke/index.d.ts +0 -9
- package/dist/services/built-in/tell-joke/index.js +0 -31
- package/dist/services/built-in/translate/index.d.ts +0 -6
- package/dist/services/built-in/translate/index.js +0 -21
- package/dist/services/built-in/web-research/index.d.ts +0 -9
- package/dist/services/built-in/web-research/index.js +0 -51
- package/dist/services/index.d.ts +0 -13
- package/dist/services/index.js +0 -14
- package/dist/services/loader.d.ts +0 -77
- package/dist/services/loader.js +0 -292
- package/dist/services/manager.d.ts +0 -86
- package/dist/services/manager.js +0 -255
- package/dist/services/registry.d.ts +0 -98
- package/dist/services/registry.js +0 -204
- package/dist/services/types.d.ts +0 -230
- package/dist/services/types.js +0 -30
- package/dist/test/cli.test.d.ts +0 -7
- package/dist/test/cli.test.js +0 -329
- package/dist/test/comprehensive-overlay.test.d.ts +0 -13
- package/dist/test/comprehensive-overlay.test.js +0 -593
- package/dist/test/key-derivation.test.d.ts +0 -12
- package/dist/test/key-derivation.test.js +0 -86
- package/dist/test/overlay-submit.test.d.ts +0 -10
- package/dist/test/overlay-submit.test.js +0 -460
- package/dist/test/request-response-flow.test.d.ts +0 -5
- package/dist/test/request-response-flow.test.js +0 -209
- package/dist/test/service-system.test.d.ts +0 -5
- package/dist/test/service-system.test.js +0 -190
- package/dist/test/utils/server-logic.d.ts +0 -98
- package/dist/test/utils/server-logic.js +0 -286
- package/dist/test/wallet.test.d.ts +0 -7
- package/dist/test/wallet.test.js +0 -146
package/dist/services/manager.js
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Service manager implementation.
|
|
3
|
-
*
|
|
4
|
-
* This orchestrates the service system, providing a high-level interface
|
|
5
|
-
* for service execution while keeping payment and relay logic separate.
|
|
6
|
-
*/
|
|
7
|
-
import { serviceRegistry } from './registry.js';
|
|
8
|
-
import { serviceLoader } from './loader.js';
|
|
9
|
-
/**
|
|
10
|
-
* Default service manager implementation.
|
|
11
|
-
*/
|
|
12
|
-
export class DefaultServiceManager {
|
|
13
|
-
registry;
|
|
14
|
-
loader;
|
|
15
|
-
initialized = false;
|
|
16
|
-
constructor() {
|
|
17
|
-
this.registry = serviceRegistry;
|
|
18
|
-
this.loader = serviceLoader;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Initialize the service system.
|
|
22
|
-
*/
|
|
23
|
-
async initialize() {
|
|
24
|
-
if (this.initialized) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
// Load all services
|
|
28
|
-
const services = await this.loader.loadAllServices();
|
|
29
|
-
// Register all services
|
|
30
|
-
for (const service of services) {
|
|
31
|
-
try {
|
|
32
|
-
this.registry.register(service);
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
console.warn(`Failed to register service '${service.id}':`, error);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
this.initialized = true;
|
|
39
|
-
console.log(`Service manager initialized with ${this.registry.count()} services`);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Execute a service request.
|
|
43
|
-
*/
|
|
44
|
-
async execute(serviceId, input, context) {
|
|
45
|
-
if (!this.initialized) {
|
|
46
|
-
throw new Error('Service manager not initialized');
|
|
47
|
-
}
|
|
48
|
-
const service = this.registry.get(serviceId);
|
|
49
|
-
if (!service) {
|
|
50
|
-
return {
|
|
51
|
-
success: false,
|
|
52
|
-
error: `Service '${serviceId}' not found`
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
// Validate input if service has a handler
|
|
56
|
-
if (service.handler) {
|
|
57
|
-
const validation = service.handler.validate(input);
|
|
58
|
-
if (!validation.valid) {
|
|
59
|
-
return {
|
|
60
|
-
success: false,
|
|
61
|
-
error: `Input validation failed: ${validation.error}`
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
// Use sanitized input if provided
|
|
65
|
-
input = validation.sanitized || input;
|
|
66
|
-
}
|
|
67
|
-
// Execute the service
|
|
68
|
-
try {
|
|
69
|
-
if (service.handler) {
|
|
70
|
-
// Use custom handler
|
|
71
|
-
return await service.handler.process(input, context);
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
// Service uses agent mode - return success with input for agent processing
|
|
75
|
-
return {
|
|
76
|
-
success: true,
|
|
77
|
-
data: {
|
|
78
|
-
serviceId,
|
|
79
|
-
input,
|
|
80
|
-
mode: 'agent',
|
|
81
|
-
promptFile: service.promptFile
|
|
82
|
-
},
|
|
83
|
-
metadata: {
|
|
84
|
-
version: '1.0',
|
|
85
|
-
executionMode: 'agent'
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
return {
|
|
92
|
-
success: false,
|
|
93
|
-
error: error instanceof Error ? error.message : String(error),
|
|
94
|
-
metadata: {
|
|
95
|
-
serviceId,
|
|
96
|
-
errorType: 'execution_error'
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Validate service input.
|
|
103
|
-
*/
|
|
104
|
-
validate(serviceId, input) {
|
|
105
|
-
const service = this.registry.get(serviceId);
|
|
106
|
-
if (!service) {
|
|
107
|
-
return {
|
|
108
|
-
valid: false,
|
|
109
|
-
error: `Service '${serviceId}' not found`
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
// Use service handler validation if available
|
|
113
|
-
if (service.handler) {
|
|
114
|
-
return service.handler.validate(input);
|
|
115
|
-
}
|
|
116
|
-
// Default validation for agent-mode services
|
|
117
|
-
if (service.inputSchema) {
|
|
118
|
-
return this.validateAgainstSchema(input, service.inputSchema);
|
|
119
|
-
}
|
|
120
|
-
// No validation required
|
|
121
|
-
return { valid: true };
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Reload all services.
|
|
125
|
-
*/
|
|
126
|
-
async reload() {
|
|
127
|
-
// Clear existing services
|
|
128
|
-
this.registry.clear();
|
|
129
|
-
this.initialized = false;
|
|
130
|
-
// Reinitialize
|
|
131
|
-
await this.initialize();
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Get service for agent-mode processing.
|
|
135
|
-
*/
|
|
136
|
-
getServiceForAgentMode(serviceId) {
|
|
137
|
-
const service = this.registry.get(serviceId);
|
|
138
|
-
if (!service) {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
return {
|
|
142
|
-
service,
|
|
143
|
-
promptFile: service.promptFile
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Check if service is available.
|
|
148
|
-
*/
|
|
149
|
-
isServiceAvailable(serviceId) {
|
|
150
|
-
return this.registry.has(serviceId);
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Get service execution mode.
|
|
154
|
-
*/
|
|
155
|
-
getServiceMode(serviceId) {
|
|
156
|
-
const service = this.registry.get(serviceId);
|
|
157
|
-
if (!service) {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
return service.handler ? 'handler' : 'agent';
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Get all available services for discovery.
|
|
164
|
-
*/
|
|
165
|
-
getAvailableServices() {
|
|
166
|
-
return this.registry.list().map(service => ({
|
|
167
|
-
id: service.id,
|
|
168
|
-
name: service.name,
|
|
169
|
-
description: service.description,
|
|
170
|
-
defaultPrice: service.defaultPrice,
|
|
171
|
-
category: service.category,
|
|
172
|
-
mode: service.handler ? 'handler' : 'agent'
|
|
173
|
-
}));
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Validate input against JSON schema.
|
|
177
|
-
*/
|
|
178
|
-
validateAgainstSchema(input, schema) {
|
|
179
|
-
// Simple schema validation - in production, you might use a library like ajv
|
|
180
|
-
try {
|
|
181
|
-
const schemaObj = schema;
|
|
182
|
-
if (schemaObj.type === 'object') {
|
|
183
|
-
if (!input || typeof input !== 'object') {
|
|
184
|
-
return { valid: false, error: 'Input must be an object' };
|
|
185
|
-
}
|
|
186
|
-
// Check required properties
|
|
187
|
-
if (schemaObj.required && Array.isArray(schemaObj.required)) {
|
|
188
|
-
for (const requiredProp of schemaObj.required) {
|
|
189
|
-
if (!(requiredProp in input)) {
|
|
190
|
-
return { valid: false, error: `Missing required property: ${requiredProp}` };
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
// Basic type checking for properties
|
|
195
|
-
if (schemaObj.properties) {
|
|
196
|
-
for (const [propName, propSchema] of Object.entries(schemaObj.properties)) {
|
|
197
|
-
if (propName in input) {
|
|
198
|
-
const propType = propSchema.type;
|
|
199
|
-
const actualType = typeof input[propName];
|
|
200
|
-
if (propType && propType !== actualType) {
|
|
201
|
-
return { valid: false, error: `Property '${propName}' must be of type ${propType}` };
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return { valid: true, sanitized: input };
|
|
208
|
-
}
|
|
209
|
-
catch (error) {
|
|
210
|
-
return { valid: false, error: `Schema validation error: ${error}` };
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Get service statistics.
|
|
215
|
-
*/
|
|
216
|
-
getStatistics() {
|
|
217
|
-
const services = this.registry.list();
|
|
218
|
-
const stats = {
|
|
219
|
-
totalServices: services.length,
|
|
220
|
-
handlerServices: 0,
|
|
221
|
-
agentServices: 0,
|
|
222
|
-
servicesByCategory: {}
|
|
223
|
-
};
|
|
224
|
-
for (const service of services) {
|
|
225
|
-
// Count by execution mode
|
|
226
|
-
if (service.handler) {
|
|
227
|
-
stats.handlerServices++;
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
stats.agentServices++;
|
|
231
|
-
}
|
|
232
|
-
// Count by category
|
|
233
|
-
const category = service.category || 'uncategorized';
|
|
234
|
-
stats.servicesByCategory[category] = (stats.servicesByCategory[category] || 0) + 1;
|
|
235
|
-
}
|
|
236
|
-
return stats;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Global service manager instance.
|
|
241
|
-
*/
|
|
242
|
-
export const serviceManager = new DefaultServiceManager();
|
|
243
|
-
/**
|
|
244
|
-
* Initialize the service system.
|
|
245
|
-
* This should be called once during application startup.
|
|
246
|
-
*/
|
|
247
|
-
export async function initializeServiceSystem() {
|
|
248
|
-
await serviceManager.initialize();
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Get service manager instance.
|
|
252
|
-
*/
|
|
253
|
-
export function getServiceManager() {
|
|
254
|
-
return serviceManager;
|
|
255
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Service registry implementation.
|
|
3
|
-
*
|
|
4
|
-
* This provides a centralized registry for all services, allowing
|
|
5
|
-
* dynamic registration and discovery without modifying core code.
|
|
6
|
-
*/
|
|
7
|
-
import { ServiceDefinition, ServiceRegistry } from './types.js';
|
|
8
|
-
/**
|
|
9
|
-
* Default service registry implementation.
|
|
10
|
-
*/
|
|
11
|
-
export declare class DefaultServiceRegistry implements ServiceRegistry {
|
|
12
|
-
private services;
|
|
13
|
-
/**
|
|
14
|
-
* Register a new service definition.
|
|
15
|
-
*/
|
|
16
|
-
register(service: ServiceDefinition): void;
|
|
17
|
-
/**
|
|
18
|
-
* Get a service definition by ID.
|
|
19
|
-
*/
|
|
20
|
-
get(serviceId: string): ServiceDefinition | undefined;
|
|
21
|
-
/**
|
|
22
|
-
* List all registered services.
|
|
23
|
-
*/
|
|
24
|
-
list(): ServiceDefinition[];
|
|
25
|
-
/**
|
|
26
|
-
* List services by category.
|
|
27
|
-
*/
|
|
28
|
-
listByCategory(category: string): ServiceDefinition[];
|
|
29
|
-
/**
|
|
30
|
-
* Check if a service is registered.
|
|
31
|
-
*/
|
|
32
|
-
has(serviceId: string): boolean;
|
|
33
|
-
/**
|
|
34
|
-
* Unregister a service.
|
|
35
|
-
*/
|
|
36
|
-
unregister(serviceId: string): void;
|
|
37
|
-
/**
|
|
38
|
-
* Clear all services (useful for testing).
|
|
39
|
-
*/
|
|
40
|
-
clear(): void;
|
|
41
|
-
/**
|
|
42
|
-
* Get service count.
|
|
43
|
-
*/
|
|
44
|
-
count(): number;
|
|
45
|
-
/**
|
|
46
|
-
* Get services by price range.
|
|
47
|
-
*/
|
|
48
|
-
getByPriceRange(minPrice: number, maxPrice: number): ServiceDefinition[];
|
|
49
|
-
/**
|
|
50
|
-
* Search services by name or description.
|
|
51
|
-
*/
|
|
52
|
-
search(query: string): ServiceDefinition[];
|
|
53
|
-
/**
|
|
54
|
-
* Validate a service definition.
|
|
55
|
-
*/
|
|
56
|
-
private validateServiceDefinition;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Global service registry instance.
|
|
60
|
-
*/
|
|
61
|
-
export declare const serviceRegistry: DefaultServiceRegistry;
|
|
62
|
-
/**
|
|
63
|
-
* Utility functions for working with the service registry.
|
|
64
|
-
*/
|
|
65
|
-
export declare const ServiceRegistryUtils: {
|
|
66
|
-
/**
|
|
67
|
-
* Register multiple services at once.
|
|
68
|
-
*/
|
|
69
|
-
registerMultiple(services: ServiceDefinition[]): void;
|
|
70
|
-
/**
|
|
71
|
-
* Get services that support a specific input type.
|
|
72
|
-
*/
|
|
73
|
-
getServicesForInput(inputType: string): ServiceDefinition[];
|
|
74
|
-
/**
|
|
75
|
-
* Validate service exists and return it.
|
|
76
|
-
*/
|
|
77
|
-
requireService(serviceId: string): ServiceDefinition;
|
|
78
|
-
/**
|
|
79
|
-
* Get all service IDs.
|
|
80
|
-
*/
|
|
81
|
-
getAllServiceIds(): string[];
|
|
82
|
-
/**
|
|
83
|
-
* Check if any services are registered.
|
|
84
|
-
*/
|
|
85
|
-
hasAnyServices(): boolean;
|
|
86
|
-
/**
|
|
87
|
-
* Get service statistics.
|
|
88
|
-
*/
|
|
89
|
-
getStatistics(): {
|
|
90
|
-
totalServices: number;
|
|
91
|
-
servicesByCategory: Record<string, number>;
|
|
92
|
-
priceRange: {
|
|
93
|
-
min: number;
|
|
94
|
-
max: number;
|
|
95
|
-
};
|
|
96
|
-
servicesWithHandlers: number;
|
|
97
|
-
};
|
|
98
|
-
};
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Service registry implementation.
|
|
3
|
-
*
|
|
4
|
-
* This provides a centralized registry for all services, allowing
|
|
5
|
-
* dynamic registration and discovery without modifying core code.
|
|
6
|
-
*/
|
|
7
|
-
import { ServiceCategory } from './types.js';
|
|
8
|
-
/**
|
|
9
|
-
* Default service registry implementation.
|
|
10
|
-
*/
|
|
11
|
-
export class DefaultServiceRegistry {
|
|
12
|
-
services = new Map();
|
|
13
|
-
/**
|
|
14
|
-
* Register a new service definition.
|
|
15
|
-
*/
|
|
16
|
-
register(service) {
|
|
17
|
-
// Validate service definition
|
|
18
|
-
this.validateServiceDefinition(service);
|
|
19
|
-
// Check for duplicates
|
|
20
|
-
if (this.services.has(service.id)) {
|
|
21
|
-
throw new Error(`Service '${service.id}' is already registered`);
|
|
22
|
-
}
|
|
23
|
-
// Register the service
|
|
24
|
-
this.services.set(service.id, { ...service });
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Get a service definition by ID.
|
|
28
|
-
*/
|
|
29
|
-
get(serviceId) {
|
|
30
|
-
return this.services.get(serviceId);
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* List all registered services.
|
|
34
|
-
*/
|
|
35
|
-
list() {
|
|
36
|
-
return Array.from(this.services.values());
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* List services by category.
|
|
40
|
-
*/
|
|
41
|
-
listByCategory(category) {
|
|
42
|
-
return this.list().filter(service => service.category === category);
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Check if a service is registered.
|
|
46
|
-
*/
|
|
47
|
-
has(serviceId) {
|
|
48
|
-
return this.services.has(serviceId);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Unregister a service.
|
|
52
|
-
*/
|
|
53
|
-
unregister(serviceId) {
|
|
54
|
-
this.services.delete(serviceId);
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Clear all services (useful for testing).
|
|
58
|
-
*/
|
|
59
|
-
clear() {
|
|
60
|
-
this.services.clear();
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Get service count.
|
|
64
|
-
*/
|
|
65
|
-
count() {
|
|
66
|
-
return this.services.size;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Get services by price range.
|
|
70
|
-
*/
|
|
71
|
-
getByPriceRange(minPrice, maxPrice) {
|
|
72
|
-
return this.list().filter(service => service.defaultPrice >= minPrice && service.defaultPrice <= maxPrice);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Search services by name or description.
|
|
76
|
-
*/
|
|
77
|
-
search(query) {
|
|
78
|
-
const lowerQuery = query.toLowerCase();
|
|
79
|
-
return this.list().filter(service => service.name.toLowerCase().includes(lowerQuery) ||
|
|
80
|
-
service.description.toLowerCase().includes(lowerQuery) ||
|
|
81
|
-
service.id.toLowerCase().includes(lowerQuery));
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Validate a service definition.
|
|
85
|
-
*/
|
|
86
|
-
validateServiceDefinition(service) {
|
|
87
|
-
if (!service.id) {
|
|
88
|
-
throw new Error('Service ID is required');
|
|
89
|
-
}
|
|
90
|
-
if (typeof service.id !== 'string' || service.id.trim().length === 0) {
|
|
91
|
-
throw new Error('Service ID must be a non-empty string');
|
|
92
|
-
}
|
|
93
|
-
// Validate ID format (kebab-case)
|
|
94
|
-
if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(service.id)) {
|
|
95
|
-
throw new Error('Service ID must be in kebab-case format (lowercase, hyphens only)');
|
|
96
|
-
}
|
|
97
|
-
if (!service.name || typeof service.name !== 'string' || service.name.trim().length === 0) {
|
|
98
|
-
throw new Error('Service name is required and must be a non-empty string');
|
|
99
|
-
}
|
|
100
|
-
if (!service.description || typeof service.description !== 'string' || service.description.trim().length === 0) {
|
|
101
|
-
throw new Error('Service description is required and must be a non-empty string');
|
|
102
|
-
}
|
|
103
|
-
if (typeof service.defaultPrice !== 'number' || service.defaultPrice < 0 || !Number.isInteger(service.defaultPrice)) {
|
|
104
|
-
throw new Error('Service defaultPrice must be a non-negative integer');
|
|
105
|
-
}
|
|
106
|
-
if (service.category && !Object.values(ServiceCategory).includes(service.category)) {
|
|
107
|
-
throw new Error(`Invalid service category: ${service.category}`);
|
|
108
|
-
}
|
|
109
|
-
// Validate input schema if provided
|
|
110
|
-
if (service.inputSchema && typeof service.inputSchema !== 'object') {
|
|
111
|
-
throw new Error('Service inputSchema must be an object');
|
|
112
|
-
}
|
|
113
|
-
// Validate handler if provided
|
|
114
|
-
if (service.handler) {
|
|
115
|
-
if (typeof service.handler.validate !== 'function') {
|
|
116
|
-
throw new Error('Service handler must have a validate function');
|
|
117
|
-
}
|
|
118
|
-
if (typeof service.handler.process !== 'function') {
|
|
119
|
-
throw new Error('Service handler must have a process function');
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Global service registry instance.
|
|
126
|
-
*/
|
|
127
|
-
export const serviceRegistry = new DefaultServiceRegistry();
|
|
128
|
-
/**
|
|
129
|
-
* Utility functions for working with the service registry.
|
|
130
|
-
*/
|
|
131
|
-
export const ServiceRegistryUtils = {
|
|
132
|
-
/**
|
|
133
|
-
* Register multiple services at once.
|
|
134
|
-
*/
|
|
135
|
-
registerMultiple(services) {
|
|
136
|
-
for (const service of services) {
|
|
137
|
-
serviceRegistry.register(service);
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
/**
|
|
141
|
-
* Get services that support a specific input type.
|
|
142
|
-
*/
|
|
143
|
-
getServicesForInput(inputType) {
|
|
144
|
-
return serviceRegistry.list().filter(service => {
|
|
145
|
-
if (!service.inputSchema)
|
|
146
|
-
return false;
|
|
147
|
-
const schema = service.inputSchema;
|
|
148
|
-
return schema.properties && schema.properties[inputType];
|
|
149
|
-
});
|
|
150
|
-
},
|
|
151
|
-
/**
|
|
152
|
-
* Validate service exists and return it.
|
|
153
|
-
*/
|
|
154
|
-
requireService(serviceId) {
|
|
155
|
-
const service = serviceRegistry.get(serviceId);
|
|
156
|
-
if (!service) {
|
|
157
|
-
throw new Error(`Service '${serviceId}' not found`);
|
|
158
|
-
}
|
|
159
|
-
return service;
|
|
160
|
-
},
|
|
161
|
-
/**
|
|
162
|
-
* Get all service IDs.
|
|
163
|
-
*/
|
|
164
|
-
getAllServiceIds() {
|
|
165
|
-
return serviceRegistry.list().map(service => service.id);
|
|
166
|
-
},
|
|
167
|
-
/**
|
|
168
|
-
* Check if any services are registered.
|
|
169
|
-
*/
|
|
170
|
-
hasAnyServices() {
|
|
171
|
-
return serviceRegistry.count() > 0;
|
|
172
|
-
},
|
|
173
|
-
/**
|
|
174
|
-
* Get service statistics.
|
|
175
|
-
*/
|
|
176
|
-
getStatistics() {
|
|
177
|
-
const services = serviceRegistry.list();
|
|
178
|
-
const servicesByCategory = {};
|
|
179
|
-
let minPrice = Infinity;
|
|
180
|
-
let maxPrice = -Infinity;
|
|
181
|
-
let servicesWithHandlers = 0;
|
|
182
|
-
for (const service of services) {
|
|
183
|
-
// Count by category
|
|
184
|
-
const category = service.category || 'uncategorized';
|
|
185
|
-
servicesByCategory[category] = (servicesByCategory[category] || 0) + 1;
|
|
186
|
-
// Track price range
|
|
187
|
-
minPrice = Math.min(minPrice, service.defaultPrice);
|
|
188
|
-
maxPrice = Math.max(maxPrice, service.defaultPrice);
|
|
189
|
-
// Count services with handlers
|
|
190
|
-
if (service.handler) {
|
|
191
|
-
servicesWithHandlers++;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return {
|
|
195
|
-
totalServices: services.length,
|
|
196
|
-
servicesByCategory,
|
|
197
|
-
priceRange: {
|
|
198
|
-
min: minPrice === Infinity ? 0 : minPrice,
|
|
199
|
-
max: maxPrice === -Infinity ? 0 : maxPrice
|
|
200
|
-
},
|
|
201
|
-
servicesWithHandlers
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
};
|