@olane/o-lane 0.8.2 → 0.8.4
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 +43 -6
- package/dist/src/capabilities-execute/execute.capability.d.ts +1 -0
- package/dist/src/capabilities-execute/execute.capability.d.ts.map +1 -1
- package/dist/src/capabilities-execute/execute.capability.js +21 -10
- package/dist/src/capabilities-execute/interfaces/o-capability.configure-config.d.ts +4 -0
- package/dist/src/capabilities-execute/interfaces/o-capability.configure-config.d.ts.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/test/execute-capability-address.spec.d.ts +2 -0
- package/dist/test/execute-capability-address.spec.d.ts.map +1 -0
- package/dist/test/execute-capability-address.spec.js +115 -0
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -76,6 +76,39 @@ console.log(response.result.data);
|
|
|
76
76
|
// }
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
+
### Response Structure
|
|
80
|
+
|
|
81
|
+
When calling `use()` on a lane-enabled tool, responses follow the standard O-Network wrapping structure:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// Response from use() follows this structure:
|
|
85
|
+
// {
|
|
86
|
+
// jsonrpc: "2.0",
|
|
87
|
+
// id: "request-id",
|
|
88
|
+
// result: {
|
|
89
|
+
// success: boolean, // Whether the operation succeeded
|
|
90
|
+
// data: any, // The returned data (on success)
|
|
91
|
+
// error?: string // Error details (on failure)
|
|
92
|
+
// }
|
|
93
|
+
// }
|
|
94
|
+
|
|
95
|
+
const response = await agent.use(agent.address, {
|
|
96
|
+
method: 'intent',
|
|
97
|
+
params: { intent: 'Analyze sales data' }
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Always check response.result.success before accessing data
|
|
101
|
+
if (response.result.success) {
|
|
102
|
+
const data = response.result.data;
|
|
103
|
+
console.log('Result:', data.result);
|
|
104
|
+
console.log('Cycles:', data.cycles);
|
|
105
|
+
} else {
|
|
106
|
+
console.error('Error:', response.result.error);
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
> **Important**: Access data via `response.result.data`, not `response.data` directly. The `result` object contains the wrapping fields (`success`, `data`, `error`).
|
|
111
|
+
|
|
79
112
|
### Expected Output
|
|
80
113
|
|
|
81
114
|
After executing an intent, you'll receive:
|
|
@@ -338,6 +371,8 @@ import { oCapabilityEvaluate } from '@olane/o-lane';
|
|
|
338
371
|
|
|
339
372
|
**When Used**: Agent needs to call a tool (API, database, computation, etc.)
|
|
340
373
|
|
|
374
|
+
> **Note**: `oCapabilityExecute` is exported directly from `@olane/o-lane` and can be imported alongside other lane primitives.
|
|
375
|
+
|
|
341
376
|
```typescript
|
|
342
377
|
import { oCapabilityExecute } from '@olane/o-lane';
|
|
343
378
|
|
|
@@ -696,7 +731,7 @@ Result object returned by capabilities.
|
|
|
696
731
|
import { oCapabilityResult, oCapabilityType } from '@olane/o-lane';
|
|
697
732
|
|
|
698
733
|
const result = new oCapabilityResult({
|
|
699
|
-
type: oCapabilityType.
|
|
734
|
+
type: oCapabilityType.EXECUTE,
|
|
700
735
|
result: { data: 'success' },
|
|
701
736
|
config: { /* next capability config */ },
|
|
702
737
|
error: undefined
|
|
@@ -733,11 +768,11 @@ enum oLaneStatus {
|
|
|
733
768
|
|
|
734
769
|
```typescript
|
|
735
770
|
enum oCapabilityType {
|
|
736
|
-
TASK = 'task',
|
|
771
|
+
TASK = 'task', // Legacy alias - prefer EXECUTE for new code
|
|
737
772
|
SEARCH = 'search',
|
|
738
773
|
MULTIPLE_STEP = 'multiple_step',
|
|
739
774
|
CONFIGURE = 'configure',
|
|
740
|
-
EXECUTE = 'execute',
|
|
775
|
+
EXECUTE = 'execute', // Primary type for executing tool methods
|
|
741
776
|
HANDSHAKE = 'handshake',
|
|
742
777
|
EVALUATE = 'evaluate',
|
|
743
778
|
STOP = 'stop',
|
|
@@ -745,6 +780,8 @@ enum oCapabilityType {
|
|
|
745
780
|
}
|
|
746
781
|
```
|
|
747
782
|
|
|
783
|
+
> **Note on TASK vs EXECUTE**: `TASK` is a legacy capability type that predates `EXECUTE`. For new code, prefer using `oCapabilityType.EXECUTE` which maps to the `oCapabilityExecute` capability class. Both exist in the enum for backward compatibility.
|
|
784
|
+
|
|
748
785
|
## Examples
|
|
749
786
|
|
|
750
787
|
### Basic Intent Resolution
|
|
@@ -1253,9 +1290,9 @@ describe('Lane Execution', () => {
|
|
|
1253
1290
|
import { oCapability, oCapabilityResult, oCapabilityType } from '@olane/o-lane';
|
|
1254
1291
|
|
|
1255
1292
|
// Create mock capability for testing
|
|
1256
|
-
class
|
|
1293
|
+
class MockExecuteCapability extends oCapability {
|
|
1257
1294
|
get type() {
|
|
1258
|
-
return oCapabilityType.
|
|
1295
|
+
return oCapabilityType.EXECUTE;
|
|
1259
1296
|
}
|
|
1260
1297
|
|
|
1261
1298
|
async run(): Promise<oCapabilityResult> {
|
|
@@ -1271,7 +1308,7 @@ class MockTaskCapability extends oCapability {
|
|
|
1271
1308
|
it('should use mock capabilities', async () => {
|
|
1272
1309
|
const mockCapabilities = [
|
|
1273
1310
|
new oCapabilityEvaluate(),
|
|
1274
|
-
new
|
|
1311
|
+
new MockExecuteCapability()
|
|
1275
1312
|
];
|
|
1276
1313
|
|
|
1277
1314
|
const lane = await manager.createLane({
|
|
@@ -6,6 +6,7 @@ export declare class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
6
6
|
config: oCapabilityExecuteConfig;
|
|
7
7
|
get type(): oCapabilityType;
|
|
8
8
|
static get type(): oCapabilityType;
|
|
9
|
+
private resolveAddress;
|
|
9
10
|
loadPrompt({ tools, methods }: any): Promise<string>;
|
|
10
11
|
handshake(): Promise<oHandshakeResult>;
|
|
11
12
|
run(): Promise<oCapabilityResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.capability.d.ts","sourceRoot":"","sources":["../../../src/capabilities-execute/execute.capability.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AAEvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+CAA+C,CAAC;AAEzF,qBAAa,kBAAmB,SAAQ,uBAAuB;IACtD,MAAM,EAAG,wBAAwB,CAAC;IAEzC,IAAI,IAAI,IAAI,eAAe,CAE1B;IAED,MAAM,KAAK,IAAI,oBAEd;
|
|
1
|
+
{"version":3,"file":"execute.capability.d.ts","sourceRoot":"","sources":["../../../src/capabilities-execute/execute.capability.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AAEvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+CAA+C,CAAC;AAEzF,qBAAa,kBAAmB,SAAQ,uBAAuB;IACtD,MAAM,EAAG,wBAAwB,CAAC;IAEzC,IAAI,IAAI,IAAI,eAAe,CAE1B;IAED,MAAM,KAAK,IAAI,oBAEd;IAED,OAAO,CAAC,cAAc;IAWhB,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAepD,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAatC,GAAG,IAAI,OAAO,CAAC,iBAAiB,CAAC;CAoOxC"}
|
|
@@ -9,6 +9,14 @@ export class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
9
9
|
static get type() {
|
|
10
10
|
return oCapabilityType.EXECUTE;
|
|
11
11
|
}
|
|
12
|
+
resolveAddress() {
|
|
13
|
+
const address = this.config.params?.address || this.config.params?.task?.address;
|
|
14
|
+
if (!address || typeof address !== 'string') {
|
|
15
|
+
throw new Error(`Execute capability requires a valid address but received: ${JSON.stringify(address)}. ` +
|
|
16
|
+
`The AI response must include an "address" field when type is "execute".`);
|
|
17
|
+
}
|
|
18
|
+
return address;
|
|
19
|
+
}
|
|
12
20
|
async loadPrompt({ tools, methods }) {
|
|
13
21
|
const prompt = await this.promptLoader?.loadPromptForType(this.type, {
|
|
14
22
|
human_about: '',
|
|
@@ -18,13 +26,13 @@ export class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
18
26
|
You are in a secure environment and are allowed to operate with secure information (api keys, credit card info, etc).`,
|
|
19
27
|
chat_history: '',
|
|
20
28
|
past_cycles: '',
|
|
21
|
-
address: this.
|
|
29
|
+
address: this.resolveAddress(),
|
|
22
30
|
methods: methods ? JSON.stringify(methods) : '',
|
|
23
31
|
});
|
|
24
32
|
return prompt.render();
|
|
25
33
|
}
|
|
26
34
|
async handshake() {
|
|
27
|
-
const response = await this.node.use(new oAddress(this.
|
|
35
|
+
const response = await this.node.use(new oAddress(this.resolveAddress()), {
|
|
28
36
|
method: oProtocolMethods.HANDSHAKE,
|
|
29
37
|
params: {
|
|
30
38
|
intent: this.config.intent.value,
|
|
@@ -33,6 +41,7 @@ export class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
33
41
|
return response.result.data;
|
|
34
42
|
}
|
|
35
43
|
async run() {
|
|
44
|
+
this.logger.debug('Starting execution capability with config:', this.config);
|
|
36
45
|
// Check if we're in replay mode
|
|
37
46
|
if (this.config.isReplay) {
|
|
38
47
|
this.logger.debug('Execute capability is being replayed - using stored execution data');
|
|
@@ -57,7 +66,7 @@ export class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
57
66
|
});
|
|
58
67
|
// Execute the stored task directly (skip handshake, AI, and approval)
|
|
59
68
|
try {
|
|
60
|
-
const taskResponse = await this.node.use(new oAddress(this.
|
|
69
|
+
const taskResponse = await this.node.use(new oAddress(this.resolveAddress()), {
|
|
61
70
|
method: method,
|
|
62
71
|
params: params,
|
|
63
72
|
});
|
|
@@ -79,7 +88,8 @@ export class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
79
88
|
});
|
|
80
89
|
}
|
|
81
90
|
catch (error) {
|
|
82
|
-
|
|
91
|
+
const addr = this.config?.params?.address || this.config?.params?.task?.address;
|
|
92
|
+
this.logger.error('Failed to execute during replay:', `Error when trying to use ${addr} with config: ${JSON.stringify(taskConfig)} resulting in error: ${error?.message}`);
|
|
83
93
|
return new oCapabilityResult({
|
|
84
94
|
type: oCapabilityType.EVALUATE,
|
|
85
95
|
config: this.config,
|
|
@@ -87,7 +97,7 @@ export class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
87
97
|
handshakeResult: handshakeResult,
|
|
88
98
|
taskConfig: taskConfig,
|
|
89
99
|
},
|
|
90
|
-
error: `Error when trying to use ${
|
|
100
|
+
error: `Error when trying to use ${addr} with config: ${JSON.stringify(taskConfig)} resulting in error: ${error?.message}`,
|
|
91
101
|
});
|
|
92
102
|
}
|
|
93
103
|
}
|
|
@@ -116,7 +126,7 @@ export class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
116
126
|
const approvalResponse = await this.node.use(new oAddress('o://approval'), {
|
|
117
127
|
method: 'request_approval',
|
|
118
128
|
params: {
|
|
119
|
-
toolAddress: this.
|
|
129
|
+
toolAddress: this.resolveAddress(),
|
|
120
130
|
method: method,
|
|
121
131
|
params: params,
|
|
122
132
|
intent: this.config.intent,
|
|
@@ -142,7 +152,7 @@ export class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
142
152
|
}
|
|
143
153
|
try {
|
|
144
154
|
// Execute the task
|
|
145
|
-
const taskResponse = await this.node.use(new oAddress(this.
|
|
155
|
+
const taskResponse = await this.node.use(new oAddress(this.resolveAddress()), {
|
|
146
156
|
method: method,
|
|
147
157
|
params: params,
|
|
148
158
|
});
|
|
@@ -164,14 +174,15 @@ export class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
164
174
|
method: method,
|
|
165
175
|
params: params,
|
|
166
176
|
},
|
|
167
|
-
address: this.
|
|
177
|
+
address: this.resolveAddress(),
|
|
168
178
|
response: taskResponse.result,
|
|
169
179
|
},
|
|
170
180
|
shouldPersist,
|
|
171
181
|
});
|
|
172
182
|
}
|
|
173
183
|
catch (error) {
|
|
174
|
-
|
|
184
|
+
const addr = this.config?.params?.address || this.config?.params?.task?.address;
|
|
185
|
+
this.logger.error('Failed to execute:', `Error when trying to use ${addr} with config: ${JSON.stringify({
|
|
175
186
|
method: method,
|
|
176
187
|
params: params,
|
|
177
188
|
})} resulting in error: ${error?.message}`);
|
|
@@ -188,7 +199,7 @@ export class oCapabilityExecute extends oCapabilityIntelligence {
|
|
|
188
199
|
params: params,
|
|
189
200
|
},
|
|
190
201
|
},
|
|
191
|
-
error: `Error when trying to use ${
|
|
202
|
+
error: `Error when trying to use ${addr} with config: ${JSON.stringify({
|
|
192
203
|
method: method,
|
|
193
204
|
params: params,
|
|
194
205
|
})} resulting in error: ${error?.message}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-capability.configure-config.d.ts","sourceRoot":"","sources":["../../../../src/capabilities-execute/interfaces/o-capability.configure-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE;YACf,KAAK,EAAE,MAAM,EAAE,CAAC;YAChB,OAAO,EAAE;gBAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;aAAE,CAAC;SACrC,CAAC;QACF,UAAU,EAAE;YACV,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,EAAE,GAAG,CAAC;SACb,CAAC;KACH,CAAC;CACH"}
|
|
1
|
+
{"version":3,"file":"o-capability.configure-config.d.ts","sourceRoot":"","sources":["../../../../src/capabilities-execute/interfaces/o-capability.configure-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE;YACf,KAAK,EAAE,MAAM,EAAE,CAAC;YAChB,OAAO,EAAE;gBAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;aAAE,CAAC;SACrC,CAAC;QACF,UAAU,EAAE;YACV,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,EAAE,GAAG,CAAC;SACb,CAAC;QACF,IAAI,CAAC,EAAE;YACL,OAAO,EAAE,MAAM,CAAC;YAChB,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC;KACH,CAAC;CACH"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './o-lane.tool.js';
|
|
|
7
7
|
export * from './capabilities/index.js';
|
|
8
8
|
export * from './intent/index.js';
|
|
9
9
|
export * from './capabilities-all/o-capability.all.js';
|
|
10
|
+
export * from './capabilities-execute/execute.capability.js';
|
|
10
11
|
export * from './capabilities-evaluate/o-capability.evaluate.js';
|
|
11
12
|
export * from './capabilities-multiple-step/o-capability.multiple-step.js';
|
|
12
13
|
export * from './capabilities-search/o-capability.search.js';
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wCAAwC,CAAC;AACvD,cAAc,kDAAkD,CAAC;AACjE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,8CAA8C,CAAC;AAC7D,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wCAAwC,CAAC;AACvD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,kDAAkD,CAAC;AACjE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,8CAA8C,CAAC;AAC7D,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export * from './o-lane.tool.js';
|
|
|
7
7
|
export * from './capabilities/index.js';
|
|
8
8
|
export * from './intent/index.js';
|
|
9
9
|
export * from './capabilities-all/o-capability.all.js';
|
|
10
|
+
export * from './capabilities-execute/execute.capability.js';
|
|
10
11
|
export * from './capabilities-evaluate/o-capability.evaluate.js';
|
|
11
12
|
export * from './capabilities-multiple-step/o-capability.multiple-step.js';
|
|
12
13
|
export * from './capabilities-search/o-capability.search.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute-capability-address.spec.d.ts","sourceRoot":"","sources":["../../test/execute-capability-address.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { oCapabilityConfig } from '../src/capabilities/o-capability.config.js';
|
|
3
|
+
import { oCapabilityExecute } from '../src/capabilities-execute/execute.capability.js';
|
|
4
|
+
import { oIntent } from '../src/intent/o-intent.js';
|
|
5
|
+
/**
|
|
6
|
+
* Tests the interface contract between EVALUATE results and the EXECUTE capability.
|
|
7
|
+
*
|
|
8
|
+
* When EVALUATE's AI returns type:"execute", the response may place the address
|
|
9
|
+
* either at the root level or nested inside a `task` object. resultToConfig()
|
|
10
|
+
* passes the AI result as `params`, so the execute capability must handle both shapes.
|
|
11
|
+
*/
|
|
12
|
+
describe('EVALUATE → EXECUTE handoff: address resolution', () => {
|
|
13
|
+
// Minimal stub that satisfies oToolBase enough for oCapabilityConfig
|
|
14
|
+
const stubNode = {};
|
|
15
|
+
const stubPromptLoader = {};
|
|
16
|
+
const intent = new oIntent({ intent: 'test intent' });
|
|
17
|
+
/**
|
|
18
|
+
* Simulates what resultToConfig() does: it takes the AI result object
|
|
19
|
+
* and sets it as `params` on the next capability's config.
|
|
20
|
+
*/
|
|
21
|
+
function simulateResultToConfig(aiResult) {
|
|
22
|
+
const obj = aiResult;
|
|
23
|
+
return oCapabilityConfig.fromJSON({
|
|
24
|
+
params: typeof obj === 'object' ? obj : {},
|
|
25
|
+
intent,
|
|
26
|
+
node: stubNode,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Creates an oCapabilityExecute instance and sets its config,
|
|
31
|
+
* then calls the private resolveAddress() via the prototype.
|
|
32
|
+
*/
|
|
33
|
+
function resolveAddressFrom(config) {
|
|
34
|
+
const capability = new oCapabilityExecute({
|
|
35
|
+
promptLoader: stubPromptLoader,
|
|
36
|
+
node: stubNode,
|
|
37
|
+
});
|
|
38
|
+
// Set config as execute() would
|
|
39
|
+
capability.config = config;
|
|
40
|
+
// Call private method
|
|
41
|
+
return capability.resolveAddress();
|
|
42
|
+
}
|
|
43
|
+
describe('resolveAddress()', () => {
|
|
44
|
+
it('should resolve address from params.address (flat AI response)', () => {
|
|
45
|
+
const aiResult = {
|
|
46
|
+
type: 'execute',
|
|
47
|
+
address: 'o://search',
|
|
48
|
+
summary: 'Searching for something',
|
|
49
|
+
reasoning: 'User wants to search',
|
|
50
|
+
};
|
|
51
|
+
const config = simulateResultToConfig(aiResult);
|
|
52
|
+
const address = resolveAddressFrom(config);
|
|
53
|
+
expect(address).to.equal('o://search');
|
|
54
|
+
});
|
|
55
|
+
it('should resolve address from params.task.address (nested AI response)', () => {
|
|
56
|
+
const aiResult = {
|
|
57
|
+
type: 'execute',
|
|
58
|
+
task: {
|
|
59
|
+
address: 'o://search',
|
|
60
|
+
intent: 'Search for card feed refresh functionality',
|
|
61
|
+
},
|
|
62
|
+
summary: 'Searching for card feed refresh functionality',
|
|
63
|
+
reasoning: 'The intent mentions refreshing',
|
|
64
|
+
};
|
|
65
|
+
const config = simulateResultToConfig(aiResult);
|
|
66
|
+
const address = resolveAddressFrom(config);
|
|
67
|
+
expect(address).to.equal('o://search');
|
|
68
|
+
});
|
|
69
|
+
it('should prefer params.address over params.task.address when both exist', () => {
|
|
70
|
+
const aiResult = {
|
|
71
|
+
type: 'execute',
|
|
72
|
+
address: 'o://primary',
|
|
73
|
+
task: {
|
|
74
|
+
address: 'o://fallback',
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
const config = simulateResultToConfig(aiResult);
|
|
78
|
+
const address = resolveAddressFrom(config);
|
|
79
|
+
expect(address).to.equal('o://primary');
|
|
80
|
+
});
|
|
81
|
+
it('should throw when neither address location is present', () => {
|
|
82
|
+
const aiResult = {
|
|
83
|
+
type: 'execute',
|
|
84
|
+
summary: 'Missing address entirely',
|
|
85
|
+
reasoning: 'Bad AI response',
|
|
86
|
+
};
|
|
87
|
+
const config = simulateResultToConfig(aiResult);
|
|
88
|
+
expect(() => resolveAddressFrom(config)).to.throw('Execute capability requires a valid address');
|
|
89
|
+
});
|
|
90
|
+
it('should throw when address is not a string', () => {
|
|
91
|
+
const aiResult = {
|
|
92
|
+
type: 'execute',
|
|
93
|
+
address: 123,
|
|
94
|
+
};
|
|
95
|
+
const config = simulateResultToConfig(aiResult);
|
|
96
|
+
expect(() => resolveAddressFrom(config)).to.throw('Execute capability requires a valid address');
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe('resultToConfig() params shape', () => {
|
|
100
|
+
it('should pass AI result object as params', () => {
|
|
101
|
+
const aiResult = {
|
|
102
|
+
type: 'execute',
|
|
103
|
+
address: 'o://search',
|
|
104
|
+
task: { address: 'o://search', intent: 'find things' },
|
|
105
|
+
summary: 'test',
|
|
106
|
+
};
|
|
107
|
+
const config = simulateResultToConfig(aiResult);
|
|
108
|
+
expect(config.params).to.deep.equal(aiResult);
|
|
109
|
+
});
|
|
110
|
+
it('should set params to empty object for non-object results', () => {
|
|
111
|
+
const config = simulateResultToConfig('not an object');
|
|
112
|
+
expect(config.params).to.deep.equal({});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olane/o-lane",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@eslint/eslintrc": "^3.3.1",
|
|
38
38
|
"@eslint/js": "^9.29.0",
|
|
39
|
-
"@olane/o-test": "0.8.
|
|
39
|
+
"@olane/o-test": "0.8.4",
|
|
40
40
|
"@tsconfig/node20": "^20.1.6",
|
|
41
41
|
"@types/handlebars": "^4.1.0",
|
|
42
42
|
"@types/jest": "^30.0.0",
|
|
@@ -57,15 +57,15 @@
|
|
|
57
57
|
"typescript": "5.4.5"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@olane/o-config": "0.8.
|
|
61
|
-
"@olane/o-core": "0.8.
|
|
62
|
-
"@olane/o-node": "0.8.
|
|
63
|
-
"@olane/o-protocol": "0.8.
|
|
64
|
-
"@olane/o-storage": "0.8.
|
|
65
|
-
"@olane/o-tool": "0.8.
|
|
60
|
+
"@olane/o-config": "0.8.4",
|
|
61
|
+
"@olane/o-core": "0.8.4",
|
|
62
|
+
"@olane/o-node": "0.8.4",
|
|
63
|
+
"@olane/o-protocol": "0.8.4",
|
|
64
|
+
"@olane/o-storage": "0.8.4",
|
|
65
|
+
"@olane/o-tool": "0.8.4",
|
|
66
66
|
"debug": "^4.4.1",
|
|
67
67
|
"dotenv": "^16.5.0",
|
|
68
68
|
"handlebars": "^4.7.8"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "b53623b1ad4365133911722f80d5597a72b65bf2"
|
|
71
71
|
}
|