@olane/o-lane 0.7.12-alpha.9 → 0.7.12
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/enums/o-capability.type-enum.d.ts +1 -0
- package/dist/src/capabilities/enums/o-capability.type-enum.d.ts.map +1 -1
- package/dist/src/capabilities/enums/o-capability.type-enum.js +1 -0
- package/dist/src/capabilities/interfaces/o-capability.config.d.ts +4 -2
- package/dist/src/capabilities/interfaces/o-capability.config.d.ts.map +1 -1
- package/dist/src/capabilities/interfaces/o-capability.result-interface.d.ts +1 -0
- package/dist/src/capabilities/interfaces/o-capability.result-interface.d.ts.map +1 -1
- package/dist/src/capabilities/o-capability.d.ts +3 -2
- package/dist/src/capabilities/o-capability.d.ts.map +1 -1
- package/dist/src/capabilities/o-capability.intelligence.d.ts.map +1 -1
- package/dist/src/capabilities/o-capability.intelligence.js +33 -8
- package/dist/src/capabilities/o-capability.js +3 -0
- package/dist/src/capabilities/o-capability.result.d.ts +2 -0
- package/dist/src/capabilities/o-capability.result.d.ts.map +1 -1
- package/dist/src/capabilities/o-capability.result.js +2 -0
- package/dist/src/capabilities/utils/result-stream-parser.d.ts +37 -0
- package/dist/src/capabilities/utils/result-stream-parser.d.ts.map +1 -0
- package/dist/src/capabilities/utils/result-stream-parser.js +90 -0
- package/dist/src/capabilities-multiple-step/interfaces/o-capability.multiple-step-config.d.ts +1 -0
- package/dist/src/capabilities-multiple-step/interfaces/o-capability.multiple-step-config.d.ts.map +1 -1
- package/dist/src/capabilities-multiple-step/o-capability.multiple-step.d.ts +2 -0
- package/dist/src/capabilities-multiple-step/o-capability.multiple-step.d.ts.map +1 -1
- package/dist/src/capabilities-multiple-step/o-capability.multiple-step.js +12 -0
- package/dist/src/capabilities-search/interfaces/o-capability.search-config.d.ts +1 -0
- package/dist/src/capabilities-search/interfaces/o-capability.search-config.d.ts.map +1 -1
- package/dist/src/capabilities-search/o-capability.search.d.ts.map +1 -1
- package/dist/src/capabilities-search/o-capability.search.js +24 -6
- package/dist/src/capabilities-task/interfaces/o-capability.task-config.d.ts +1 -0
- package/dist/src/capabilities-task/interfaces/o-capability.task-config.d.ts.map +1 -1
- package/dist/src/capabilities-task/o-capability.task.d.ts.map +1 -1
- package/dist/src/capabilities-task/o-capability.task.js +4 -0
- package/dist/src/errors/capability-errors.d.ts +71 -0
- package/dist/src/errors/capability-errors.d.ts.map +1 -0
- package/dist/src/errors/capability-errors.js +142 -0
- package/dist/src/errors/index.d.ts +5 -0
- package/dist/src/errors/index.d.ts.map +1 -0
- package/dist/src/errors/index.js +4 -0
- package/dist/src/formatters/index.d.ts +7 -0
- package/dist/src/formatters/index.d.ts.map +1 -0
- package/dist/src/formatters/index.js +6 -0
- package/dist/src/formatters/markdown-builder.d.ts +65 -0
- package/dist/src/formatters/markdown-builder.d.ts.map +1 -0
- package/dist/src/formatters/markdown-builder.js +120 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/interfaces/o-lane.config.d.ts +5 -2
- package/dist/src/interfaces/o-lane.config.d.ts.map +1 -1
- package/dist/src/o-lane.d.ts +8 -1
- package/dist/src/o-lane.d.ts.map +1 -1
- package/dist/src/o-lane.js +165 -23
- package/dist/src/o-lane.mixin.d.ts +17 -0
- package/dist/src/o-lane.mixin.d.ts.map +1 -0
- package/dist/src/o-lane.mixin.js +136 -0
- package/dist/src/o-lane.tool.d.ts +12 -19
- package/dist/src/o-lane.tool.d.ts.map +1 -1
- package/dist/src/o-lane.tool.js +11 -93
- package/dist/src/prompts/agent.prompt.d.ts +11 -0
- package/dist/src/prompts/agent.prompt.d.ts.map +1 -1
- package/dist/src/prompts/agent.prompt.js +34 -10
- package/dist/src/prompts/configure.prompt.d.ts +7 -0
- package/dist/src/prompts/configure.prompt.d.ts.map +1 -1
- package/dist/src/prompts/configure.prompt.js +8 -1
- package/dist/src/prompts/custom.prompt.d.ts +7 -0
- package/dist/src/prompts/custom.prompt.d.ts.map +1 -1
- package/dist/src/prompts/custom.prompt.js +77 -0
- package/dist/src/storage/index.d.ts +8 -0
- package/dist/src/storage/index.d.ts.map +1 -0
- package/dist/src/storage/index.js +12 -0
- package/dist/src/storage/interfaces/prompt-storage.interface.d.ts +102 -0
- package/dist/src/storage/interfaces/prompt-storage.interface.d.ts.map +1 -0
- package/dist/src/storage/interfaces/prompt-storage.interface.js +1 -0
- package/dist/src/storage/methods/prompt-storage.methods.d.ts +9 -0
- package/dist/src/storage/methods/prompt-storage.methods.d.ts.map +1 -0
- package/dist/src/storage/methods/prompt-storage.methods.js +338 -0
- package/dist/src/storage/prompt-loader.d.ts +40 -0
- package/dist/src/storage/prompt-loader.d.ts.map +1 -0
- package/dist/src/storage/prompt-loader.js +126 -0
- package/dist/src/storage/prompt-schema.d.ts +42 -0
- package/dist/src/storage/prompt-schema.d.ts.map +1 -0
- package/dist/src/storage/prompt-schema.js +29 -0
- package/dist/src/storage/prompt-seeder.d.ts +42 -0
- package/dist/src/storage/prompt-seeder.d.ts.map +1 -0
- package/dist/src/storage/prompt-seeder.js +141 -0
- package/dist/src/storage/prompt-storage-provider.tool.d.ts +99 -0
- package/dist/src/storage/prompt-storage-provider.tool.d.ts.map +1 -0
- package/dist/src/storage/prompt-storage-provider.tool.js +320 -0
- package/dist/test/prompt-seeder.spec.d.ts +2 -0
- package/dist/test/prompt-seeder.spec.d.ts.map +1 -0
- package/dist/test/prompt-seeder.spec.js +254 -0
- package/dist/test/prompt-storage-provider.spec.d.ts +2 -0
- package/dist/test/prompt-storage-provider.spec.d.ts.map +1 -0
- package/dist/test/prompt-storage-provider.spec.js +456 -0
- package/package.json +10 -7
- package/dist/test/ai.spec.d.ts +0 -2
- package/dist/test/ai.spec.d.ts.map +0 -1
- package/dist/test/ai.spec.js +0 -19
package/dist/src/o-lane.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { oAddress, oError, oErrorCodes, NodeState, oObject, } from '@olane/o-core';
|
|
1
|
+
import { oAddress, oError, oErrorCodes, NodeState, oObject, oResponse, } from '@olane/o-core';
|
|
2
2
|
import { CID } from 'multiformats';
|
|
3
3
|
import * as json from 'multiformats/codecs/json';
|
|
4
4
|
import { sha256 } from 'multiformats/hashes/sha2';
|
|
@@ -7,6 +7,7 @@ import { oIntentEncoder } from './intent-encoder/index.js';
|
|
|
7
7
|
import { oLaneStatus } from './enum/o-lane.status-enum.js';
|
|
8
8
|
import { oCapabilityResult, oCapabilityType, } from './capabilities/index.js';
|
|
9
9
|
import { ALL_CAPABILITIES } from './capabilities-all/o-capability.all.js';
|
|
10
|
+
import { MarkdownBuilder } from './formatters/index.js';
|
|
10
11
|
export class oLane extends oObject {
|
|
11
12
|
constructor(config) {
|
|
12
13
|
super('o-lane:' + `[${config.intent.value}]`);
|
|
@@ -18,6 +19,7 @@ export class oLane extends oObject {
|
|
|
18
19
|
this.sequence = Object.assign([], this.config.sequence || []);
|
|
19
20
|
this.parentLaneId = this.config.parentLaneId;
|
|
20
21
|
this.intentEncoder = new oIntentEncoder();
|
|
22
|
+
this.onChunk = this.config.onChunk;
|
|
21
23
|
// set a max cycles if one is not provided
|
|
22
24
|
if (!!process.env.MAX_CYCLES) {
|
|
23
25
|
this.MAX_CYCLES = parseInt(process.env.MAX_CYCLES);
|
|
@@ -84,42 +86,142 @@ export class oLane extends oObject {
|
|
|
84
86
|
}
|
|
85
87
|
get agentHistory() {
|
|
86
88
|
const added = {};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
const MAX_RESULT_LENGTH = 1000; // Truncate large results
|
|
90
|
+
const KEEP_FULL_DETAIL_COUNT = 3; // Keep full detail for last N cycles
|
|
91
|
+
const filteredSequence = this.sequence?.filter((s) => {
|
|
89
92
|
if (added[s.id]) {
|
|
90
93
|
return false;
|
|
91
94
|
}
|
|
92
95
|
added[s.id] = true;
|
|
93
96
|
return true;
|
|
94
|
-
})
|
|
97
|
+
});
|
|
98
|
+
return (filteredSequence
|
|
95
99
|
?.map((s, index) => {
|
|
100
|
+
const isRecent = index >= filteredSequence.length - KEEP_FULL_DETAIL_COUNT;
|
|
96
101
|
const result = s.result || s.error;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
const params = s.config?.params || {};
|
|
103
|
+
// Extract summary and reasoning if available
|
|
104
|
+
const summary = params.summary || '';
|
|
105
|
+
const reasoning = params.reasoning || '';
|
|
106
|
+
// Format result, truncating if not a recent cycle
|
|
107
|
+
let formattedResult;
|
|
108
|
+
if (typeof result === 'string') {
|
|
109
|
+
formattedResult =
|
|
110
|
+
isRecent || result.length <= MAX_RESULT_LENGTH
|
|
111
|
+
? result
|
|
112
|
+
: result.substring(0, MAX_RESULT_LENGTH) + '... (truncated)';
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const jsonStr = JSON.stringify(result, null, 2);
|
|
116
|
+
formattedResult =
|
|
117
|
+
isRecent || jsonStr.length <= MAX_RESULT_LENGTH
|
|
118
|
+
? jsonStr
|
|
119
|
+
: jsonStr.substring(0, MAX_RESULT_LENGTH) + '... (truncated)';
|
|
120
|
+
}
|
|
121
|
+
// Build formatted history entry
|
|
122
|
+
let entry = `[Cycle ${index + 1}: ${s.type}]\n`;
|
|
123
|
+
entry += `Intent: ${s.config?.intent.toString()}\n`;
|
|
124
|
+
if (summary) {
|
|
125
|
+
entry += `Summary: ${summary}\n`;
|
|
126
|
+
}
|
|
127
|
+
if (reasoning) {
|
|
128
|
+
entry += `Reasoning: ${reasoning}\n`;
|
|
129
|
+
}
|
|
130
|
+
if (s.error) {
|
|
131
|
+
entry += `Error: ${s.error}\n`;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
entry += `Result: ${formattedResult}\n`;
|
|
135
|
+
}
|
|
136
|
+
return entry;
|
|
105
137
|
})
|
|
106
138
|
.join('\n') || '');
|
|
107
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Generate a human-readable execution trace of the lane
|
|
142
|
+
* Shows the decision points and flow of execution
|
|
143
|
+
*/
|
|
144
|
+
getExecutionTrace() {
|
|
145
|
+
const mb = MarkdownBuilder.create();
|
|
146
|
+
mb.header('Execution Trace', 2);
|
|
147
|
+
mb.paragraph(`Intent: ${this.config.intent.value}`);
|
|
148
|
+
mb.paragraph(`Cycles: ${this.sequence.length}`);
|
|
149
|
+
mb.paragraph(`Status: ${this.status}`);
|
|
150
|
+
if (this.sequence.length === 0) {
|
|
151
|
+
mb.paragraph('No execution cycles recorded.');
|
|
152
|
+
return mb.build();
|
|
153
|
+
}
|
|
154
|
+
mb.br();
|
|
155
|
+
mb.header('Cycle Details', 3);
|
|
156
|
+
this.sequence.forEach((step, index) => {
|
|
157
|
+
const params = step.config?.params || {};
|
|
158
|
+
const summary = params.summary || '';
|
|
159
|
+
const reasoning = params.reasoning || '';
|
|
160
|
+
mb.br();
|
|
161
|
+
mb.raw(`${mb.bold(`Cycle ${index + 1}`)} [${step.type}]`);
|
|
162
|
+
if (summary) {
|
|
163
|
+
mb.raw(`\n└─ ${mb.italic('Summary:')} ${summary}`);
|
|
164
|
+
}
|
|
165
|
+
if (reasoning) {
|
|
166
|
+
mb.raw(`\n└─ ${mb.italic('Reasoning:')} ${reasoning}`);
|
|
167
|
+
}
|
|
168
|
+
if (step.error) {
|
|
169
|
+
mb.raw(`\n└─ ❌ ${mb.bold('Error:')} ${step.error}`);
|
|
170
|
+
}
|
|
171
|
+
else if (step.type === oCapabilityType.STOP) {
|
|
172
|
+
mb.raw(`\n└─ ✓ ${mb.bold('Completed')}`);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
// Add final result summary
|
|
176
|
+
if (this.result) {
|
|
177
|
+
mb.br();
|
|
178
|
+
mb.hr();
|
|
179
|
+
mb.header('Final Result', 3);
|
|
180
|
+
const resultParams = this.result.config?.params || {};
|
|
181
|
+
const finalSummary = resultParams.summary || '';
|
|
182
|
+
if (finalSummary) {
|
|
183
|
+
mb.paragraph(finalSummary);
|
|
184
|
+
}
|
|
185
|
+
if (this.result.error) {
|
|
186
|
+
mb.paragraph(`${mb.bold('Status:')} Failed`);
|
|
187
|
+
mb.paragraph(`${mb.bold('Error:')} ${this.result.error}`);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
mb.paragraph(`${mb.bold('Status:')} Success`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return mb.build();
|
|
194
|
+
}
|
|
108
195
|
async preflight() {
|
|
109
196
|
this.logger.debug('Preflight...');
|
|
110
197
|
this.status = oLaneStatus.PREFLIGHT;
|
|
198
|
+
this.logger.debug('Pinging intelligence tool...');
|
|
199
|
+
// ping the intelligence tool to ensure it is available
|
|
200
|
+
await this.node.use(new oAddress('o://intelligence'), {
|
|
201
|
+
method: 'ping',
|
|
202
|
+
params: {},
|
|
203
|
+
});
|
|
111
204
|
}
|
|
112
205
|
async execute() {
|
|
113
206
|
this.logger.debug('Executing...');
|
|
114
|
-
await this.preflight();
|
|
115
|
-
this.status = oLaneStatus.RUNNING;
|
|
116
207
|
try {
|
|
208
|
+
await this.preflight().catch((error) => {
|
|
209
|
+
this.logger.error('Error in preflight: ', error);
|
|
210
|
+
this.result = new oCapabilityResult({
|
|
211
|
+
type: oCapabilityType.ERROR,
|
|
212
|
+
result: null,
|
|
213
|
+
error: 'Intelligence services are not available. Try again later.',
|
|
214
|
+
});
|
|
215
|
+
throw new oError(oErrorCodes.INVALID_STATE, 'Intelligence services are not available. Try again later.');
|
|
216
|
+
});
|
|
217
|
+
this.status = oLaneStatus.RUNNING;
|
|
117
218
|
this.result = await this.loop();
|
|
118
219
|
}
|
|
119
220
|
catch (error) {
|
|
120
221
|
this.logger.error('Error in execute: ', error);
|
|
121
222
|
this.status = oLaneStatus.FAILED;
|
|
122
223
|
}
|
|
224
|
+
this.logger.debug('Completed loop...');
|
|
123
225
|
await this.postflight(this.result);
|
|
124
226
|
this.status = oLaneStatus.COMPLETED;
|
|
125
227
|
return this.result;
|
|
@@ -137,19 +239,32 @@ export class oLane extends oObject {
|
|
|
137
239
|
...this.config,
|
|
138
240
|
sequence: this.sequence, // pass the full sequence to the next capability
|
|
139
241
|
},
|
|
242
|
+
useStream: this.config.useStream || false,
|
|
140
243
|
};
|
|
141
244
|
}
|
|
142
245
|
async doCapability(currentStep) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
246
|
+
try {
|
|
247
|
+
const capabilityType = currentStep.type;
|
|
248
|
+
for (const capability of this.capabilities) {
|
|
249
|
+
if (capability.type === capabilityType && currentStep.config) {
|
|
250
|
+
const capabilityConfig = this.resultToConfig(currentStep);
|
|
251
|
+
this.logger.debug('Executing capability: ', capabilityType);
|
|
252
|
+
const result = await capability.execute({
|
|
253
|
+
...capabilityConfig,
|
|
254
|
+
});
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
151
257
|
}
|
|
152
258
|
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
this.logger.error('Error in doCapability: ', error);
|
|
261
|
+
const errorResult = new oCapabilityResult({
|
|
262
|
+
type: oCapabilityType.ERROR,
|
|
263
|
+
result: null,
|
|
264
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
265
|
+
});
|
|
266
|
+
return errorResult;
|
|
267
|
+
}
|
|
153
268
|
throw new oError(oErrorCodes.INVALID_CAPABILITY, 'Unknown capability');
|
|
154
269
|
}
|
|
155
270
|
async loop() {
|
|
@@ -181,6 +296,12 @@ export class oLane extends oObject {
|
|
|
181
296
|
this.logger.debug('Capability result flagged for persistence - automatically setting persistToConfig');
|
|
182
297
|
this.config.persistToConfig = true;
|
|
183
298
|
}
|
|
299
|
+
await this.emitNonFinalChunk(result, {
|
|
300
|
+
data: {
|
|
301
|
+
...result,
|
|
302
|
+
config: undefined,
|
|
303
|
+
},
|
|
304
|
+
});
|
|
184
305
|
if (result.type === oCapabilityType.STOP) {
|
|
185
306
|
return result;
|
|
186
307
|
}
|
|
@@ -189,6 +310,18 @@ export class oLane extends oObject {
|
|
|
189
310
|
}
|
|
190
311
|
throw new Error('Plan failed');
|
|
191
312
|
}
|
|
313
|
+
async emitNonFinalChunk(result, payload) {
|
|
314
|
+
if (this.config.useStream && this.onChunk) {
|
|
315
|
+
await this.onChunk(new oResponse({
|
|
316
|
+
...payload,
|
|
317
|
+
_last: false,
|
|
318
|
+
_isStreaming: true,
|
|
319
|
+
_connectionId: this.node.address.toString(),
|
|
320
|
+
_requestMethod: 'unknown',
|
|
321
|
+
id: this.config.requestId ?? uuidv4(), // Use request ID for proper correlation, fallback to UUID
|
|
322
|
+
}));
|
|
323
|
+
}
|
|
324
|
+
}
|
|
192
325
|
async postflight(response) {
|
|
193
326
|
this.logger.debug('Postflight...');
|
|
194
327
|
this.status = oLaneStatus.POSTFLIGHT;
|
|
@@ -211,9 +344,14 @@ export class oLane extends oObject {
|
|
|
211
344
|
const data = response?.result;
|
|
212
345
|
if (data.addresses_to_index) {
|
|
213
346
|
for (const address of data.addresses_to_index) {
|
|
214
|
-
|
|
347
|
+
this.logger.debug('Indexing address: ', address.toString());
|
|
348
|
+
await this.node
|
|
349
|
+
.use(new oAddress(address), {
|
|
215
350
|
method: 'index_network',
|
|
216
351
|
params: {},
|
|
352
|
+
})
|
|
353
|
+
.catch((error) => {
|
|
354
|
+
this.logger.error('Error indexing address: ', error);
|
|
217
355
|
});
|
|
218
356
|
}
|
|
219
357
|
}
|
|
@@ -232,6 +370,10 @@ export class oLane extends oObject {
|
|
|
232
370
|
cancel() {
|
|
233
371
|
this.logger.debug('Cancelling lane...');
|
|
234
372
|
this.status = oLaneStatus.CANCELLED;
|
|
373
|
+
// tell all capabilities to cancel
|
|
374
|
+
for (const capability of this.capabilities) {
|
|
375
|
+
capability.cancel();
|
|
376
|
+
}
|
|
235
377
|
}
|
|
236
378
|
/**
|
|
237
379
|
* Replay a stored lane from storage by CID
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { oToolBase } from '@olane/o-tool';
|
|
2
|
+
/**
|
|
3
|
+
* withLane mixin - adds lane execution capabilities to any tool base class
|
|
4
|
+
* This mixin pattern allows lane functionality to be composed with different
|
|
5
|
+
* base classes (e.g., node-based, browser-based, or other implementations)
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // Apply to node-based tool
|
|
10
|
+
* export class oLaneTool extends withLane(oNodeTool) {}
|
|
11
|
+
*
|
|
12
|
+
* // Future: Apply to browser-based tool
|
|
13
|
+
* export class oBrowserLaneTool extends withLane(oBrowserTool) {}
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare function withLane<T extends new (...args: any[]) => oToolBase>(Base: T): T;
|
|
17
|
+
//# sourceMappingURL=o-lane.mixin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"o-lane.mixin.d.ts","sourceRoot":"","sources":["../../src/o-lane.mixin.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAQ1C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,SAAS,EAClE,IAAI,EAAE,CAAC,GACN,CAAC,CAiJH"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { CoreUtils, oAddress, oError, oErrorCodes, oResponse, } from '@olane/o-core';
|
|
2
|
+
import { oCapabilityType } from './capabilities/index.js';
|
|
3
|
+
import { oIntent } from './intent/index.js';
|
|
4
|
+
import { oLaneContext } from './o-lane.context.js';
|
|
5
|
+
import { oLaneManager } from './manager/o-lane.manager.js';
|
|
6
|
+
import { oCapabilityResult } from './capabilities/o-capability.result.js';
|
|
7
|
+
/**
|
|
8
|
+
* withLane mixin - adds lane execution capabilities to any tool base class
|
|
9
|
+
* This mixin pattern allows lane functionality to be composed with different
|
|
10
|
+
* base classes (e.g., node-based, browser-based, or other implementations)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Apply to node-based tool
|
|
15
|
+
* export class oLaneTool extends withLane(oNodeTool) {}
|
|
16
|
+
*
|
|
17
|
+
* // Future: Apply to browser-based tool
|
|
18
|
+
* export class oBrowserLaneTool extends withLane(oBrowserTool) {}
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function withLane(Base) {
|
|
22
|
+
return class extends Base {
|
|
23
|
+
constructor(...args) {
|
|
24
|
+
super(...args);
|
|
25
|
+
this.manager = new oLaneManager();
|
|
26
|
+
}
|
|
27
|
+
async _tool_handshake(handshake) {
|
|
28
|
+
this.logger.debug('Performing handshake with intent: ', handshake.params.intent);
|
|
29
|
+
let tools = await this.myTools();
|
|
30
|
+
let methods = this.methods;
|
|
31
|
+
const { tool } = handshake.params;
|
|
32
|
+
if (tool) {
|
|
33
|
+
tools = tools.filter((t) => t === tool);
|
|
34
|
+
methods = { tool: this.methods[tool] };
|
|
35
|
+
}
|
|
36
|
+
return new oCapabilityResult({
|
|
37
|
+
result: {
|
|
38
|
+
tools: tools.filter((t) => t !== 'handshake' && t !== 'intent'),
|
|
39
|
+
methods: methods,
|
|
40
|
+
},
|
|
41
|
+
type: oCapabilityType.HANDSHAKE,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Where all intents go to be resolved.
|
|
46
|
+
* @param request
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
async _tool_intent(request) {
|
|
50
|
+
this.logger.debug('Intent resolution called: ', request.params);
|
|
51
|
+
const { intent, context, streamTo, _isStreaming = false } = request.params;
|
|
52
|
+
const pc = await this.manager.createLane({
|
|
53
|
+
intent: new oIntent({ intent: intent }),
|
|
54
|
+
currentNode: this,
|
|
55
|
+
caller: this.address,
|
|
56
|
+
streamTo: streamTo ? new oAddress(streamTo) : undefined,
|
|
57
|
+
useStream: _isStreaming,
|
|
58
|
+
requestId: request.id, // Pass request ID for proper response correlation
|
|
59
|
+
onChunk: _isStreaming
|
|
60
|
+
? async (chunk) => {
|
|
61
|
+
if (chunk?._last ||
|
|
62
|
+
chunk?.result?._last ||
|
|
63
|
+
chunk?.result?.data?._last) {
|
|
64
|
+
this.logger.error('UNEXPECTED LAST CHUNK RECEIVED', JSON.stringify(chunk, null, 2));
|
|
65
|
+
throw new oError(oErrorCodes.INVALID_ACTION, 'Misbehaving client sent unexpected last chunk');
|
|
66
|
+
}
|
|
67
|
+
await CoreUtils.sendStreamResponse(oResponse.fromJSON(chunk), request.stream);
|
|
68
|
+
}
|
|
69
|
+
: undefined,
|
|
70
|
+
context: context
|
|
71
|
+
? new oLaneContext([
|
|
72
|
+
`[Chat History Context Begin]\n${context}\n[Chat History Context End]`,
|
|
73
|
+
])
|
|
74
|
+
: undefined,
|
|
75
|
+
});
|
|
76
|
+
// TODO: brendon experiment review
|
|
77
|
+
// stream.addEventListener('close', () => {
|
|
78
|
+
// this.logger.debug('Stream closed, cancelling lane for intent:', intent);
|
|
79
|
+
// pc.cancel();
|
|
80
|
+
// });
|
|
81
|
+
let response;
|
|
82
|
+
response = await pc.execute();
|
|
83
|
+
const completeResponse = {
|
|
84
|
+
result: response?.result,
|
|
85
|
+
humanResult: response?.humanResult, // Full human-readable formatted result (AI-generated markdown)
|
|
86
|
+
summary: response?.config?.params?.summary, // Short 1-2 sentence summary
|
|
87
|
+
error: response?.error,
|
|
88
|
+
cycles: pc.sequence.length,
|
|
89
|
+
cid: pc.cid?.toString(),
|
|
90
|
+
sequence: pc.sequence.map((s) => {
|
|
91
|
+
return s.result;
|
|
92
|
+
}),
|
|
93
|
+
};
|
|
94
|
+
await new Promise((resolve) => setTimeout(resolve, 3000)); // TODO: fix this: wait for 3 seconds to let the stream send 2 messages lol
|
|
95
|
+
console.log('completeResponse', completeResponse);
|
|
96
|
+
return completeResponse;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Replay a stored lane from storage by CID
|
|
100
|
+
* This restores network state from a previously executed lane
|
|
101
|
+
* @param request - Request containing the CID of the lane to replay
|
|
102
|
+
* @returns The result of the replayed lane
|
|
103
|
+
*/
|
|
104
|
+
async _tool_replay(request) {
|
|
105
|
+
this.logger.debug('Lane replay called: ', request.params);
|
|
106
|
+
const { cid } = request.params;
|
|
107
|
+
if (!cid || typeof cid !== 'string') {
|
|
108
|
+
throw new Error('CID parameter is required and must be a string');
|
|
109
|
+
}
|
|
110
|
+
// Create a lane instance for replay
|
|
111
|
+
const lane = await this.manager.createLane({
|
|
112
|
+
intent: new oIntent({ intent: 'replay' }),
|
|
113
|
+
currentNode: this,
|
|
114
|
+
caller: this.address,
|
|
115
|
+
});
|
|
116
|
+
try {
|
|
117
|
+
const response = await lane.replay(cid);
|
|
118
|
+
this.logger.debug('Lane replay response: ', response);
|
|
119
|
+
return {
|
|
120
|
+
result: response?.result,
|
|
121
|
+
error: response?.error,
|
|
122
|
+
cycles: lane.sequence.length,
|
|
123
|
+
cid: cid,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
this.logger.error('Lane replay failed: ', error);
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async teardown() {
|
|
132
|
+
await this.manager.teardown();
|
|
133
|
+
await super.teardown();
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
@@ -1,23 +1,16 @@
|
|
|
1
|
-
import { oRequest } from '@olane/o-core';
|
|
2
1
|
import { oNodeConfig, oNodeTool } from '@olane/o-node';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
declare const oLaneTool_base: typeof oNodeTool;
|
|
3
|
+
/**
|
|
4
|
+
* oLaneTool - Node-based tool with lane execution capabilities
|
|
5
|
+
* This class composes the withLane mixin with oNodeTool to provide
|
|
6
|
+
* a concrete implementation for node-based lane execution.
|
|
7
|
+
*
|
|
8
|
+
* All lane-specific functionality is provided by the withLane mixin,
|
|
9
|
+
* making this implementation backward compatible while enabling
|
|
10
|
+
* future flexibility to apply lane capabilities to other base classes.
|
|
11
|
+
*/
|
|
12
|
+
export declare class oLaneTool extends oLaneTool_base {
|
|
6
13
|
constructor(config: oNodeConfig);
|
|
7
|
-
_tool_handshake(handshake: oRequest): Promise<oHandshakeResult>;
|
|
8
|
-
/**
|
|
9
|
-
* Where all intents go to be resolved.
|
|
10
|
-
* @param request
|
|
11
|
-
* @returns
|
|
12
|
-
*/
|
|
13
|
-
_tool_intent(request: oRequest): Promise<any>;
|
|
14
|
-
/**
|
|
15
|
-
* Replay a stored lane from storage by CID
|
|
16
|
-
* This restores network state from a previously executed lane
|
|
17
|
-
* @param request - Request containing the CID of the lane to replay
|
|
18
|
-
* @returns The result of the replayed lane
|
|
19
|
-
*/
|
|
20
|
-
_tool_replay(request: oRequest): Promise<any>;
|
|
21
|
-
teardown(): Promise<void>;
|
|
22
14
|
}
|
|
15
|
+
export {};
|
|
23
16
|
//# sourceMappingURL=o-lane.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-lane.tool.d.ts","sourceRoot":"","sources":["../../src/o-lane.tool.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"o-lane.tool.d.ts","sourceRoot":"","sources":["../../src/o-lane.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;;AAGvD;;;;;;;;GAQG;AACH,qBAAa,SAAU,SAAQ,cAAmB;gBACpC,MAAM,EAAE,WAAW;CAGhC"}
|
package/dist/src/o-lane.tool.js
CHANGED
|
@@ -1,98 +1,16 @@
|
|
|
1
|
-
import { oAddress } from '@olane/o-core';
|
|
2
1
|
import { oNodeTool } from '@olane/o-node';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { withLane } from './o-lane.mixin.js';
|
|
3
|
+
/**
|
|
4
|
+
* oLaneTool - Node-based tool with lane execution capabilities
|
|
5
|
+
* This class composes the withLane mixin with oNodeTool to provide
|
|
6
|
+
* a concrete implementation for node-based lane execution.
|
|
7
|
+
*
|
|
8
|
+
* All lane-specific functionality is provided by the withLane mixin,
|
|
9
|
+
* making this implementation backward compatible while enabling
|
|
10
|
+
* future flexibility to apply lane capabilities to other base classes.
|
|
11
|
+
*/
|
|
12
|
+
export class oLaneTool extends withLane(oNodeTool) {
|
|
9
13
|
constructor(config) {
|
|
10
14
|
super(config);
|
|
11
|
-
this.manager = new oLaneManager();
|
|
12
|
-
}
|
|
13
|
-
async _tool_handshake(handshake) {
|
|
14
|
-
this.logger.debug('Performing handshake with intent: ', handshake.params.intent);
|
|
15
|
-
let tools = await this.myTools();
|
|
16
|
-
let methods = this.methods;
|
|
17
|
-
const { tool } = handshake.params;
|
|
18
|
-
if (tool) {
|
|
19
|
-
tools = tools.filter((t) => t === tool);
|
|
20
|
-
methods = { tool: this.methods[tool] };
|
|
21
|
-
}
|
|
22
|
-
return new oCapabilityResult({
|
|
23
|
-
result: {
|
|
24
|
-
tools: tools.filter((t) => t !== 'handshake' && t !== 'intent'),
|
|
25
|
-
methods: methods,
|
|
26
|
-
},
|
|
27
|
-
type: oCapabilityType.HANDSHAKE,
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Where all intents go to be resolved.
|
|
32
|
-
* @param request
|
|
33
|
-
* @returns
|
|
34
|
-
*/
|
|
35
|
-
async _tool_intent(request) {
|
|
36
|
-
this.logger.debug('Intent resolution called: ', request.params);
|
|
37
|
-
const { intent, context, streamTo } = request.params;
|
|
38
|
-
const pc = await this.manager.createLane({
|
|
39
|
-
intent: new oIntent({ intent: intent }),
|
|
40
|
-
currentNode: this,
|
|
41
|
-
caller: this.address,
|
|
42
|
-
streamTo: streamTo ? new oAddress(streamTo) : undefined,
|
|
43
|
-
context: context
|
|
44
|
-
? new oLaneContext([
|
|
45
|
-
`[Chat History Context Begin]\n${context}\n[Chat History Context End]`,
|
|
46
|
-
])
|
|
47
|
-
: undefined,
|
|
48
|
-
});
|
|
49
|
-
const response = await pc.execute();
|
|
50
|
-
this.logger.debug('Intent resolution response: ', response);
|
|
51
|
-
return {
|
|
52
|
-
result: response?.result,
|
|
53
|
-
error: response?.error,
|
|
54
|
-
cycles: pc.sequence.length,
|
|
55
|
-
cid: pc.cid?.toString(),
|
|
56
|
-
sequence: pc.sequence.map((s) => {
|
|
57
|
-
return s.result;
|
|
58
|
-
}),
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Replay a stored lane from storage by CID
|
|
63
|
-
* This restores network state from a previously executed lane
|
|
64
|
-
* @param request - Request containing the CID of the lane to replay
|
|
65
|
-
* @returns The result of the replayed lane
|
|
66
|
-
*/
|
|
67
|
-
async _tool_replay(request) {
|
|
68
|
-
this.logger.debug('Lane replay called: ', request.params);
|
|
69
|
-
const { cid } = request.params;
|
|
70
|
-
if (!cid || typeof cid !== 'string') {
|
|
71
|
-
throw new Error('CID parameter is required and must be a string');
|
|
72
|
-
}
|
|
73
|
-
// Create a lane instance for replay
|
|
74
|
-
const lane = await this.manager.createLane({
|
|
75
|
-
intent: new oIntent({ intent: 'replay' }),
|
|
76
|
-
currentNode: this,
|
|
77
|
-
caller: this.address,
|
|
78
|
-
});
|
|
79
|
-
try {
|
|
80
|
-
const response = await lane.replay(cid);
|
|
81
|
-
this.logger.debug('Lane replay response: ', response);
|
|
82
|
-
return {
|
|
83
|
-
result: response?.result,
|
|
84
|
-
error: response?.error,
|
|
85
|
-
cycles: lane.sequence.length,
|
|
86
|
-
cid: cid,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
this.logger.error('Lane replay failed: ', error);
|
|
91
|
-
throw error;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
async teardown() {
|
|
95
|
-
await this.manager.teardown();
|
|
96
|
-
await super.teardown();
|
|
97
15
|
}
|
|
98
16
|
}
|
|
@@ -1,2 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cycle instructions for seeding - extracted from agent workflow
|
|
3
|
+
*/
|
|
4
|
+
export declare const CYCLE_INSTRUCTIONS_SEED = "\n Every Step Instructions:\n1. Review the provided user intent, context and agent history\n2. If you can complete the user intent, return the \"Stop Response\" using the [RETURN INSTRUCTIONS] steps\n3. If the intent is already completed in past cycles, return the \"Stop Response\" using the [RETURN INSTRUCTIONS] steps\n4. If you experience 3 similar errors in a row, return the \"Stop Response\" indicating an error and follow the [RETURN INSTRUCTIONS] steps\n5. Review the current step number and perform the instructions associated with that step\n6. Start with step 1\n\nStep 1 - Evaluate the intent\n1. A complex step means there are multiple actions required to complete the user's intent\n2. If the intent is not-complex, continue to step 2\n3. If the intent is complex, break it up into a list of simple concise intents. Return the \"Complex Intent Response\" using the [RETURN INSTRUCTIONS]\n\nStep 2 - Search for tools and context\n1. If all entities and tool addresses are known within the user intent, continue to step 4\n2. If you know the tool address to use to complete the user intent, continue to step 4\n3. If there are unknown tool addresses or entities within the user intent, generate search queries to resolve the unknown entities. \n4. Use the o://mcp search tool to find model context protocol servers (MCP servers) that can help you add tooling that could help you complete the user intent.\n5. If there is a placeholder address used (o://.../placeholder), do not extract the contents of the placeholder address unless necessary for completing the user intent.\n6. Use the search results data & tooling to help you resolve the unknown entities.\n7. Continue to step 3.\n\nStep 3 - Filter Search Results\n1. If all search results are relevant to the user intent resolution, continue to step 4.\n2. Filter the search results for information that may contain supporting data or tooling that can help complete the user intent.\n3. If you do not see anything that can help you. Return the \"Stop Response\" using the [RETURN INSTRUCTIONS]\n4. Continue to step 4\n\nStep 4 - Configure the target tool address use\n1. Identify the tool address that most likely will help you complete the user intent.\n2. Review the provided context for past cycles that contain configuration instructions for the target tool address.\n3. If there is no configuration instructions for the target tool address, return the \"Configure Response\" using the [RETURN INSTRUCTIONS]\n4. Identify if there are any missing parameter values for the target tool address and search for them if so.\n5. If the tool use configuration is already known including all parameter values, continue to step 5\n\nStep 5 - Use target tool address\n1. If the target tool address configuration is known, return the \"Use Tool Response\" using the [RETURN INSTRUCTIONS]\n2. If the target tool address with the same configuration has failed in the past cycles, return the \"Error Response\" using the [RETURN INSTRUCTIONS] steps to indicate the error.\n3. Using this filtered tool list, return the \"Use Tool Response\" using the [RETURN INSTRUCTIONS] steps to return a series of addresses and respective intents to align with the current user intent resolution goal\n4. Continue to step 6\n\nStep 6 - Review the tool use results\n1. Analyze each tool use result\n2. When formatting tool results for the user in a Stop Response, present as clean markdown:\n - For general contexts, present as clean markdown:\n * Use headings to organize different sections\n * Use lists for multiple items\n * Use bold for important values or labels\n * Use code blocks for addresses (e.g., `o://tool-address`)\n * Transform raw JSON into readable prose and structured lists\n3. In the summary field, provide a 1-2 sentence overview\n4. If it failed, clearly explain why in a user-friendly way\n\n\n ";
|
|
5
|
+
/**
|
|
6
|
+
* Output instructions for seeding - extracted from return format specifications
|
|
7
|
+
*/
|
|
8
|
+
export declare const OUTPUT_INSTRUCTIONS_SEED = "\n[RETURN INSTRUCTIONS BEGIN]\nThese are the types of cycle responses: \"Complex Intent Response\", \"Search Response\", \"Use Tool Response\", \"Stop Response\", \"Error Response\", \"Configure Response\".\n\nAll Return Step Instructions:\n1. Do not explain your reasoning process, just return the output in the correct format.\n2. Determine what type of results we have\n3. Output the respective results using the matching output type.\n4. Generate a reasoning key value pair for why this result was returned.\n5. The reasoning should be no longer than 1 sentence.\n6. The summary should be a short message used to inform the user of the result of the cycle. These updates should be insightful and concise and within 1-2 sentences.\n6. Do not include ```json or ``` in your output.\n\nComplex Intent Results:\n{\n \"intents\": [\n \"simple intent 1\",\n \"simple intent 2\",\n \"simple intent 3\",\n ],\n \"summary\": string,\n \"reasoning\": string,\n \"type\": \"multiple_step\",\n}\n\nConfigure Response:\n{\n \"intent\": string,\n \"toolAddress\": string,\n \"reasoning\": string,\n \"summary\": string,\n \"type\": \"configure\",\n}\n\nSearch Response:\n{\n \"queries\": [\n {\n \"query\": \"vector database query key terms to search for\",\n \"limit\": number,\n }\n ],\n \"isExternal\": boolean,\n \"reasoning\": string,\n \"summary\": string,\n \"type\": \"search\",\n}\n\nStop Response:\n{\n \"result\": string, // IMPORTANT: Format this as clean, readable markdown. Use headers (##, ###), lists (-, 1.), bold (**text**), and code blocks (`code`) to make the response easy to read. Structure tool outputs, search results, and data clearly. Focus on what the user needs to know, not raw data dumps.\n \"reasoning\": string,\n \"addresses_to_index\": [string], // COMMENT: If the results of a tool use include \"address_to_index\", list them in the \"addresses_to_index\" array.\n \"summary\": string, // A concise 1-2 sentence summary for the user\n \"type\": \"stop\",\n}\n\nError Response:\n{\n \"result\": \"string explaining the error\",\n \"summary\": string,\n \"reasoning\": string,\n \"type\": \"evaluate\",\n}\n\nUse Tool Response:\n{\n \"task\": {\n \"address\": string,\n \"payload\": { \"method\": string, \"params\": any }\n },\n \"summary\": string,\n \"type\": \"task\",\n}\n[RETURN INSTRUCTIONS END]\n\n ";
|
|
9
|
+
/**
|
|
10
|
+
* Runtime agent prompt function with parameter interpolation
|
|
11
|
+
*/
|
|
1
12
|
export declare const AGENT_PROMPT: (intent: string, context: string, agentHistory: string, extraInstructions: string) => string;
|
|
2
13
|
//# sourceMappingURL=agent.prompt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.prompt.d.ts","sourceRoot":"","sources":["../../../src/prompts/agent.prompt.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,WACf,MAAM,WACL,MAAM,gBACD,MAAM,qBACD,MAAM,
|
|
1
|
+
{"version":3,"file":"agent.prompt.d.ts","sourceRoot":"","sources":["../../../src/prompts/agent.prompt.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,uBAAuB,izHAuDjC,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,wBAAwB,41EA4ElC,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,YAAY,WACf,MAAM,WACL,MAAM,gBACD,MAAM,qBACD,MAAM,WASxB,CAAC"}
|