@olane/o-lane 0.8.2 → 0.8.3
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/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/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
|
@@ -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"}
|
|
@@ -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.3",
|
|
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.3",
|
|
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.3",
|
|
61
|
+
"@olane/o-core": "0.8.3",
|
|
62
|
+
"@olane/o-node": "0.8.3",
|
|
63
|
+
"@olane/o-protocol": "0.8.3",
|
|
64
|
+
"@olane/o-storage": "0.8.3",
|
|
65
|
+
"@olane/o-tool": "0.8.3",
|
|
66
66
|
"debug": "^4.4.1",
|
|
67
67
|
"dotenv": "^16.5.0",
|
|
68
68
|
"handlebars": "^4.7.8"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "189c0cf7b6dd9d5d961f5424af21d37978092d9e"
|
|
71
71
|
}
|