@olane/os 0.7.12-alpha.59 → 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.
Files changed (34) hide show
  1. package/dist/test/capabilities/base-capability.spec.d.ts +2 -0
  2. package/dist/test/capabilities/base-capability.spec.d.ts.map +1 -0
  3. package/dist/test/capabilities/base-capability.spec.js +174 -0
  4. package/dist/test/capabilities/capability-errors.spec.d.ts +2 -0
  5. package/dist/test/capabilities/capability-errors.spec.d.ts.map +1 -0
  6. package/dist/test/capabilities/capability-errors.spec.js +340 -0
  7. package/dist/test/capabilities/capability-integration.spec.d.ts +2 -0
  8. package/dist/test/capabilities/capability-integration.spec.d.ts.map +1 -0
  9. package/dist/test/capabilities/capability-integration.spec.js +463 -0
  10. package/dist/test/capabilities/capability-registry.spec.d.ts +2 -0
  11. package/dist/test/capabilities/capability-registry.spec.d.ts.map +1 -0
  12. package/dist/test/capabilities/capability-registry.spec.js +261 -0
  13. package/dist/test/capabilities/configure-capability.spec.d.ts +2 -0
  14. package/dist/test/capabilities/configure-capability.spec.d.ts.map +1 -0
  15. package/dist/test/capabilities/configure-capability.spec.js +366 -0
  16. package/dist/test/capabilities/evaluate-capability.spec.d.ts +2 -0
  17. package/dist/test/capabilities/evaluate-capability.spec.d.ts.map +1 -0
  18. package/dist/test/capabilities/evaluate-capability.spec.js +323 -0
  19. package/dist/test/capabilities/intelligence-capability.spec.d.ts +2 -0
  20. package/dist/test/capabilities/intelligence-capability.spec.d.ts.map +1 -0
  21. package/dist/test/capabilities/intelligence-capability.spec.js +171 -0
  22. package/dist/test/capabilities/multiple-step-capability.spec.d.ts +2 -0
  23. package/dist/test/capabilities/multiple-step-capability.spec.d.ts.map +1 -0
  24. package/dist/test/capabilities/multiple-step-capability.spec.js +441 -0
  25. package/dist/test/capabilities/search-capability.spec.d.ts +2 -0
  26. package/dist/test/capabilities/search-capability.spec.d.ts.map +1 -0
  27. package/dist/test/capabilities/search-capability.spec.js +337 -0
  28. package/dist/test/capabilities/task-capability.spec.d.ts +2 -0
  29. package/dist/test/capabilities/task-capability.spec.d.ts.map +1 -0
  30. package/dist/test/capabilities/task-capability.spec.js +335 -0
  31. package/dist/test/capabilities/utils/capability-test-utils.d.ts +68 -0
  32. package/dist/test/capabilities/utils/capability-test-utils.d.ts.map +1 -0
  33. package/dist/test/capabilities/utils/capability-test-utils.js +161 -0
  34. package/package.json +15 -14
