@olane/os 0.7.12-alpha.6 → 0.7.12-alpha.60
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/dist/src/o-olane-os/config/default.config.js +1 -1
- package/dist/src/o-olane-os/o-os.d.ts +1 -1
- package/dist/src/o-olane-os/o-os.d.ts.map +1 -1
- package/dist/src/o-olane-os/o-os.js +1 -2
- package/dist/src/utils/config.d.ts.map +1 -1
- package/dist/src/utils/config.js +2 -2
- package/dist/test/basic/basic-usage.spec.d.ts +0 -1
- package/dist/test/basic/basic-usage.spec.js +137 -107
- package/dist/test/basic/playground.spec.d.ts +2 -0
- package/dist/test/basic/playground.spec.d.ts.map +1 -0
- package/dist/test/basic/playground.spec.js +108 -0
- package/dist/test/capabilities/base-capability.spec.d.ts +2 -0
- package/dist/test/capabilities/base-capability.spec.d.ts.map +1 -0
- package/dist/test/capabilities/base-capability.spec.js +174 -0
- package/dist/test/capabilities/capability-errors.spec.d.ts +2 -0
- package/dist/test/capabilities/capability-errors.spec.d.ts.map +1 -0
- package/dist/test/capabilities/capability-errors.spec.js +340 -0
- package/dist/test/capabilities/capability-integration.spec.d.ts +2 -0
- package/dist/test/capabilities/capability-integration.spec.d.ts.map +1 -0
- package/dist/test/capabilities/capability-integration.spec.js +463 -0
- package/dist/test/capabilities/capability-registry.spec.d.ts +2 -0
- package/dist/test/capabilities/capability-registry.spec.d.ts.map +1 -0
- package/dist/test/capabilities/capability-registry.spec.js +261 -0
- package/dist/test/capabilities/configure-capability.spec.d.ts +2 -0
- package/dist/test/capabilities/configure-capability.spec.d.ts.map +1 -0
- package/dist/test/capabilities/configure-capability.spec.js +366 -0
- package/dist/test/capabilities/evaluate-capability.spec.d.ts +2 -0
- package/dist/test/capabilities/evaluate-capability.spec.d.ts.map +1 -0
- package/dist/test/capabilities/evaluate-capability.spec.js +323 -0
- package/dist/test/capabilities/intelligence-capability.spec.d.ts +2 -0
- package/dist/test/capabilities/intelligence-capability.spec.d.ts.map +1 -0
- package/dist/test/capabilities/intelligence-capability.spec.js +171 -0
- package/dist/test/capabilities/multiple-step-capability.spec.d.ts +2 -0
- package/dist/test/capabilities/multiple-step-capability.spec.d.ts.map +1 -0
- package/dist/test/capabilities/multiple-step-capability.spec.js +441 -0
- package/dist/test/capabilities/search-capability.spec.d.ts +2 -0
- package/dist/test/capabilities/search-capability.spec.d.ts.map +1 -0
- package/dist/test/capabilities/search-capability.spec.js +337 -0
- package/dist/test/capabilities/task-capability.spec.d.ts +2 -0
- package/dist/test/capabilities/task-capability.spec.d.ts.map +1 -0
- package/dist/test/capabilities/task-capability.spec.js +335 -0
- package/dist/test/capabilities/utils/capability-test-utils.d.ts +68 -0
- package/dist/test/capabilities/utils/capability-test-utils.d.ts.map +1 -0
- package/dist/test/capabilities/utils/capability-test-utils.js +161 -0
- package/dist/test/utils/tmp.node.d.ts +3 -0
- package/dist/test/utils/tmp.node.d.ts.map +1 -0
- package/dist/test/utils/tmp.node.js +8 -0
- package/package.json +15 -12
- package/dist/src/network/config/default.config.d.ts +0 -3
- package/dist/src/network/config/default.config.d.ts.map +0 -1
- package/dist/src/network/config/default.config.js +0 -32
- package/dist/src/network/index.d.ts +0 -5
- package/dist/src/network/index.d.ts.map +0 -1
- package/dist/src/network/index.js +0 -4
- package/dist/src/network/interfaces/network-status.enum.d.ts +0 -7
- package/dist/src/network/interfaces/network-status.enum.d.ts.map +0 -1
- package/dist/src/network/interfaces/network-status.enum.js +0 -7
- package/dist/src/network/interfaces/network.interface.d.ts +0 -18
- package/dist/src/network/interfaces/network.interface.d.ts.map +0 -1
- package/dist/src/network/interfaces/network.interface.js +0 -1
- package/dist/src/network/o-network.d.ts +0 -34
- package/dist/src/network/o-network.d.ts.map +0 -1
- package/dist/src/network/o-network.js +0 -247
- package/dist/test/utils/default.network.d.ts +0 -3
- package/dist/test/utils/default.network.d.ts.map +0 -1
- package/dist/test/utils/default.network.js +0 -33
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
// Note: CapabilityError is not exported from @olane/o-lane index
|
|
3
|
+
// We need to import directly from the errors file
|
|
4
|
+
// For now, we'll test the concept using standard errors until the export is available
|
|
5
|
+
describe('Capability Error Handling @capability @errors', () => {
|
|
6
|
+
describe('CapabilityErrorType enum', () => {
|
|
7
|
+
it('should define error types', () => {
|
|
8
|
+
// Test error type constants exist
|
|
9
|
+
const errorTypes = [
|
|
10
|
+
'NOT_FOUND',
|
|
11
|
+
'UNAUTHORIZED',
|
|
12
|
+
'FORBIDDEN',
|
|
13
|
+
'INVALID_CONFIG',
|
|
14
|
+
'MISSING_PARAMETER',
|
|
15
|
+
'INVALID_PARAMETER',
|
|
16
|
+
'TOOL_ERROR',
|
|
17
|
+
'TIMEOUT',
|
|
18
|
+
'NETWORK_ERROR',
|
|
19
|
+
'INVALID_STATE',
|
|
20
|
+
'RESOURCE_EXHAUSTED',
|
|
21
|
+
'UNKNOWN'
|
|
22
|
+
];
|
|
23
|
+
expect(errorTypes).to.be.an('array');
|
|
24
|
+
expect(errorTypes.length).to.equal(12);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('Error context structure', () => {
|
|
28
|
+
it('should support cycle context', () => {
|
|
29
|
+
const context = {
|
|
30
|
+
cycle: 5,
|
|
31
|
+
capabilityType: 'TASK',
|
|
32
|
+
toolAddress: 'o://test-tool',
|
|
33
|
+
method: 'testMethod'
|
|
34
|
+
};
|
|
35
|
+
expect(context.cycle).to.equal(5);
|
|
36
|
+
expect(context.capabilityType).to.equal('TASK');
|
|
37
|
+
expect(context.toolAddress).to.equal('o://test-tool');
|
|
38
|
+
expect(context.method).to.equal('testMethod');
|
|
39
|
+
});
|
|
40
|
+
it('should support capability type context', () => {
|
|
41
|
+
const context = {
|
|
42
|
+
capabilityType: 'EVALUATE'
|
|
43
|
+
};
|
|
44
|
+
expect(context.capabilityType).to.equal('EVALUATE');
|
|
45
|
+
});
|
|
46
|
+
it('should support tool address context', () => {
|
|
47
|
+
const context = {
|
|
48
|
+
toolAddress: 'o://calculator'
|
|
49
|
+
};
|
|
50
|
+
expect(context.toolAddress).to.equal('o://calculator');
|
|
51
|
+
});
|
|
52
|
+
it('should support method context', () => {
|
|
53
|
+
const context = {
|
|
54
|
+
method: 'add'
|
|
55
|
+
};
|
|
56
|
+
expect(context.method).to.equal('add');
|
|
57
|
+
});
|
|
58
|
+
it('should support additional data context', () => {
|
|
59
|
+
const context = {
|
|
60
|
+
data: {
|
|
61
|
+
param1: 'value1',
|
|
62
|
+
param2: 123,
|
|
63
|
+
nested: { value: true }
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
expect(context.data).to.exist;
|
|
67
|
+
expect(context.data.param1).to.equal('value1');
|
|
68
|
+
});
|
|
69
|
+
it('should support intent context', () => {
|
|
70
|
+
const context = {
|
|
71
|
+
intent: 'User wanted to calculate 2+2'
|
|
72
|
+
};
|
|
73
|
+
expect(context.intent).to.equal('User wanted to calculate 2+2');
|
|
74
|
+
});
|
|
75
|
+
it('should support empty context', () => {
|
|
76
|
+
const context = {};
|
|
77
|
+
expect(context).to.be.an('object');
|
|
78
|
+
expect(Object.keys(context).length).to.equal(0);
|
|
79
|
+
});
|
|
80
|
+
it('should support partial context', () => {
|
|
81
|
+
const context = {
|
|
82
|
+
cycle: 3,
|
|
83
|
+
toolAddress: 'o://test'
|
|
84
|
+
// Other fields omitted
|
|
85
|
+
};
|
|
86
|
+
expect(context.cycle).to.equal(3);
|
|
87
|
+
expect(context.toolAddress).to.equal('o://test');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe('Standard Error handling in capabilities', () => {
|
|
91
|
+
it('should create error with message', () => {
|
|
92
|
+
const error = new Error('Test capability error');
|
|
93
|
+
expect(error).to.be.instanceOf(Error);
|
|
94
|
+
expect(error.message).to.equal('Test capability error');
|
|
95
|
+
});
|
|
96
|
+
it('should preserve error stack trace', () => {
|
|
97
|
+
const error = new Error('Test error with stack');
|
|
98
|
+
expect(error.stack).to.exist;
|
|
99
|
+
expect(error.stack).to.be.a('string');
|
|
100
|
+
});
|
|
101
|
+
it('should support error with cause', () => {
|
|
102
|
+
const originalError = new Error('Original error');
|
|
103
|
+
const wrappedError = new Error('Wrapped error');
|
|
104
|
+
wrappedError.cause = originalError;
|
|
105
|
+
expect(wrappedError.cause).to.equal(originalError);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe('Error type inference', () => {
|
|
109
|
+
it('should infer NOT_FOUND from message', () => {
|
|
110
|
+
const messages = [
|
|
111
|
+
'Tool not found',
|
|
112
|
+
'Resource not found',
|
|
113
|
+
'Error 404',
|
|
114
|
+
'Cannot find the specified tool'
|
|
115
|
+
];
|
|
116
|
+
messages.forEach(msg => {
|
|
117
|
+
const error = new Error(msg);
|
|
118
|
+
expect(error.message.includes('not found') || error.message.includes('404')).to.be.true;
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
it('should infer UNAUTHORIZED from message', () => {
|
|
122
|
+
const messages = [
|
|
123
|
+
'Unauthorized access',
|
|
124
|
+
'Error 401',
|
|
125
|
+
'Not authorized'
|
|
126
|
+
];
|
|
127
|
+
messages.forEach(msg => {
|
|
128
|
+
const error = new Error(msg);
|
|
129
|
+
expect(error.message.toLowerCase()).to.satisfy((s) => s.includes('unauthorized') || s.includes('401') || s.includes('authorized'));
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
it('should infer FORBIDDEN from message', () => {
|
|
133
|
+
const messages = [
|
|
134
|
+
'Forbidden',
|
|
135
|
+
'Error 403',
|
|
136
|
+
'Access forbidden'
|
|
137
|
+
];
|
|
138
|
+
messages.forEach(msg => {
|
|
139
|
+
const error = new Error(msg);
|
|
140
|
+
expect(error.message).to.satisfy((s) => s.toLowerCase().includes('forbidden') || s.includes('403'));
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
it('should infer TIMEOUT from message', () => {
|
|
144
|
+
const messages = [
|
|
145
|
+
'Operation timeout',
|
|
146
|
+
'Request timed out',
|
|
147
|
+
'Timeout exceeded'
|
|
148
|
+
];
|
|
149
|
+
messages.forEach(msg => {
|
|
150
|
+
const error = new Error(msg);
|
|
151
|
+
expect(error.message.toLowerCase()).to.include('timeout');
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
it('should infer NETWORK_ERROR from message', () => {
|
|
155
|
+
const messages = [
|
|
156
|
+
'Network error',
|
|
157
|
+
'ECONNREFUSED',
|
|
158
|
+
'Connection refused'
|
|
159
|
+
];
|
|
160
|
+
messages.forEach(msg => {
|
|
161
|
+
const error = new Error(msg);
|
|
162
|
+
expect(error.message).to.satisfy((s) => s.toLowerCase().includes('network') || s.includes('ECONNREFUSED') || s.toLowerCase().includes('connection'));
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
it('should infer INVALID_CONFIG from message', () => {
|
|
166
|
+
const messages = [
|
|
167
|
+
'Invalid configuration',
|
|
168
|
+
'Config parameter missing',
|
|
169
|
+
'Configuration error'
|
|
170
|
+
];
|
|
171
|
+
messages.forEach(msg => {
|
|
172
|
+
const error = new Error(msg);
|
|
173
|
+
expect(error.message.toLowerCase()).to.satisfy((s) => s.includes('config') || s.includes('parameter'));
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
describe('Error message formatting', () => {
|
|
178
|
+
it('should create descriptive error messages', () => {
|
|
179
|
+
const error = new Error('Failed to configure the tool use');
|
|
180
|
+
expect(error.message).to.be.a('string');
|
|
181
|
+
expect(error.message.length).to.be.greaterThan(0);
|
|
182
|
+
});
|
|
183
|
+
it('should include context in error messages', () => {
|
|
184
|
+
const toolAddress = 'o://calculator';
|
|
185
|
+
const method = 'add';
|
|
186
|
+
const message = `Failed to execute ${method} on ${toolAddress}`;
|
|
187
|
+
const error = new Error(message);
|
|
188
|
+
expect(error.message).to.include(toolAddress);
|
|
189
|
+
expect(error.message).to.include(method);
|
|
190
|
+
});
|
|
191
|
+
it('should format multi-line error messages', () => {
|
|
192
|
+
const message = `Error occurred:
|
|
193
|
+
- Tool: o://test
|
|
194
|
+
- Method: testMethod
|
|
195
|
+
- Reason: Parameter validation failed`;
|
|
196
|
+
const error = new Error(message);
|
|
197
|
+
expect(error.message).to.include('Tool: o://test');
|
|
198
|
+
expect(error.message).to.include('Method: testMethod');
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
describe('Error remediation suggestions', () => {
|
|
202
|
+
it('should suggest remediation for NOT_FOUND errors', () => {
|
|
203
|
+
const remediation = 'Verify the tool address exists and is accessible. Use search to find available tools.';
|
|
204
|
+
expect(remediation).to.include('Verify');
|
|
205
|
+
expect(remediation).to.include('tool address');
|
|
206
|
+
});
|
|
207
|
+
it('should suggest remediation for UNAUTHORIZED errors', () => {
|
|
208
|
+
const remediation = 'Check that you have the necessary permissions to access this resource.';
|
|
209
|
+
expect(remediation).to.include('permissions');
|
|
210
|
+
});
|
|
211
|
+
it('should suggest remediation for INVALID_CONFIG errors', () => {
|
|
212
|
+
const remediation = 'Review the configuration parameters and ensure they match the required format.';
|
|
213
|
+
expect(remediation).to.include('configuration');
|
|
214
|
+
expect(remediation).to.include('parameters');
|
|
215
|
+
});
|
|
216
|
+
it('should suggest remediation for MISSING_PARAMETER errors', () => {
|
|
217
|
+
const remediation = 'Provide all required parameters. Use the tool\'s handshake to see parameter requirements.';
|
|
218
|
+
expect(remediation).to.include('parameters');
|
|
219
|
+
expect(remediation).to.include('handshake');
|
|
220
|
+
});
|
|
221
|
+
it('should suggest remediation for TIMEOUT errors', () => {
|
|
222
|
+
const remediation = 'The operation took too long. Try simplifying the request or increasing the timeout.';
|
|
223
|
+
expect(remediation).to.include('timeout');
|
|
224
|
+
});
|
|
225
|
+
it('should suggest remediation for NETWORK_ERROR errors', () => {
|
|
226
|
+
const remediation = 'Check your network connection and try again.';
|
|
227
|
+
expect(remediation).to.include('network');
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
describe('Error serialization', () => {
|
|
231
|
+
it('should serialize error to JSON', () => {
|
|
232
|
+
const error = new Error('Test error');
|
|
233
|
+
const json = {
|
|
234
|
+
name: error.name,
|
|
235
|
+
message: error.message,
|
|
236
|
+
stack: error.stack
|
|
237
|
+
};
|
|
238
|
+
expect(json.name).to.equal('Error');
|
|
239
|
+
expect(json.message).to.equal('Test error');
|
|
240
|
+
expect(json.stack).to.exist;
|
|
241
|
+
});
|
|
242
|
+
it('should include context in JSON serialization', () => {
|
|
243
|
+
const error = new Error('Test error');
|
|
244
|
+
const context = {
|
|
245
|
+
cycle: 5,
|
|
246
|
+
capabilityType: 'TASK',
|
|
247
|
+
toolAddress: 'o://test'
|
|
248
|
+
};
|
|
249
|
+
const json = {
|
|
250
|
+
name: error.name,
|
|
251
|
+
message: error.message,
|
|
252
|
+
context: context
|
|
253
|
+
};
|
|
254
|
+
expect(json.context).to.deep.equal(context);
|
|
255
|
+
});
|
|
256
|
+
it('should handle circular references in context', () => {
|
|
257
|
+
const context = {
|
|
258
|
+
cycle: 1
|
|
259
|
+
};
|
|
260
|
+
context.self = context; // Circular reference
|
|
261
|
+
// JSON.stringify would fail on circular refs, so we test safe handling
|
|
262
|
+
const safeContext = { cycle: context.cycle };
|
|
263
|
+
expect(safeContext.cycle).to.equal(1);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
describe('Error wrapping and chaining', () => {
|
|
267
|
+
it('should wrap generic errors', () => {
|
|
268
|
+
const originalError = new Error('Original error');
|
|
269
|
+
const wrappedError = new Error(`Capability failed: ${originalError.message}`);
|
|
270
|
+
expect(wrappedError.message).to.include('Original error');
|
|
271
|
+
});
|
|
272
|
+
it('should preserve original error information', () => {
|
|
273
|
+
const originalError = new Error('Database connection failed');
|
|
274
|
+
originalError.stack = 'Stack trace here';
|
|
275
|
+
const wrappedError = new Error(`Tool error: ${originalError.message}`);
|
|
276
|
+
wrappedError.originalError = originalError;
|
|
277
|
+
expect(wrappedError.originalError).to.equal(originalError);
|
|
278
|
+
expect(wrappedError.originalError.stack).to.exist;
|
|
279
|
+
});
|
|
280
|
+
it('should handle already wrapped errors', () => {
|
|
281
|
+
const error1 = new Error('Level 1 error');
|
|
282
|
+
const error2 = new Error(`Level 2: ${error1.message}`);
|
|
283
|
+
const error3 = new Error(`Level 3: ${error2.message}`);
|
|
284
|
+
expect(error3.message).to.include('Level 1 error');
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
describe('Error labels and categorization', () => {
|
|
288
|
+
it('should provide friendly labels for error types', () => {
|
|
289
|
+
const labels = {
|
|
290
|
+
NOT_FOUND: 'Resource Not Found',
|
|
291
|
+
UNAUTHORIZED: 'Unauthorized',
|
|
292
|
+
FORBIDDEN: 'Forbidden',
|
|
293
|
+
INVALID_CONFIG: 'Invalid Configuration',
|
|
294
|
+
MISSING_PARAMETER: 'Missing Parameter',
|
|
295
|
+
INVALID_PARAMETER: 'Invalid Parameter',
|
|
296
|
+
TOOL_ERROR: 'Tool Execution Error',
|
|
297
|
+
TIMEOUT: 'Timeout',
|
|
298
|
+
NETWORK_ERROR: 'Network Error',
|
|
299
|
+
INVALID_STATE: 'Invalid State',
|
|
300
|
+
RESOURCE_EXHAUSTED: 'Resource Exhausted',
|
|
301
|
+
UNKNOWN: 'Unknown Error'
|
|
302
|
+
};
|
|
303
|
+
expect(labels.NOT_FOUND).to.equal('Resource Not Found');
|
|
304
|
+
expect(labels.TIMEOUT).to.equal('Timeout');
|
|
305
|
+
expect(labels.UNKNOWN).to.equal('Unknown Error');
|
|
306
|
+
});
|
|
307
|
+
it('should categorize errors by severity', () => {
|
|
308
|
+
const severities = {
|
|
309
|
+
critical: ['RESOURCE_EXHAUSTED', 'NETWORK_ERROR'],
|
|
310
|
+
warning: ['TIMEOUT', 'INVALID_STATE'],
|
|
311
|
+
info: ['NOT_FOUND', 'MISSING_PARAMETER']
|
|
312
|
+
};
|
|
313
|
+
expect(severities.critical).to.include('RESOURCE_EXHAUSTED');
|
|
314
|
+
expect(severities.warning).to.include('TIMEOUT');
|
|
315
|
+
expect(severities.info).to.include('NOT_FOUND');
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
describe('Error recovery strategies', () => {
|
|
319
|
+
it('should indicate retryable errors', () => {
|
|
320
|
+
const retryableErrors = [
|
|
321
|
+
'TIMEOUT',
|
|
322
|
+
'NETWORK_ERROR',
|
|
323
|
+
'RESOURCE_EXHAUSTED'
|
|
324
|
+
];
|
|
325
|
+
expect(retryableErrors).to.include('TIMEOUT');
|
|
326
|
+
expect(retryableErrors).to.include('NETWORK_ERROR');
|
|
327
|
+
});
|
|
328
|
+
it('should indicate non-retryable errors', () => {
|
|
329
|
+
const nonRetryableErrors = [
|
|
330
|
+
'NOT_FOUND',
|
|
331
|
+
'UNAUTHORIZED',
|
|
332
|
+
'FORBIDDEN',
|
|
333
|
+
'INVALID_CONFIG',
|
|
334
|
+
'INVALID_PARAMETER'
|
|
335
|
+
];
|
|
336
|
+
expect(nonRetryableErrors).to.include('NOT_FOUND');
|
|
337
|
+
expect(nonRetryableErrors).to.include('UNAUTHORIZED');
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-integration.spec.d.ts","sourceRoot":"","sources":["../../../test/capabilities/capability-integration.spec.ts"],"names":[],"mappings":""}
|