@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.
@@ -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;IAEK,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;CA8NxC"}
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.config.params.address,
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.config.params.address), {
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.config.params.address), {
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
- this.logger.error('Failed to execute during replay:', `Error when trying to use ${this.config?.params?.address} with config: ${JSON.stringify(taskConfig)} resulting in error: ${error?.message}`);
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 ${this.config?.params?.address} with config: ${JSON.stringify(taskConfig)} resulting in error: ${error?.message}`,
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.config.params.address,
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.config.params.address), {
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.config.params.address,
177
+ address: this.resolveAddress(),
168
178
  response: taskResponse.result,
169
179
  },
170
180
  shouldPersist,
171
181
  });
172
182
  }
173
183
  catch (error) {
174
- this.logger.error('Failed to execute:', `Error when trying to use ${this.config?.params?.address} with config: ${JSON.stringify({
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 ${this.config?.params?.address} with config: ${JSON.stringify({
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}`,
@@ -14,6 +14,10 @@ export interface oCapabilityExecuteConfig extends oCapabilityConfig {
14
14
  method: string;
15
15
  params: any;
16
16
  };
17
+ task?: {
18
+ address: string;
19
+ intent?: string;
20
+ };
17
21
  };
18
22
  }
19
23
  //# sourceMappingURL=o-capability.configure-config.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=execute-capability-address.spec.d.ts.map
@@ -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.2",
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.2",
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.2",
61
- "@olane/o-core": "0.8.2",
62
- "@olane/o-node": "0.8.2",
63
- "@olane/o-protocol": "0.8.2",
64
- "@olane/o-storage": "0.8.2",
65
- "@olane/o-tool": "0.8.2",
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": "9e35c874d849d051bcffe483fd2a8c2b3ecf68cc"
70
+ "gitHead": "189c0cf7b6dd9d5d961f5424af21d37978092d9e"
71
71
  }