@@ -0,0 +1,337 @@
1
+ import { expect } from 'chai';
2
+ import { oCapabilitySearch, oCapabilityType } from '@olane/o-lane';
3
+ import { createTestOS, createTestLaneTool, createMockCapabilityConfig } from './utils/capability-test-utils.js';
4
+ describe('oCapabilitySearch @capability @search', () => {
5
+ let os;
6
+ let laneTool;
7
+ let searchCapability;
8
+ before(async () => {
9
+ os = await createTestOS();
10
+ laneTool = await createTestLaneTool(os);
11
+ });
12
+ after(async () => {
13
+ if (laneTool) {
14
+ await laneTool.stop();
15
+ }
16
+ if (os) {
17
+ await os.stop();
18
+ }
19
+ });
20
+ beforeEach(() => {
21
+ searchCapability = new oCapabilitySearch();
22
+ });
23
+ describe('type identification', () => {
24
+ it('should return SEARCH type from instance getter', () => {
25
+ expect(searchCapability.type).to.equal(oCapabilityType.SEARCH);
26
+ });
27
+ it('should return SEARCH type from static getter', () => {
28
+ expect(oCapabilitySearch.type).to.equal(oCapabilityType.SEARCH);
29
+ });
30
+ });
31
+ describe('configuration getters', () => {
32
+ it('should provide access to external flag', async () => {
33
+ const params = {
34
+ isExternal: true,
35
+ queries: [{ query: 'test query' }],
36
+ explanation: 'Test explanation'
37
+ };
38
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
39
+ await searchCapability.execute(config);
40
+ expect(searchCapability.external).to.be.true;
41
+ });
42
+ it('should provide access to queries', async () => {
43
+ const queries = [
44
+ { query: 'first query', limit: 10 },
45
+ { query: 'second query', limit: 20 }
46
+ ];
47
+ const params = {
48
+ isExternal: false,
49
+ queries,
50
+ explanation: 'Test explanation'
51
+ };
52
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
53
+ await searchCapability.execute(config);
54
+ expect(searchCapability.queries).to.deep.equal(queries);
55
+ });
56
+ it('should provide access to explanation', async () => {
57
+ const params = {
58
+ isExternal: false,
59
+ queries: [{ query: 'test' }],
60
+ explanation: 'This is why we are searching'
61
+ };
62
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
63
+ await searchCapability.execute(config);
64
+ expect(searchCapability.explanation).to.equal('This is why we are searching');
65
+ });
66
+ it('should handle internal search flag', async () => {
67
+ const params = {
68
+ isExternal: false,
69
+ queries: [{ query: 'test' }],
70
+ explanation: 'Internal search'
71
+ };
72
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
73
+ await searchCapability.execute(config);
74
+ expect(searchCapability.external).to.be.false;
75
+ });
76
+ });
77
+ describe('internal search', () => {
78
+ it('should execute internal search when isExternal is false', async () => {
79
+ const params = {
80
+ isExternal: false,
81
+ queries: [{ query: 'test internal search', limit: 5 }],
82
+ explanation: 'Testing internal search'
83
+ };
84
+ const config = createMockCapabilityConfig(laneTool, 'Internal search intent', params);
85
+ const result = await searchCapability.execute(config);
86
+ expect(result).to.exist;
87
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
88
+ });
89
+ it('should handle multiple internal search queries', async () => {
90
+ const params = {
91
+ isExternal: false,
92
+ queries: [
93
+ { query: 'first query', limit: 5 },
94
+ { query: 'second query', limit: 10 },
95
+ { query: 'third query', limit: 15 }
96
+ ],
97
+ explanation: 'Multiple queries'
98
+ };
99
+ const config = createMockCapabilityConfig(laneTool, 'Multiple search intent', params);
100
+ const result = await searchCapability.execute(config);
101
+ expect(result).to.exist;
102
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
103
+ });
104
+ it('should handle query without limit', async () => {
105
+ const params = {
106
+ isExternal: false,
107
+ queries: [{ query: 'test query' }], // No limit specified
108
+ explanation: 'Query without limit'
109
+ };
110
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
111
+ const result = await searchCapability.execute(config);
112
+ expect(result).to.exist;
113
+ // Default limit of 20 should be used
114
+ });
115
+ it('should format internal search results', async () => {
116
+ const params = {
117
+ isExternal: false,
118
+ queries: [{ query: 'formatting test', limit: 3 }],
119
+ explanation: 'Test formatting'
120
+ };
121
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
122
+ const result = await searchCapability.execute(config);
123
+ expect(result).to.exist;
124
+ expect(result.result).to.be.a('string');
125
+ // Should contain search result markers
126
+ if (typeof result.result === 'string') {
127
+ expect(result.result).to.include('[Search Results Begin]');
128
+ expect(result.result).to.include('[Search Results End]');
129
+ }
130
+ });
131
+ it('should handle empty search results', async () => {
132
+ const params = {
133
+ isExternal: false,
134
+ queries: [{ query: 'query_that_returns_nothing_xyz123', limit: 5 }],
135
+ explanation: 'Empty results test'
136
+ };
137
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
138
+ const result = await searchCapability.execute(config);
139
+ expect(result).to.exist;
140
+ // Should handle empty results gracefully
141
+ });
142
+ });
143
+ describe('external search', () => {
144
+ it('should execute external search when isExternal is true', async () => {
145
+ const params = {
146
+ isExternal: true,
147
+ queries: [{ query: 'test external search' }],
148
+ explanation: 'Testing external search'
149
+ };
150
+ const config = createMockCapabilityConfig(laneTool, 'External search intent', params);
151
+ const result = await searchCapability.execute(config);
152
+ expect(result).to.exist;
153
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
154
+ });
155
+ it('should handle multiple external search queries', async () => {
156
+ const params = {
157
+ isExternal: true,
158
+ queries: [
159
+ { query: 'first external query' },
160
+ { query: 'second external query' }
161
+ ],
162
+ explanation: 'Multiple external queries'
163
+ };
164
+ const config = createMockCapabilityConfig(laneTool, 'Multiple search intent', params);
165
+ const result = await searchCapability.execute(config);
166
+ expect(result).to.exist;
167
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
168
+ });
169
+ it('should format external search results', async () => {
170
+ const params = {
171
+ isExternal: true,
172
+ queries: [{ query: 'external formatting test' }],
173
+ explanation: 'Test external formatting'
174
+ };
175
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
176
+ const result = await searchCapability.execute(config);
177
+ expect(result).to.exist;
178
+ expect(result.result).to.be.a('string');
179
+ // Should contain search result markers
180
+ if (typeof result.result === 'string') {
181
+ expect(result.result).to.include('[Search Results Begin]');
182
+ expect(result.result).to.include('[Search Results End]');
183
+ }
184
+ });
185
+ it('should handle external search with streaming', async () => {
186
+ const chunks = [];
187
+ const params = {
188
+ isExternal: true,
189
+ queries: [{ query: 'streaming test query' }],
190
+ explanation: 'Test streaming'
191
+ };
192
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params, {
193
+ useStream: true,
194
+ onChunk: (chunk) => chunks.push(chunk)
195
+ });
196
+ const result = await searchCapability.execute(config);
197
+ expect(result).to.exist;
198
+ expect(config.useStream).to.be.true;
199
+ });
200
+ });
201
+ describe('result structure', () => {
202
+ it('should return oCapabilitySearchResult', async () => {
203
+ const params = {
204
+ isExternal: false,
205
+ queries: [{ query: 'test' }],
206
+ explanation: 'Result structure test'
207
+ };
208
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
209
+ const result = await searchCapability.execute(config);
210
+ expect(result).to.exist;
211
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
212
+ expect(result.result).to.exist;
213
+ expect(result.config).to.equal(config);
214
+ });
215
+ it('should include formatted result string', async () => {
216
+ const params = {
217
+ isExternal: false,
218
+ queries: [{ query: 'test' }],
219
+ explanation: 'Formatted result test'
220
+ };
221
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
222
+ const result = await searchCapability.execute(config);
223
+ expect(result.result).to.be.a('string');
224
+ });
225
+ it('should include humanResult with raw data', async () => {
226
+ const params = {
227
+ isExternal: false,
228
+ queries: [{ query: 'test' }],
229
+ explanation: 'Human result test'
230
+ };
231
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
232
+ const result = await searchCapability.execute(config);
233
+ expect(result.humanResult).to.exist;
234
+ });
235
+ it('should set type to EVALUATE in result', async () => {
236
+ const params = {
237
+ isExternal: false,
238
+ queries: [{ query: 'test' }],
239
+ explanation: 'Type test'
240
+ };
241
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
242
+ const result = await searchCapability.execute(config);
243
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
244
+ });
245
+ });
246
+ describe('query handling', () => {
247
+ it('should handle single query', async () => {
248
+ const params = {
249
+ isExternal: false,
250
+ queries: [{ query: 'single query test' }],
251
+ explanation: 'Single query'
252
+ };
253
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
254
+ const result = await searchCapability.execute(config);
255
+ expect(result).to.exist;
256
+ expect(searchCapability.queries.length).to.equal(1);
257
+ });
258
+ it('should handle empty queries array', async () => {
259
+ const params = {
260
+ isExternal: false,
261
+ queries: [],
262
+ explanation: 'Empty queries'
263
+ };
264
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
265
+ const result = await searchCapability.execute(config);
266
+ expect(result).to.exist;
267
+ expect(searchCapability.queries.length).to.equal(0);
268
+ });
269
+ it('should handle complex query strings', async () => {
270
+ const params = {
271
+ isExternal: false,
272
+ queries: [
273
+ { query: 'query with special chars !@#$%^&*()' },
274
+ { query: 'query with "quotes" and \'apostrophes\'' },
275
+ { query: 'multi\nline\nquery' }
276
+ ],
277
+ explanation: 'Complex queries'
278
+ };
279
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
280
+ const result = await searchCapability.execute(config);
281
+ expect(result).to.exist;
282
+ expect(searchCapability.queries.length).to.equal(3);
283
+ });
284
+ it('should preserve query limits', async () => {
285
+ const params = {
286
+ isExternal: false,
287
+ queries: [
288
+ { query: 'query 1', limit: 5 },
289
+ { query: 'query 2', limit: 15 },
290
+ { query: 'query 3', limit: 25 }
291
+ ],
292
+ explanation: 'Limit preservation test'
293
+ };
294
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
295
+ await searchCapability.execute(config);
296
+ expect(searchCapability.queries[0].limit).to.equal(5);
297
+ expect(searchCapability.queries[1].limit).to.equal(15);
298
+ expect(searchCapability.queries[2].limit).to.equal(25);
299
+ });
300
+ });
301
+ describe('error handling', () => {
302
+ it('should handle search service unavailable', async () => {
303
+ const params = {
304
+ isExternal: false,
305
+ queries: [{ query: 'test' }],
306
+ explanation: 'Service unavailable test'
307
+ };
308
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
309
+ // Search may fail if service not available
310
+ try {
311
+ const result = await searchCapability.execute(config);
312
+ expect(result).to.exist;
313
+ }
314
+ catch (error) {
315
+ // Expected if search service is not configured
316
+ expect(error).to.exist;
317
+ }
318
+ });
319
+ it('should handle external provider unavailable', async () => {
320
+ const params = {
321
+ isExternal: true,
322
+ queries: [{ query: 'test' }],
323
+ explanation: 'External provider unavailable test'
324
+ };
325
+ const config = createMockCapabilityConfig(laneTool, 'Search intent', params);
326
+ // External search may fail if Perplexity is not configured
327
+ try {
328
+ const result = await searchCapability.execute(config);
329
+ expect(result).to.exist;
330
+ }
331
+ catch (error) {
332
+ // Expected if external search service is not configured
333
+ expect(error).to.exist;
334
+ }
335
+ });
336
+ });
337
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=task-capability.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-capability.spec.d.ts","sourceRoot":"","sources":["../../../test/capabilities/task-capability.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,335 @@
1
+ import { expect } from 'chai';
2
+ import { oCapabilityTask, oCapabilityType } from '@olane/o-lane';
3
+ import { createTestOS, createTestLaneTool, createMockCapabilityConfig } from './utils/capability-test-utils.js';
4
+ describe('oCapabilityTask @capability @task', () => {
5
+ let os;
6
+ let laneTool;
7
+ let taskCapability;
8
+ before(async () => {
9
+ os = await createTestOS();
10
+ laneTool = await createTestLaneTool(os);
11
+ });
12
+ after(async () => {
13
+ if (laneTool) {
14
+ await laneTool.stop();
15
+ }
16
+ if (os) {
17
+ await os.stop();
18
+ }
19
+ });
20
+ beforeEach(() => {
21
+ taskCapability = new oCapabilityTask();
22
+ });
23
+ describe('type identification', () => {
24
+ it('should return TASK type from instance getter', () => {
25
+ expect(taskCapability.type).to.equal(oCapabilityType.TASK);
26
+ });
27
+ it('should return TASK type from static getter', () => {
28
+ expect(oCapabilityTask.type).to.equal(oCapabilityType.TASK);
29
+ });
30
+ });
31
+ describe('task getter', () => {
32
+ it('should provide access to task from params', async () => {
33
+ const task = {
34
+ address: 'o://test-tool',
35
+ payload: {
36
+ method: 'testMethod',
37
+ params: { arg1: 'value1' }
38
+ }
39
+ };
40
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
41
+ await taskCapability.execute(config);
42
+ expect(taskCapability.task).to.deep.equal(task);
43
+ });
44
+ it('should handle undefined task params', async () => {
45
+ const config = createMockCapabilityConfig(laneTool, 'Test task', {});
46
+ await taskCapability.execute(config);
47
+ expect(taskCapability.task).to.be.undefined;
48
+ });
49
+ });
50
+ describe('run() method - validation', () => {
51
+ it('should fail if task is missing', async () => {
52
+ const config = createMockCapabilityConfig(laneTool, 'Test task', {});
53
+ const result = await taskCapability.execute(config);
54
+ expect(result.error).to.exist;
55
+ expect(result.error).to.include('Failed to configure the tool use');
56
+ });
57
+ it('should fail if task.address is missing', async () => {
58
+ const task = {
59
+ payload: {
60
+ method: 'testMethod',
61
+ params: { arg1: 'value1' }
62
+ }
63
+ };
64
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
65
+ const result = await taskCapability.execute(config);
66
+ expect(result.error).to.exist;
67
+ expect(result.error).to.include('Failed to configure the tool use');
68
+ });
69
+ it('should fail if task object is null', async () => {
70
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task: null });
71
+ const result = await taskCapability.execute(config);
72
+ expect(result.error).to.exist;
73
+ });
74
+ });
75
+ describe('run() method - approval system', () => {
76
+ it('should handle missing approval service gracefully', async () => {
77
+ const task = {
78
+ address: 'o://nonexistent-tool',
79
+ payload: {
80
+ method: 'testMethod',
81
+ params: {}
82
+ }
83
+ };
84
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
85
+ // This should attempt approval and continue even if service is not available
86
+ const result = await taskCapability.execute(config);
87
+ // The task will fail because the tool doesn't exist, but not because of approval
88
+ expect(result).to.exist;
89
+ });
90
+ it('should handle task with params for approval', async () => {
91
+ const task = {
92
+ address: 'o://test-tool',
93
+ payload: {
94
+ method: 'testMethod',
95
+ params: { arg1: 'value1', arg2: 123 }
96
+ }
97
+ };
98
+ const config = createMockCapabilityConfig(laneTool, 'Test task with params', { task });
99
+ const result = await taskCapability.execute(config);
100
+ expect(result).to.exist;
101
+ // Result may have error if tool/approval doesn't exist, but validates structure
102
+ });
103
+ });
104
+ describe('run() method - task execution', () => {
105
+ it('should handle tool not found error', async () => {
106
+ const task = {
107
+ address: 'o://nonexistent-tool',
108
+ payload: {
109
+ method: 'someMethod',
110
+ params: {}
111
+ }
112
+ };
113
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
114
+ const result = await taskCapability.execute(config);
115
+ expect(result).to.exist;
116
+ expect(result.error).to.exist;
117
+ });
118
+ it('should handle method not found error', async () => {
119
+ const task = {
120
+ address: 'o://test-tool',
121
+ payload: {
122
+ method: 'nonexistentMethod',
123
+ params: {}
124
+ }
125
+ };
126
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
127
+ const result = await taskCapability.execute(config);
128
+ expect(result).to.exist;
129
+ // Will likely error because tool doesn't exist
130
+ });
131
+ it('should include task address in execution', async () => {
132
+ const toolAddress = 'o://test-calculation-tool';
133
+ const task = {
134
+ address: toolAddress,
135
+ payload: {
136
+ method: 'calculate',
137
+ params: { a: 5, b: 10 }
138
+ }
139
+ };
140
+ const config = createMockCapabilityConfig(laneTool, 'Calculate something', { task });
141
+ const result = await taskCapability.execute(config);
142
+ expect(result).to.exist;
143
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
144
+ });
145
+ });
146
+ describe('result structure', () => {
147
+ it('should return oCapabilityTaskResult', async () => {
148
+ const task = {
149
+ address: 'o://test-tool',
150
+ payload: {
151
+ method: 'testMethod',
152
+ params: {}
153
+ }
154
+ };
155
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
156
+ const result = await taskCapability.execute(config);
157
+ expect(result).to.exist;
158
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
159
+ expect(result.config).to.equal(config);
160
+ });
161
+ it('should set type to EVALUATE in result', async () => {
162
+ const task = {
163
+ address: 'o://test-tool',
164
+ payload: {
165
+ method: 'testMethod',
166
+ params: {}
167
+ }
168
+ };
169
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
170
+ const result = await taskCapability.execute(config);
171
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
172
+ });
173
+ it('should include config in result', async () => {
174
+ const task = {
175
+ address: 'o://test-tool',
176
+ payload: {
177
+ method: 'testMethod',
178
+ params: {}
179
+ }
180
+ };
181
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
182
+ const result = await taskCapability.execute(config);
183
+ expect(result.config).to.exist;
184
+ expect(result.config).to.equal(config);
185
+ });
186
+ });
187
+ describe('streaming support', () => {
188
+ it('should call onChunk when provided', async () => {
189
+ const chunks = [];
190
+ const task = {
191
+ address: 'o://test-tool',
192
+ payload: {
193
+ method: 'testMethod',
194
+ params: {}
195
+ }
196
+ };
197
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task }, {
198
+ useStream: true,
199
+ onChunk: (chunk) => chunks.push(chunk)
200
+ });
201
+ await taskCapability.execute(config);
202
+ // onChunk is called with the response
203
+ // May not have chunks if tool doesn't exist, but validates structure
204
+ expect(config.onChunk).to.be.a('function');
205
+ });
206
+ it('should handle streaming without onChunk callback', async () => {
207
+ const task = {
208
+ address: 'o://test-tool',
209
+ payload: {
210
+ method: 'testMethod',
211
+ params: {}
212
+ }
213
+ };
214
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task }, { useStream: true });
215
+ const result = await taskCapability.execute(config);
216
+ expect(result).to.exist;
217
+ });
218
+ });
219
+ describe('replay mode', () => {
220
+ it('should handle replay mode flag', async () => {
221
+ const task = {
222
+ address: 'o://test-tool',
223
+ payload: {
224
+ method: 'testMethod',
225
+ params: {}
226
+ }
227
+ };
228
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task }, { isReplay: true });
229
+ const result = await taskCapability.execute(config);
230
+ expect(result).to.exist;
231
+ expect(config.isReplay).to.be.true;
232
+ });
233
+ it('should execute task even in replay mode', async () => {
234
+ const task = {
235
+ address: 'o://test-tool',
236
+ payload: {
237
+ method: 'testMethod',
238
+ params: { replay: true }
239
+ }
240
+ };
241
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task }, { isReplay: true });
242
+ const result = await taskCapability.execute(config);
243
+ expect(result).to.exist;
244
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
245
+ });
246
+ });
247
+ describe('error handling', () => {
248
+ it('should return error in result on failure', async () => {
249
+ const config = createMockCapabilityConfig(laneTool, 'Test task', {});
250
+ const result = await taskCapability.execute(config);
251
+ expect(result.error).to.exist;
252
+ expect(result.error).to.be.a('string');
253
+ });
254
+ it('should handle oError instances', async () => {
255
+ const task = {
256
+ address: null, // Invalid address
257
+ payload: {
258
+ method: 'testMethod',
259
+ params: {}
260
+ }
261
+ };
262
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
263
+ const result = await taskCapability.execute(config);
264
+ expect(result.error).to.exist;
265
+ });
266
+ it('should include error type in result', async () => {
267
+ const config = createMockCapabilityConfig(laneTool, 'Test task', {});
268
+ const result = await taskCapability.execute(config);
269
+ expect(result.type).to.equal(oCapabilityType.EVALUATE);
270
+ expect(result.error).to.exist;
271
+ });
272
+ });
273
+ describe('persistence flag', () => {
274
+ it('should detect _save flag in tool response', async () => {
275
+ // This tests the structure - actual _save detection requires tool response
276
+ const task = {
277
+ address: 'o://test-tool',
278
+ payload: {
279
+ method: 'testMethod',
280
+ params: {}
281
+ }
282
+ };
283
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
284
+ const result = await taskCapability.execute(config);
285
+ expect(result).to.exist;
286
+ // shouldPersist would be set if tool response contained _save: true
287
+ expect(result.hasOwnProperty('shouldPersist')).to.be.true;
288
+ });
289
+ });
290
+ describe('parameter handling', () => {
291
+ it('should pass params to tool execution', async () => {
292
+ const params = {
293
+ stringParam: 'test',
294
+ numberParam: 123,
295
+ boolParam: true,
296
+ objectParam: { nested: 'value' },
297
+ arrayParam: [1, 2, 3]
298
+ };
299
+ const task = {
300
+ address: 'o://test-tool',
301
+ payload: {
302
+ method: 'testMethod',
303
+ params
304
+ }
305
+ };
306
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
307
+ const result = await taskCapability.execute(config);
308
+ expect(result).to.exist;
309
+ expect(taskCapability.task.payload.params).to.deep.equal(params);
310
+ });
311
+ it('should handle empty params', async () => {
312
+ const task = {
313
+ address: 'o://test-tool',
314
+ payload: {
315
+ method: 'testMethod',
316
+ params: {}
317
+ }
318
+ };
319
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
320
+ const result = await taskCapability.execute(config);
321
+ expect(result).to.exist;
322
+ });
323
+ it('should handle undefined params', async () => {
324
+ const task = {
325
+ address: 'o://test-tool',
326
+ payload: {
327
+ method: 'testMethod'
328
+ }
329
+ };
330
+ const config = createMockCapabilityConfig(laneTool, 'Test task', { task });
331
+ const result = await taskCapability.execute(config);
332
+ expect(result).to.exist;
333
+ });
334
+ });
335
+ });