@exaudeus/workrail 0.1.5 → 0.1.7
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 +10 -1
- package/dist/application/services/loop-context-optimizer.d.ts +8 -0
- package/dist/application/services/loop-context-optimizer.js +114 -0
- package/dist/application/services/loop-execution-context.d.ts +7 -2
- package/dist/application/services/loop-execution-context.js +85 -24
- package/dist/application/services/workflow-service.d.ts +3 -1
- package/dist/application/services/workflow-service.js +43 -12
- package/dist/container.d.ts +2 -0
- package/dist/container.js +4 -1
- package/dist/types/loop-context-optimizer.d.ts +7 -0
- package/dist/types/loop-context-optimizer.js +2 -0
- package/dist/types/workflow-types.d.ts +32 -0
- package/dist/types/workflow-types.js +14 -0
- package/package.json +2 -2
- package/spec/workflow.schema.json +70 -1
- package/workflows/coding-task-workflow-with-loops.json +19 -22
- package/workflows/exploration-workflow.json +198 -17
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **Transform chaotic AI interactions into structured, reliable workflows**
|
|
4
4
|
|
|
5
5
|
[](https://modelcontextprotocol.org)
|
|
6
|
-
[]()
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -123,6 +123,15 @@ WorkRail supports powerful iteration patterns for complex tasks:
|
|
|
123
123
|
|
|
124
124
|
Perfect for batch operations, retries, polling, and iterative refinement.
|
|
125
125
|
|
|
126
|
+
### 🚀 v0.2.0: Optimized Loop Execution
|
|
127
|
+
|
|
128
|
+
- **60-80% smaller context** after first iteration
|
|
129
|
+
- **Progressive disclosure** pattern for loop information
|
|
130
|
+
- **Native function DSL** to reduce duplication
|
|
131
|
+
- **Automatic empty loop detection** and skipping
|
|
132
|
+
|
|
133
|
+
See [Loop Optimization Guide](docs/features/loop-optimization.md) for details.
|
|
134
|
+
|
|
126
135
|
---
|
|
127
136
|
|
|
128
137
|
## 📖 Quick Example
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { EnhancedContext, OptimizedLoopContext, LoopPhaseReference, LoopStep } from '../../types/workflow-types';
|
|
2
|
+
import { ILoopContextOptimizer } from '../../types/loop-context-optimizer';
|
|
3
|
+
export declare class LoopContextOptimizer implements ILoopContextOptimizer {
|
|
4
|
+
optimizeLoopContext(context: EnhancedContext, iteration: number): OptimizedLoopContext;
|
|
5
|
+
createPhaseReference(loopStep: LoopStep): LoopPhaseReference;
|
|
6
|
+
hasLoopItems(context: EnhancedContext, loopStep: LoopStep): boolean;
|
|
7
|
+
stripLoopMetadata(context: EnhancedContext): OptimizedLoopContext;
|
|
8
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LoopContextOptimizer = void 0;
|
|
4
|
+
class LoopContextOptimizer {
|
|
5
|
+
optimizeLoopContext(context, iteration) {
|
|
6
|
+
if (!context._currentLoop) {
|
|
7
|
+
throw new Error('Cannot optimize context without active loop');
|
|
8
|
+
}
|
|
9
|
+
const { loopId, loopStep } = context._currentLoop;
|
|
10
|
+
const isFirstIteration = iteration === 0;
|
|
11
|
+
const optimizedContext = {
|
|
12
|
+
...context,
|
|
13
|
+
_currentLoop: {
|
|
14
|
+
loopId,
|
|
15
|
+
loopType: loopStep.loop.type,
|
|
16
|
+
iteration,
|
|
17
|
+
isFirstIteration
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
if (!isFirstIteration && optimizedContext._currentLoop) {
|
|
21
|
+
optimizedContext._currentLoop.phaseReference = this.createPhaseReference(loopStep);
|
|
22
|
+
return this.stripLoopMetadata(optimizedContext);
|
|
23
|
+
}
|
|
24
|
+
return optimizedContext;
|
|
25
|
+
}
|
|
26
|
+
createPhaseReference(loopStep) {
|
|
27
|
+
const reference = {
|
|
28
|
+
loopId: loopStep.id,
|
|
29
|
+
phaseTitle: loopStep.title,
|
|
30
|
+
totalSteps: Array.isArray(loopStep.body) ? loopStep.body.length : 1
|
|
31
|
+
};
|
|
32
|
+
if (loopStep.functionDefinitions && loopStep.functionDefinitions.length > 0) {
|
|
33
|
+
reference.functionDefinitions = loopStep.functionDefinitions;
|
|
34
|
+
}
|
|
35
|
+
return reference;
|
|
36
|
+
}
|
|
37
|
+
hasLoopItems(context, loopStep) {
|
|
38
|
+
const { loop } = loopStep;
|
|
39
|
+
switch (loop.type) {
|
|
40
|
+
case 'forEach':
|
|
41
|
+
if (loop.items) {
|
|
42
|
+
const items = context[loop.items];
|
|
43
|
+
return Array.isArray(items) && items.length > 0;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
case 'for':
|
|
47
|
+
const count = typeof loop.count === 'number'
|
|
48
|
+
? loop.count
|
|
49
|
+
: (loop.count ? context[loop.count] : 0);
|
|
50
|
+
return count > 0;
|
|
51
|
+
case 'while':
|
|
52
|
+
case 'until':
|
|
53
|
+
return true;
|
|
54
|
+
default:
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
stripLoopMetadata(context) {
|
|
59
|
+
let optimizedContext;
|
|
60
|
+
if ('loopType' in (context._currentLoop || {})) {
|
|
61
|
+
optimizedContext = context;
|
|
62
|
+
}
|
|
63
|
+
else if (context._currentLoop) {
|
|
64
|
+
const { loopId, loopStep } = context._currentLoop;
|
|
65
|
+
const iteration = context._loopState?.[loopId]?.iteration || 0;
|
|
66
|
+
optimizedContext = {
|
|
67
|
+
...context,
|
|
68
|
+
_currentLoop: {
|
|
69
|
+
loopId,
|
|
70
|
+
loopType: loopStep.loop.type,
|
|
71
|
+
iteration,
|
|
72
|
+
isFirstIteration: iteration === 0
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return context;
|
|
78
|
+
}
|
|
79
|
+
const strippedContext = { ...optimizedContext };
|
|
80
|
+
if (strippedContext._currentLoop?.loopType === 'forEach') {
|
|
81
|
+
const loopState = strippedContext._loopState;
|
|
82
|
+
if (loopState) {
|
|
83
|
+
Object.keys(loopState).forEach(loopId => {
|
|
84
|
+
const state = loopState[loopId];
|
|
85
|
+
if (state.items && Array.isArray(state.items)) {
|
|
86
|
+
const currentIndex = state.index || 0;
|
|
87
|
+
if (currentIndex < state.items.length) {
|
|
88
|
+
state.items = [state.items[currentIndex]];
|
|
89
|
+
state.index = 0;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const keysToCheck = Object.keys(strippedContext);
|
|
96
|
+
keysToCheck.forEach(key => {
|
|
97
|
+
if (key.startsWith('_'))
|
|
98
|
+
return;
|
|
99
|
+
const value = strippedContext[key];
|
|
100
|
+
if (Array.isArray(value) && value.length > 10) {
|
|
101
|
+
const currentLoop = strippedContext._currentLoop;
|
|
102
|
+
if (currentLoop?.loopType === 'forEach') {
|
|
103
|
+
const loopState = strippedContext._loopState?.[currentLoop.loopId];
|
|
104
|
+
if (loopState?.items === value) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
delete strippedContext[key];
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
return strippedContext;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.LoopContextOptimizer = LoopContextOptimizer;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LoopConfig, LoopState, EnhancedContext } from '../../types/workflow-types';
|
|
1
|
+
import { LoopConfig, LoopState, EnhancedContext, OptimizedLoopContext, LoopPhaseReference, LoopStep } from '../../types/workflow-types';
|
|
2
2
|
import { ConditionContext } from '../../utils/condition-evaluator';
|
|
3
3
|
export declare class LoopExecutionContext {
|
|
4
4
|
private loopId;
|
|
@@ -10,9 +10,14 @@ export declare class LoopExecutionContext {
|
|
|
10
10
|
getCurrentState(): LoopState[string];
|
|
11
11
|
shouldContinue(context: ConditionContext): boolean;
|
|
12
12
|
initializeForEach(context: ConditionContext): void;
|
|
13
|
-
injectVariables(context: ConditionContext): EnhancedContext;
|
|
14
13
|
private resolveCount;
|
|
15
14
|
private addWarning;
|
|
16
15
|
getLoopId(): string;
|
|
17
16
|
getLoopConfig(): LoopConfig;
|
|
17
|
+
getMinimalContext(context: ConditionContext): OptimizedLoopContext;
|
|
18
|
+
getPhaseReference(loopStep: LoopStep): LoopPhaseReference;
|
|
19
|
+
injectVariables(context: ConditionContext, minimal?: boolean): EnhancedContext | OptimizedLoopContext;
|
|
20
|
+
private injectVariablesFull;
|
|
21
|
+
isFirstIteration(): boolean;
|
|
22
|
+
isEmpty(context: ConditionContext): boolean;
|
|
18
23
|
}
|
|
@@ -68,7 +68,72 @@ class LoopExecutionContext {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
resolveCount(context) {
|
|
72
|
+
if (this.loopConfig.type !== 'for' || !this.loopConfig.count) {
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
if (typeof this.loopConfig.count === 'number') {
|
|
76
|
+
return this.loopConfig.count;
|
|
77
|
+
}
|
|
78
|
+
const count = context[this.loopConfig.count];
|
|
79
|
+
if (typeof count === 'number') {
|
|
80
|
+
return count;
|
|
81
|
+
}
|
|
82
|
+
this.addWarning(`Invalid count value for 'for' loop: ${this.loopConfig.count}`);
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
addWarning(message) {
|
|
86
|
+
if (!this.state.warnings) {
|
|
87
|
+
this.state.warnings = [];
|
|
88
|
+
}
|
|
89
|
+
this.state.warnings.push(message);
|
|
90
|
+
}
|
|
91
|
+
getLoopId() {
|
|
92
|
+
return this.loopId;
|
|
93
|
+
}
|
|
94
|
+
getLoopConfig() {
|
|
95
|
+
return { ...this.loopConfig };
|
|
96
|
+
}
|
|
97
|
+
getMinimalContext(context) {
|
|
98
|
+
const optimizedContext = {
|
|
99
|
+
...context,
|
|
100
|
+
_loopState: {
|
|
101
|
+
...context._loopState,
|
|
102
|
+
[this.loopId]: this.getCurrentState()
|
|
103
|
+
},
|
|
104
|
+
_currentLoop: {
|
|
105
|
+
loopId: this.loopId,
|
|
106
|
+
loopType: this.loopConfig.type,
|
|
107
|
+
iteration: this.state.iteration,
|
|
108
|
+
isFirstIteration: false
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
if (this.loopConfig.type === 'forEach' && this.state.items) {
|
|
112
|
+
const index = this.state.index || 0;
|
|
113
|
+
const itemVar = this.loopConfig.itemVar || 'currentItem';
|
|
114
|
+
const indexVar = this.loopConfig.indexVar || 'currentIndex';
|
|
115
|
+
optimizedContext[itemVar] = this.state.items[index];
|
|
116
|
+
optimizedContext[indexVar] = index;
|
|
117
|
+
}
|
|
118
|
+
const iterationVar = this.loopConfig.iterationVar || 'currentIteration';
|
|
119
|
+
optimizedContext[iterationVar] = this.state.iteration + 1;
|
|
120
|
+
return optimizedContext;
|
|
121
|
+
}
|
|
122
|
+
getPhaseReference(loopStep) {
|
|
123
|
+
return {
|
|
124
|
+
loopId: this.loopId,
|
|
125
|
+
phaseTitle: loopStep.title,
|
|
126
|
+
totalSteps: Array.isArray(loopStep.body) ? loopStep.body.length : 1,
|
|
127
|
+
functionDefinitions: loopStep.functionDefinitions
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
injectVariables(context, minimal = false) {
|
|
131
|
+
if (minimal) {
|
|
132
|
+
return this.getMinimalContext(context);
|
|
133
|
+
}
|
|
134
|
+
return this.injectVariablesFull(context);
|
|
135
|
+
}
|
|
136
|
+
injectVariablesFull(context) {
|
|
72
137
|
const enhancements = {
|
|
73
138
|
_loopState: {
|
|
74
139
|
...context._loopState,
|
|
@@ -97,31 +162,27 @@ class LoopExecutionContext {
|
|
|
97
162
|
}
|
|
98
163
|
return { ...context, ...enhancements };
|
|
99
164
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return 0;
|
|
103
|
-
}
|
|
104
|
-
if (typeof this.loopConfig.count === 'number') {
|
|
105
|
-
return this.loopConfig.count;
|
|
106
|
-
}
|
|
107
|
-
const count = context[this.loopConfig.count];
|
|
108
|
-
if (typeof count === 'number') {
|
|
109
|
-
return count;
|
|
110
|
-
}
|
|
111
|
-
this.addWarning(`Invalid count value for 'for' loop: ${this.loopConfig.count}`);
|
|
112
|
-
return 0;
|
|
165
|
+
isFirstIteration() {
|
|
166
|
+
return this.state.iteration === 0;
|
|
113
167
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
168
|
+
isEmpty(context) {
|
|
169
|
+
switch (this.loopConfig.type) {
|
|
170
|
+
case 'forEach':
|
|
171
|
+
return !this.state.items || this.state.items.length === 0;
|
|
172
|
+
case 'for':
|
|
173
|
+
const count = this.resolveCount(context);
|
|
174
|
+
return count <= 0;
|
|
175
|
+
case 'while':
|
|
176
|
+
return this.loopConfig.condition
|
|
177
|
+
? !(0, condition_evaluator_1.evaluateCondition)(this.loopConfig.condition, context)
|
|
178
|
+
: true;
|
|
179
|
+
case 'until':
|
|
180
|
+
return this.loopConfig.condition
|
|
181
|
+
? (0, condition_evaluator_1.evaluateCondition)(this.loopConfig.condition, context)
|
|
182
|
+
: true;
|
|
183
|
+
default:
|
|
184
|
+
return false;
|
|
117
185
|
}
|
|
118
|
-
this.state.warnings.push(message);
|
|
119
|
-
}
|
|
120
|
-
getLoopId() {
|
|
121
|
-
return this.loopId;
|
|
122
|
-
}
|
|
123
|
-
getLoopConfig() {
|
|
124
|
-
return { ...this.loopConfig };
|
|
125
186
|
}
|
|
126
187
|
}
|
|
127
188
|
exports.LoopExecutionContext = LoopExecutionContext;
|
|
@@ -18,11 +18,13 @@ import { IWorkflowStorage } from '../../types/storage';
|
|
|
18
18
|
import { ConditionContext } from '../../utils/condition-evaluator';
|
|
19
19
|
import { ValidationEngine } from './validation-engine';
|
|
20
20
|
import { EnhancedContext } from '../../types/workflow-types';
|
|
21
|
+
import { ILoopContextOptimizer } from '../../types/loop-context-optimizer';
|
|
21
22
|
export declare class DefaultWorkflowService implements WorkflowService {
|
|
22
23
|
private readonly storage;
|
|
23
24
|
private readonly validationEngine;
|
|
25
|
+
private readonly loopContextOptimizer?;
|
|
24
26
|
private loopStepResolver;
|
|
25
|
-
constructor(storage?: IWorkflowStorage, validationEngine?: ValidationEngine);
|
|
27
|
+
constructor(storage?: IWorkflowStorage, validationEngine?: ValidationEngine, loopContextOptimizer?: ILoopContextOptimizer | undefined);
|
|
26
28
|
listWorkflowSummaries(): Promise<WorkflowSummary[]>;
|
|
27
29
|
getWorkflowById(id: string): Promise<Workflow | null>;
|
|
28
30
|
getNextStep(workflowId: string, completedSteps: string[], context?: ConditionContext): Promise<{
|
|
@@ -11,9 +11,10 @@ const loop_step_resolver_1 = require("./loop-step-resolver");
|
|
|
11
11
|
const context_size_1 = require("../../utils/context-size");
|
|
12
12
|
const context_optimizer_1 = require("./context-optimizer");
|
|
13
13
|
class DefaultWorkflowService {
|
|
14
|
-
constructor(storage = (0, storage_1.createDefaultWorkflowStorage)(), validationEngine = new validation_engine_1.ValidationEngine()) {
|
|
14
|
+
constructor(storage = (0, storage_1.createDefaultWorkflowStorage)(), validationEngine = new validation_engine_1.ValidationEngine(), loopContextOptimizer) {
|
|
15
15
|
this.storage = storage;
|
|
16
16
|
this.validationEngine = validationEngine;
|
|
17
|
+
this.loopContextOptimizer = loopContextOptimizer;
|
|
17
18
|
this.loopStepResolver = new loop_step_resolver_1.LoopStepResolver();
|
|
18
19
|
}
|
|
19
20
|
async listWorkflowSummaries() {
|
|
@@ -56,15 +57,26 @@ class DefaultWorkflowService {
|
|
|
56
57
|
if (loopContext.shouldContinue(context)) {
|
|
57
58
|
const bodyStep = this.loopStepResolver.resolveLoopBody(workflow, loopStep.body, loopStep.id);
|
|
58
59
|
if (!Array.isArray(bodyStep)) {
|
|
59
|
-
const
|
|
60
|
-
|
|
60
|
+
const isFirst = loopContext.isFirstIteration();
|
|
61
|
+
if (isFirst && loopContext.isEmpty(context)) {
|
|
62
|
+
const skipContext = context_optimizer_1.ContextOptimizer.createEnhancedContext(context, completed);
|
|
63
|
+
delete skipContext._currentLoop;
|
|
64
|
+
const nextStep = await this.getNextStep(workflow.id, completed, skipContext);
|
|
65
|
+
return nextStep;
|
|
66
|
+
}
|
|
67
|
+
const useMinimal = !isFirst && !!this.loopContextOptimizer;
|
|
68
|
+
const loopEnhancedContext = loopContext.injectVariables(context, useMinimal);
|
|
69
|
+
const optimizedContext = useMinimal && this.loopContextOptimizer
|
|
70
|
+
? this.loopContextOptimizer.stripLoopMetadata(loopEnhancedContext)
|
|
71
|
+
: loopEnhancedContext;
|
|
72
|
+
const loopSizeCheck = (0, context_size_1.checkContextSize)(optimizedContext);
|
|
61
73
|
if (loopSizeCheck.isError) {
|
|
62
74
|
throw new Error(`Context size (${Math.round(loopSizeCheck.sizeBytes / 1024)}KB) exceeds maximum allowed size (256KB) during loop execution`);
|
|
63
75
|
}
|
|
64
76
|
return {
|
|
65
77
|
step: bodyStep,
|
|
66
78
|
guidance: {
|
|
67
|
-
prompt: this.buildStepPrompt(bodyStep, loopContext)
|
|
79
|
+
prompt: this.buildStepPrompt(bodyStep, loopContext, useMinimal)
|
|
68
80
|
},
|
|
69
81
|
isComplete: false,
|
|
70
82
|
context: loopSizeCheck.context
|
|
@@ -81,15 +93,26 @@ class DefaultWorkflowService {
|
|
|
81
93
|
return true;
|
|
82
94
|
});
|
|
83
95
|
if (uncompletedBodyStep) {
|
|
84
|
-
const
|
|
85
|
-
|
|
96
|
+
const isFirst = loopContext.isFirstIteration();
|
|
97
|
+
if (isFirst && loopContext.isEmpty(context)) {
|
|
98
|
+
const skipContext = context_optimizer_1.ContextOptimizer.createEnhancedContext(context, completed);
|
|
99
|
+
delete skipContext._currentLoop;
|
|
100
|
+
const nextStep = await this.getNextStep(workflow.id, completed, skipContext);
|
|
101
|
+
return nextStep;
|
|
102
|
+
}
|
|
103
|
+
const useMinimal = !isFirst && !!this.loopContextOptimizer;
|
|
104
|
+
const loopEnhancedContext = loopContext.injectVariables(context, useMinimal);
|
|
105
|
+
const optimizedContext = useMinimal && this.loopContextOptimizer
|
|
106
|
+
? this.loopContextOptimizer.stripLoopMetadata(loopEnhancedContext)
|
|
107
|
+
: loopEnhancedContext;
|
|
108
|
+
const loopSizeCheck = (0, context_size_1.checkContextSize)(optimizedContext);
|
|
86
109
|
if (loopSizeCheck.isError) {
|
|
87
110
|
throw new Error(`Context size (${Math.round(loopSizeCheck.sizeBytes / 1024)}KB) exceeds maximum allowed size (256KB) during loop execution`);
|
|
88
111
|
}
|
|
89
112
|
return {
|
|
90
113
|
step: uncompletedBodyStep,
|
|
91
114
|
guidance: {
|
|
92
|
-
prompt: this.buildStepPrompt(uncompletedBodyStep, loopContext)
|
|
115
|
+
prompt: this.buildStepPrompt(uncompletedBodyStep, loopContext, useMinimal)
|
|
93
116
|
},
|
|
94
117
|
isComplete: false,
|
|
95
118
|
context: loopSizeCheck.context
|
|
@@ -180,7 +203,7 @@ class DefaultWorkflowService {
|
|
|
180
203
|
context: enhancedContext
|
|
181
204
|
};
|
|
182
205
|
}
|
|
183
|
-
buildStepPrompt(step, loopContext) {
|
|
206
|
+
buildStepPrompt(step, loopContext, useMinimal = false) {
|
|
184
207
|
let stepGuidance = '';
|
|
185
208
|
if (step.guidance && step.guidance.length > 0) {
|
|
186
209
|
const guidanceHeader = '## Step Guidance';
|
|
@@ -193,10 +216,18 @@ class DefaultWorkflowService {
|
|
|
193
216
|
}
|
|
194
217
|
if (loopContext) {
|
|
195
218
|
const state = loopContext.getCurrentState();
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
219
|
+
if (useMinimal && this.loopContextOptimizer) {
|
|
220
|
+
finalPrompt += `\n\n## Loop Context\n- Iteration: ${state.iteration + 1}`;
|
|
221
|
+
if (!loopContext.isFirstIteration()) {
|
|
222
|
+
finalPrompt += '\n\n_Note: Refer to the phase overview provided in the first iteration for overall context._';
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
finalPrompt += `\n\n## Loop Context\n- Iteration: ${state.iteration + 1}`;
|
|
227
|
+
if (state.items) {
|
|
228
|
+
finalPrompt += `\n- Total Items: ${state.items.length}`;
|
|
229
|
+
finalPrompt += `\n- Current Index: ${state.index}`;
|
|
230
|
+
}
|
|
200
231
|
}
|
|
201
232
|
}
|
|
202
233
|
return finalPrompt;
|
package/dist/container.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ import { WorkflowService } from './application/services/workflow-service.js';
|
|
|
2
2
|
import { ValidationEngine } from './application/services/validation-engine.js';
|
|
3
3
|
import { IWorkflowStorage } from './types/storage.js';
|
|
4
4
|
import { WorkflowLookupServer } from './types/server.js';
|
|
5
|
+
import { ILoopContextOptimizer } from './types/loop-context-optimizer.js';
|
|
5
6
|
export interface AppContainer {
|
|
6
7
|
storage: IWorkflowStorage;
|
|
7
8
|
validationEngine: ValidationEngine;
|
|
9
|
+
loopContextOptimizer: ILoopContextOptimizer;
|
|
8
10
|
workflowService: WorkflowService;
|
|
9
11
|
server: WorkflowLookupServer;
|
|
10
12
|
}
|
package/dist/container.js
CHANGED
|
@@ -5,14 +5,17 @@ const storage_js_1 = require("./infrastructure/storage/storage.js");
|
|
|
5
5
|
const workflow_service_js_1 = require("./application/services/workflow-service.js");
|
|
6
6
|
const validation_engine_js_1 = require("./application/services/validation-engine.js");
|
|
7
7
|
const server_js_1 = require("./infrastructure/rpc/server.js");
|
|
8
|
+
const loop_context_optimizer_js_1 = require("./application/services/loop-context-optimizer.js");
|
|
8
9
|
function createAppContainer(overrides = {}) {
|
|
9
10
|
const storage = overrides.storage ?? (0, storage_js_1.createDefaultWorkflowStorage)();
|
|
10
11
|
const validationEngine = overrides.validationEngine ?? new validation_engine_js_1.ValidationEngine();
|
|
11
|
-
const
|
|
12
|
+
const loopContextOptimizer = overrides.loopContextOptimizer ?? new loop_context_optimizer_js_1.LoopContextOptimizer();
|
|
13
|
+
const workflowService = overrides.workflowService ?? new workflow_service_js_1.DefaultWorkflowService(storage, validationEngine, loopContextOptimizer);
|
|
12
14
|
const server = overrides.server ?? (0, server_js_1.createWorkflowLookupServer)(workflowService);
|
|
13
15
|
return {
|
|
14
16
|
storage,
|
|
15
17
|
validationEngine,
|
|
18
|
+
loopContextOptimizer,
|
|
16
19
|
workflowService,
|
|
17
20
|
server
|
|
18
21
|
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { EnhancedContext, OptimizedLoopContext, LoopPhaseReference, LoopStep } from './workflow-types';
|
|
2
|
+
export interface ILoopContextOptimizer {
|
|
3
|
+
optimizeLoopContext(context: EnhancedContext, iteration: number): OptimizedLoopContext;
|
|
4
|
+
createPhaseReference(loopStep: LoopStep): LoopPhaseReference;
|
|
5
|
+
hasLoopItems(context: EnhancedContext, loopStep: LoopStep): boolean;
|
|
6
|
+
stripLoopMetadata(context: EnhancedContext): OptimizedLoopContext;
|
|
7
|
+
}
|
|
@@ -8,6 +8,7 @@ export interface Workflow {
|
|
|
8
8
|
clarificationPrompts?: string[];
|
|
9
9
|
steps: (WorkflowStep | LoopStep)[];
|
|
10
10
|
metaGuidance?: string[];
|
|
11
|
+
functionDefinitions?: FunctionDefinition[];
|
|
11
12
|
}
|
|
12
13
|
export interface WorkflowStep {
|
|
13
14
|
id: string;
|
|
@@ -18,6 +19,8 @@ export interface WorkflowStep {
|
|
|
18
19
|
askForFiles?: boolean;
|
|
19
20
|
requireConfirmation?: boolean;
|
|
20
21
|
runCondition?: object;
|
|
22
|
+
functionDefinitions?: FunctionDefinition[];
|
|
23
|
+
functionReferences?: string[];
|
|
21
24
|
}
|
|
22
25
|
export interface LoopStep extends WorkflowStep {
|
|
23
26
|
type: 'loop';
|
|
@@ -56,7 +59,36 @@ export interface EnhancedContext extends ConditionContext {
|
|
|
56
59
|
loopStep: LoopStep;
|
|
57
60
|
};
|
|
58
61
|
}
|
|
62
|
+
export interface OptimizedLoopContext extends ConditionContext {
|
|
63
|
+
_loopState?: LoopState;
|
|
64
|
+
_warnings?: {
|
|
65
|
+
loops?: {
|
|
66
|
+
[loopId: string]: string[];
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
_contextSize?: number;
|
|
70
|
+
_currentLoop?: {
|
|
71
|
+
loopId: string;
|
|
72
|
+
loopType: 'for' | 'forEach' | 'while' | 'until';
|
|
73
|
+
iteration: number;
|
|
74
|
+
isFirstIteration: boolean;
|
|
75
|
+
phaseReference?: LoopPhaseReference;
|
|
76
|
+
};
|
|
77
|
+
_loopPhaseReference?: LoopPhaseReference;
|
|
78
|
+
}
|
|
79
|
+
export interface LoopPhaseReference {
|
|
80
|
+
loopId: string;
|
|
81
|
+
phaseTitle: string;
|
|
82
|
+
totalSteps: number;
|
|
83
|
+
functionDefinitions?: FunctionDefinition[];
|
|
84
|
+
}
|
|
85
|
+
export interface FunctionDefinition {
|
|
86
|
+
name: string;
|
|
87
|
+
definition: string;
|
|
88
|
+
scope?: 'workflow' | 'loop' | 'step';
|
|
89
|
+
}
|
|
59
90
|
export declare function isLoopStep(step: WorkflowStep | LoopStep): step is LoopStep;
|
|
91
|
+
export declare function isFirstLoopIteration(context: EnhancedContext | OptimizedLoopContext): boolean;
|
|
60
92
|
export interface WorkflowValidationResult {
|
|
61
93
|
valid: boolean;
|
|
62
94
|
errors: WorkflowValidationError[];
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isLoopStep = isLoopStep;
|
|
4
|
+
exports.isFirstLoopIteration = isFirstLoopIteration;
|
|
4
5
|
function isLoopStep(step) {
|
|
5
6
|
return 'type' in step && step.type === 'loop';
|
|
6
7
|
}
|
|
8
|
+
function isFirstLoopIteration(context) {
|
|
9
|
+
if ('isFirstIteration' in (context._currentLoop || {})) {
|
|
10
|
+
return context._currentLoop?.isFirstIteration === true;
|
|
11
|
+
}
|
|
12
|
+
const loopState = context._loopState;
|
|
13
|
+
if (loopState) {
|
|
14
|
+
const currentLoopId = context._currentLoop?.loopId;
|
|
15
|
+
if (currentLoopId && loopState[currentLoopId]) {
|
|
16
|
+
return loopState[currentLoopId].iteration === 0;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exaudeus/workrail",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "MCP server for structured workflow orchestration and step-by-step task guidance",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
15
|
"build": "tsc -p tsconfig.build.json",
|
|
16
|
-
"release": "./scripts/release.sh",
|
|
16
|
+
"release": "bash -c './scripts/release.sh'",
|
|
17
17
|
"dev": "npm run build && node dist/mcp-server.js",
|
|
18
18
|
"prepare": "npm run build",
|
|
19
19
|
"watch": "tsc --watch"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://workflowlookup.io/schemas/workflow/v0.
|
|
3
|
+
"$id": "https://workflowlookup.io/schemas/workflow/v0.2.0",
|
|
4
4
|
"title": "Workflow Schema",
|
|
5
5
|
"description": "Schema for defining workflows in the Workflow Orchestration System",
|
|
6
6
|
"type": "object",
|
|
@@ -74,6 +74,32 @@
|
|
|
74
74
|
"maxLength": 256
|
|
75
75
|
},
|
|
76
76
|
"uniqueItems": true
|
|
77
|
+
},
|
|
78
|
+
"functionDefinitions": {
|
|
79
|
+
"type": "array",
|
|
80
|
+
"description": "Function definitions for reducing duplication. Agents can reference these definitions to understand repeated patterns without full expansion.",
|
|
81
|
+
"items": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"properties": {
|
|
84
|
+
"name": {
|
|
85
|
+
"type": "string",
|
|
86
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
87
|
+
"description": "Function name following JavaScript identifier rules"
|
|
88
|
+
},
|
|
89
|
+
"definition": {
|
|
90
|
+
"type": "string",
|
|
91
|
+
"description": "The function definition explaining what it does"
|
|
92
|
+
},
|
|
93
|
+
"scope": {
|
|
94
|
+
"type": "string",
|
|
95
|
+
"enum": ["workflow", "loop", "step"],
|
|
96
|
+
"description": "Scope where this function is available"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"required": ["name", "definition"],
|
|
100
|
+
"additionalProperties": false
|
|
101
|
+
},
|
|
102
|
+
"uniqueItems": true
|
|
77
103
|
}
|
|
78
104
|
},
|
|
79
105
|
"required": [
|
|
@@ -91,6 +117,27 @@
|
|
|
91
117
|
"minLength": 3,
|
|
92
118
|
"maxLength": 64
|
|
93
119
|
},
|
|
120
|
+
"functionDefinition": {
|
|
121
|
+
"type": "object",
|
|
122
|
+
"properties": {
|
|
123
|
+
"name": {
|
|
124
|
+
"type": "string",
|
|
125
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
126
|
+
"description": "Function name following JavaScript identifier rules"
|
|
127
|
+
},
|
|
128
|
+
"definition": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"description": "The function definition explaining what it does"
|
|
131
|
+
},
|
|
132
|
+
"scope": {
|
|
133
|
+
"type": "string",
|
|
134
|
+
"enum": ["workflow", "loop", "step"],
|
|
135
|
+
"description": "Scope where this function is available"
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
"required": ["name", "definition"],
|
|
139
|
+
"additionalProperties": false
|
|
140
|
+
},
|
|
94
141
|
"standardStep": {
|
|
95
142
|
"type": "object",
|
|
96
143
|
"properties": {
|
|
@@ -153,6 +200,21 @@
|
|
|
153
200
|
"$ref": "#/$defs/validationComposition"
|
|
154
201
|
}
|
|
155
202
|
]
|
|
203
|
+
},
|
|
204
|
+
"functionDefinitions": {
|
|
205
|
+
"type": "array",
|
|
206
|
+
"description": "Function definitions specific to this step. Agents can reference these for understanding step-specific patterns.",
|
|
207
|
+
"items": {
|
|
208
|
+
"$ref": "#/$defs/functionDefinition"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
"functionReferences": {
|
|
212
|
+
"type": "array",
|
|
213
|
+
"description": "References to functions defined at workflow or loop level that this step uses.",
|
|
214
|
+
"items": {
|
|
215
|
+
"type": "string",
|
|
216
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*\\(\\)$"
|
|
217
|
+
}
|
|
156
218
|
}
|
|
157
219
|
},
|
|
158
220
|
"required": [
|
|
@@ -198,6 +260,13 @@
|
|
|
198
260
|
}
|
|
199
261
|
]
|
|
200
262
|
},
|
|
263
|
+
"functionDefinitions": {
|
|
264
|
+
"type": "array",
|
|
265
|
+
"description": "Function definitions specific to this loop. Available to all steps within the loop body.",
|
|
266
|
+
"items": {
|
|
267
|
+
"$ref": "#/$defs/functionDefinition"
|
|
268
|
+
}
|
|
269
|
+
},
|
|
201
270
|
"requireConfirmation": {
|
|
202
271
|
"$ref": "#/$defs/confirmationRule"
|
|
203
272
|
},
|
|
@@ -404,15 +404,14 @@
|
|
|
404
404
|
"requireConfirmation": false
|
|
405
405
|
},
|
|
406
406
|
{
|
|
407
|
-
"id": "phase-6-
|
|
408
|
-
"title": "Phase 6 Preparation:
|
|
409
|
-
"prompt": "Before starting the implementation loop,
|
|
410
|
-
"agentRole": "You are preparing the implementation phase by
|
|
407
|
+
"id": "phase-6-count-steps",
|
|
408
|
+
"title": "Phase 6 Preparation: Count Implementation Steps",
|
|
409
|
+
"prompt": "Before starting the implementation loop, count the discrete implementation steps in the approved `implementation_plan.md`.\n\n**Your task:**\n1. Read the implementation_plan.md\n2. Count each discrete, actionable step from the Implementation Strategy section\n3. Set `totalImplementationSteps` to the count (e.g., 8)\n\n**What counts as a step:**\n- Each bullet point or numbered item that represents a concrete implementation task\n- Each item that would result in a code change or file creation\n- Each item that could be a logical git commit\n\n**Example:**\nIf the plan has:\n- Create user model\n- Add authentication service\n- Implement validation\n- Write tests\n\nThen set `totalImplementationSteps` = 4\n\n**IMPORTANT:** Only count, don't extract or store the steps. You'll read them directly from the plan during implementation.",
|
|
410
|
+
"agentRole": "You are preparing the implementation phase by counting the steps to enable progress tracking.",
|
|
411
411
|
"guidance": [
|
|
412
|
-
"
|
|
413
|
-
"
|
|
414
|
-
"
|
|
415
|
-
"This enables the loop to iterate over a concrete list"
|
|
412
|
+
"Count only actionable implementation steps",
|
|
413
|
+
"Don't include meta-tasks like 'review' or 'document'",
|
|
414
|
+
"This enables progress tracking without bloating context"
|
|
416
415
|
],
|
|
417
416
|
"runCondition": {"var": "taskComplexity", "not_equals": "Small"},
|
|
418
417
|
"requireConfirmation": false
|
|
@@ -423,22 +422,20 @@
|
|
|
423
422
|
"title": "Phase 6: Iterative Implementation Loop (PREP -> IMPLEMENT -> VERIFY)",
|
|
424
423
|
"runCondition": {"var": "taskComplexity", "not_equals": "Small"},
|
|
425
424
|
"loop": {
|
|
426
|
-
"type": "
|
|
427
|
-
"
|
|
428
|
-
"
|
|
429
|
-
"
|
|
430
|
-
"maxIterations": 25,
|
|
431
|
-
"iterationVar": "stepIteration"
|
|
425
|
+
"type": "for",
|
|
426
|
+
"count": "totalImplementationSteps",
|
|
427
|
+
"indexVar": "currentStepNumber",
|
|
428
|
+
"maxIterations": 25
|
|
432
429
|
},
|
|
433
430
|
"body": [
|
|
434
431
|
{
|
|
435
432
|
"id": "phase-6-prep",
|
|
436
|
-
"title": "PREP: Prepare for {{
|
|
437
|
-
"prompt": "**PREPARATION PHASE for Step {{
|
|
433
|
+
"title": "PREP: Prepare for Step {{currentStepNumber + 1}}",
|
|
434
|
+
"prompt": "**PREPARATION PHASE for Step {{currentStepNumber + 1}}/{{totalImplementationSteps}}**\n\nBefore implementing this step, you must first PREPARE:\n\n1. **Read implementation_plan.md** and locate step #{{currentStepNumber + 1}}\n2. **Extract step details**: Note the title, description, and expected outputs\n3. **Confirm prerequisites**: Verify the previous step (if any) was completed correctly\n4. **Validate current state**: Ensure the plan for this step is still valid in the current codebase\n5. **List requirements**: Identify all required inputs, files, or dependencies\n\n**BRANCH SETUP (first iteration only):** If this is the first implementation step ({{currentStepNumber}} === 0):\n- Check git availability with 'git status'\n- If available, create feature branch: 'git checkout -b wip-[unique-task-id]'\n- Track the featureBranch variable for later use\n- If git unavailable: Skip branching, log in CONTEXT.md\n\n**CRITICAL CONTEXT OPTIMIZATION:**\nWhen calling workflow_next after this step, send ONLY:\n- currentStepNumber and totalImplementationSteps\n- Any NEW variables you created (like featureBranch)\n- DO NOT send: arrays, plans, _loopState, _currentLoop, unchanged data\n\n**Do not proceed if anything is unclear or missing.**",
|
|
438
435
|
"agentRole": "You are preparing to implement a specific step from the plan. Be meticulous in verifying all prerequisites are met before proceeding.",
|
|
439
436
|
"guidance": [
|
|
440
|
-
"This is step {{
|
|
441
|
-
"
|
|
437
|
+
"This is step {{currentStepNumber + 1}} of {{totalImplementationSteps}} total implementation steps",
|
|
438
|
+
"Read the step directly from implementation_plan.md",
|
|
442
439
|
"Focus only on preparation - implementation comes next",
|
|
443
440
|
"If this is the first step, handle git branch setup"
|
|
444
441
|
],
|
|
@@ -446,8 +443,8 @@
|
|
|
446
443
|
},
|
|
447
444
|
{
|
|
448
445
|
"id": "phase-6-implement",
|
|
449
|
-
"title": "IMPLEMENT: Execute {{
|
|
450
|
-
"prompt": "**IMPLEMENTATION PHASE for {{
|
|
446
|
+
"title": "IMPLEMENT: Execute Step {{currentStepNumber + 1}}",
|
|
447
|
+
"prompt": "**IMPLEMENTATION PHASE for Step {{currentStepNumber + 1}}/{{totalImplementationSteps}}**\n\nNow implement the step you just prepared for:\n\n**Instructions:**\n1. Re-read step #{{currentStepNumber + 1}} from implementation_plan.md\n2. Focus only on this single step\n3. useTools() to make code changes\n4. Follow quality standards\n5. Adapt to unexpected discoveries\n6. createFile() for ALL code changes\n\n**Remember:** applyUserRules() and matchPatterns() throughout.\n\n**Progress Tracking:**\n- This is step {{currentStepNumber + 1}} of {{totalImplementationSteps}}\n- If we've done > 20 steps total, pause for user intervention\n\n**CONTEXT UPDATES:** If this is every 3rd step ({{currentStepNumber + 1}} % 3 === 0):\n- Update CONTEXT.md\n- addResumptionJson(phase-6-implement)\n- updateDecisionLog()\n- List files modified with line ranges\n\n**CONTEXT OPTIMIZATION for workflow_next:**\nSend ONLY: currentStepNumber, totalImplementationSteps, filesCreated (new), any other NEW data\nDO NOT send: arrays, plans, _loopState, unchanged fields",
|
|
451
448
|
"agentRole": "You are implementing a specific step from the approved plan. Focus on precise execution while maintaining code quality.",
|
|
452
449
|
"guidance": [
|
|
453
450
|
"Implement only what this step requires",
|
|
@@ -458,8 +455,8 @@
|
|
|
458
455
|
},
|
|
459
456
|
{
|
|
460
457
|
"id": "phase-6-verify",
|
|
461
|
-
"title": "VERIFY: Validate {{
|
|
462
|
-
"prompt": "**VERIFICATION PHASE for {{
|
|
458
|
+
"title": "VERIFY: Validate Step {{currentStepNumber + 1}}",
|
|
459
|
+
"prompt": "**VERIFICATION PHASE for Step {{currentStepNumber + 1}}/{{totalImplementationSteps}}**\n\nVerify the implementation is complete and correct:\n\n**Required:** verifyImplementation()\n\n**COMMIT Decision (if all passes):**\n- checkAutomation(commit)\n- gitCommit(type, scope: description)\n- If git unavailable: Log in CONTEXT.md\n\n**FAILURE PROTOCOL:** If verification fails after 2 attempts:\n1. Do not try a third time\n2. Fall back to alternative tools\n3. updateDecisionLog() with failure details\n4. Present summary and recommendations\n5. Set 'verificationFailed' context variable to true\n\n**CONTEXT OPTIMIZATION:**\nFor workflow_next, send ONLY what changed: currentStepNumber, verificationResult, verificationFailed (if true)\nNEVER send back the full context!",
|
|
463
460
|
"agentRole": "You are verifying the implementation meets all quality standards. Be thorough but respect failure bounds.",
|
|
464
461
|
"guidance": [
|
|
465
462
|
"All three verification steps must pass",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "exploration-workflow",
|
|
3
3
|
"name": "Comprehensive Adaptive Exploration Workflow",
|
|
4
|
-
"version": "0.0
|
|
5
|
-
"description": "
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "An enterprise-grade exploration workflow featuring multi-phase research loops with saturation detection, evidence-based validation, diverse solution generation, and adversarial challenge patterns. Adapts methodology based on domain type (technical/business/creative) while ensuring depth through triangulation, confidence scoring, and systematic quality gates.",
|
|
6
6
|
"clarificationPrompts": [
|
|
7
7
|
"What specific task, problem, or question do you need to explore?",
|
|
8
8
|
"What constraints or requirements should guide the exploration? (time, budget, technical, etc.)",
|
|
@@ -13,22 +13,26 @@
|
|
|
13
13
|
],
|
|
14
14
|
"preconditions": [
|
|
15
15
|
"User has a clear task, problem, or question to explore",
|
|
16
|
-
"Agent has access to research tools (web search, codebase search, etc.)",
|
|
17
16
|
"User can provide initial context, constraints, or requirements",
|
|
18
17
|
"Agent can maintain context variables throughout the workflow"
|
|
19
18
|
],
|
|
20
19
|
"metaGuidance": [
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
20
|
+
"FUNCTION DEFINITIONS: fun trackEvidence(source, grade) = 'Add to context.evidenceLog[] with {source, grade, timestamp}. Grade: High (peer-reviewed/official), Medium (expert/established), Low (anecdotal/emerging)'",
|
|
21
|
+
"fun checkSaturation() = 'Calculate novelty score: (new_insights / total_insights). If <0.1 for last 3 iterations, set context.saturationReached=true'",
|
|
22
|
+
"fun generateSolution(index, approach) = 'Create solution in context.solutions[index] with {approach, evidence, confidence, tradeoffs, risks}'",
|
|
23
|
+
"fun calculateConfidence() = '(0.4 × evidenceStrength) + (0.3 × triangulation) + (0.2 × sourceDiversity) + (0.1 × recency). Result in context.confidenceScores[]'",
|
|
24
|
+
"fun triggerDeepDive() = 'If confidence < 0.7 OR evidenceGaps.length > 0 OR contradictions found, set context.needsDeepDive=true'",
|
|
25
|
+
"CONTEXT ARCHITECTURE: Track explorationDomain (technical/business/creative), solutions[], evidenceLog[], confidenceScores[], researchPhases[], currentPhase, saturationMetrics, contradictions[], evidenceGaps[]",
|
|
26
|
+
"EVIDENCE STANDARDS: Minimum 3 sources per key claim (from available sources: web, agent knowledge, user environment), at least 1 contrasting perspective required, formal grading using adapted RAND scale (High/Medium/Limited)",
|
|
27
|
+
"SOLUTION DIVERSITY: Generate minimum 5 solutions: Quick/Simple, Thorough/Proven, Creative/Novel, Optimal/Balanced, Contrarian/Alternative",
|
|
28
|
+
"VALIDATION GATES: Phase transitions require validation; solutions need confidence ≥0.7; evidence must pass triangulation check",
|
|
29
|
+
"This workflow follows ANALYZE -> CLARIFY -> RESEARCH (loop) -> GENERATE (divergent) -> EVALUATE (convergent) -> CHALLENGE -> RECOMMEND pattern.",
|
|
30
|
+
"Automation levels (Low/Medium/High) control confirmation requirements. High: auto-proceed if confidence >0.8",
|
|
31
|
+
"Dynamic re-triage allows complexity upgrades and safe downgrades based on research insights and saturation metrics.",
|
|
32
|
+
"TOOL ADAPTATION: Workflow adapts to available tools. Check MCPs and adjust strategy based on what's available.",
|
|
33
|
+
"Context documentation updated at phase boundaries. Include function definitions for resumption.",
|
|
34
|
+
"Failure bounds: word limits (2000), max iterations (5 per loop), total steps (>20 triggers review).",
|
|
35
|
+
"Human approval required after adversarial challenge and before final recommendations."
|
|
32
36
|
],
|
|
33
37
|
"steps": [
|
|
34
38
|
{
|
|
@@ -46,6 +50,32 @@
|
|
|
46
50
|
],
|
|
47
51
|
"requireConfirmation": true
|
|
48
52
|
},
|
|
53
|
+
{
|
|
54
|
+
"id": "phase-0a-user-context",
|
|
55
|
+
"title": "Phase 0a: User Context & Preferences Check",
|
|
56
|
+
"prompt": "**GATHER USER CONTEXT**: Before proceeding, check for relevant user preferences, rules, and past decisions that should influence this exploration.\n\n**CHECK FOR:**\n1. **User Rules/Preferences**: Use memory tools to check for:\n - Organizational standards or guidelines\n - Preferred technologies or approaches\n - Constraints or requirements from past decisions\n - Specific methodologies or frameworks to follow/avoid\n\n2. **Environmental Context**:\n - Current tech stack (if technical)\n - Business constraints (budget, timeline, resources)\n - Regulatory or compliance requirements\n - Team capabilities and preferences\n\n3. **Historical Decisions**:\n - Similar problems solved before\n - Lessons learned from past explorations\n - Established patterns to follow\n\n**ACTIONS:**\n1. Query memory/knowledge base for relevant rules\n2. Set context.userRules[] with applicable preferences\n3. Set context.constraints[] with hard requirements\n4. Note any past decisions that create precedent\n\nIf no specific rules found, note that and proceed with general best practices.",
|
|
57
|
+
"agentRole": "You are gathering user-specific context that will influence all subsequent exploration phases. Your role is to ensure the exploration aligns with the user's established preferences and constraints.",
|
|
58
|
+
"guidance": [
|
|
59
|
+
"This context check happens for all complexity levels",
|
|
60
|
+
"Rules and preferences should influence solution generation",
|
|
61
|
+
"Document which rules apply and why",
|
|
62
|
+
"If conflicts exist between rules and task requirements, flag for clarification"
|
|
63
|
+
],
|
|
64
|
+
"requireConfirmation": false
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"id": "phase-0b-domain-classification",
|
|
68
|
+
"title": "Phase 0b: Domain Classification & Tool Selection",
|
|
69
|
+
"prompt": "**CLASSIFY EXPLORATION DOMAIN**: Based on the task, classify the exploration into one of these domains:\n\n**Technical Domain:**\n- Code implementation, architecture design, debugging\n- Tool selection, framework comparison, performance optimization\n- Primary tools: codebase_search, grep_search (if available), technical documentation\n- Fallback: Agent's technical knowledge, architectural patterns from training\n\n**Business Domain:**\n- Strategy formulation, market analysis, process improvement\n- Cost-benefit analysis, resource allocation, risk assessment\n- Primary tools: web_search for market data (if available), case studies, industry reports\n- Fallback: Business frameworks and principles from agent knowledge\n\n**Creative Domain:**\n- Content creation, design systems, user experience\n- Innovation, brainstorming, conceptual development\n- Primary tools: web_search for inspiration (if available), trend analysis\n- Fallback: Creative methodologies and patterns from agent training\n\n**IMPLEMENT:**\n1. Analyze task characteristics\n2. Set context.explorationDomain = 'technical' | 'business' | 'creative'\n3. Set context.primaryTools[] based on domain\n4. Set context.evaluationCriteria[] appropriate for domain\n\n**DOMAIN-SPECIFIC SUCCESS METRICS:**\n- Technical: Feasibility, performance, maintainability, scalability\n- Business: ROI, time-to-value, risk mitigation, strategic alignment\n- Creative: Innovation, user satisfaction, aesthetics, differentiation",
|
|
70
|
+
"agentRole": "You are a domain classification specialist who identifies the nature of exploration tasks and configures appropriate methodologies, tools, and success criteria for each domain type.",
|
|
71
|
+
"guidance": [
|
|
72
|
+
"Some tasks may span domains - choose primary domain",
|
|
73
|
+
"This classification affects tool selection and evaluation criteria",
|
|
74
|
+
"Document reasoning for domain choice",
|
|
75
|
+
"Set domain-specific context variables for later steps"
|
|
76
|
+
],
|
|
77
|
+
"requireConfirmation": false
|
|
78
|
+
},
|
|
49
79
|
{
|
|
50
80
|
"id": "phase-1-simple-lookup",
|
|
51
81
|
"runCondition": {"var": "explorationComplexity", "equals": "Simple"},
|
|
@@ -152,6 +182,97 @@
|
|
|
152
182
|
]
|
|
153
183
|
}
|
|
154
184
|
},
|
|
185
|
+
{
|
|
186
|
+
"id": "phase-2c-iterative-research-loop",
|
|
187
|
+
"type": "loop",
|
|
188
|
+
"title": "Phase 2c: Multi-Phase Deep Research with Saturation Detection",
|
|
189
|
+
"runCondition": {"var": "explorationComplexity", "not_equals": "Simple"},
|
|
190
|
+
"loop": {
|
|
191
|
+
"type": "for",
|
|
192
|
+
"count": 5,
|
|
193
|
+
"maxIterations": 5,
|
|
194
|
+
"iterationVar": "researchPhase"
|
|
195
|
+
},
|
|
196
|
+
"body": [
|
|
197
|
+
{
|
|
198
|
+
"id": "research-phase-1-broad",
|
|
199
|
+
"title": "Research Phase 1/5: Broad Scan",
|
|
200
|
+
"runCondition": { "var": "researchPhase", "equals": 1 },
|
|
201
|
+
"prompt": "**OBJECTIVE**: Cast a wide net to map the solution landscape, identify key themes, and find conflicting viewpoints.",
|
|
202
|
+
"agentRole": "Systematic Researcher: Broad Scan Specialist",
|
|
203
|
+
"guidance": [
|
|
204
|
+
"Use multiple search strategies (e.g., 'how to [task]', 'alternatives to [tool]').",
|
|
205
|
+
"Identify 3-5 high-level solution categories.",
|
|
206
|
+
"Note sources that directly conflict with each other.",
|
|
207
|
+
"ACTIONS: Update context.evidenceLog[], context.broadScanThemes[], context.contradictions[]"
|
|
208
|
+
]
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"id": "research-phase-2-deep-dive",
|
|
212
|
+
"title": "Research Phase 2/5: Deep Dive",
|
|
213
|
+
"runCondition": { "var": "researchPhase", "equals": 2 },
|
|
214
|
+
"prompt": "**OBJECTIVE**: Focus on the most promising themes from the broad scan. Investigate technical details, find implementation examples, and assess feasibility.",
|
|
215
|
+
"agentRole": "Systematic Researcher: Deep Dive Analyst",
|
|
216
|
+
"guidance": [
|
|
217
|
+
"Focus on the themes in context.broadScanThemes[].",
|
|
218
|
+
"Find specific, real-world implementation examples or case studies.",
|
|
219
|
+
"Assess complexity, dependencies, and requirements for each.",
|
|
220
|
+
"ACTIONS: Update context.evidenceLog[], context.deepDiveFindings[]"
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"id": "research-phase-3-contrarian",
|
|
225
|
+
"title": "Research Phase 3/5: Contrarian Research",
|
|
226
|
+
"runCondition": { "var": "researchPhase", "equals": 3 },
|
|
227
|
+
"prompt": "**OBJECTIVE**: Actively seek out opposing viewpoints, failure cases, and critiques of the promising solutions. The goal is to challenge assumptions.",
|
|
228
|
+
"agentRole": "Systematic Researcher: Devil's Advocate",
|
|
229
|
+
"guidance": [
|
|
230
|
+
"Search for '[solution] problems', '[approach] failures', 'why not use [tool]'.",
|
|
231
|
+
"Identify hidden assumptions in the mainstream approaches.",
|
|
232
|
+
"Look for entirely different paradigms that were missed.",
|
|
233
|
+
"ACTIONS: Update context.evidenceLog[], context.contrarianEvidence[]"
|
|
234
|
+
]
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"id": "research-phase-4-synthesis",
|
|
238
|
+
"title": "Research Phase 4/5: Evidence Synthesis",
|
|
239
|
+
"runCondition": { "var": "researchPhase", "equals": 4 },
|
|
240
|
+
"prompt": "**OBJECTIVE**: Consolidate all findings. Resolve contradictions, identify patterns, and build a coherent narrative of the solution landscape.",
|
|
241
|
+
"agentRole": "Systematic Researcher: Synthesizer",
|
|
242
|
+
"guidance": [
|
|
243
|
+
"Review evidence from all previous phases.",
|
|
244
|
+
"Where sources conflict, try to understand the reason for the disagreement.",
|
|
245
|
+
"Build a framework or matrix to compare the approaches.",
|
|
246
|
+
"ACTIONS: Update context.synthesisFramework, context.evidenceGaps[]"
|
|
247
|
+
]
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"id": "research-phase-5-gap-filling",
|
|
251
|
+
"title": "Research Phase 5/5: Gap Filling & Closure",
|
|
252
|
+
"runCondition": { "var": "researchPhase", "equals": 5 },
|
|
253
|
+
"prompt": "**OBJECTIVE**: Address the specific, critical unknowns identified during synthesis. Verify key assumptions and prepare for solution generation.",
|
|
254
|
+
"agentRole": "Systematic Researcher: Finisher",
|
|
255
|
+
"guidance": [
|
|
256
|
+
"Focus only on the critical gaps listed in context.evidenceGaps[].",
|
|
257
|
+
"Perform targeted searches to answer these specific questions.",
|
|
258
|
+
"This is the final research step. The goal is to be 'done', not perfect.",
|
|
259
|
+
"ACTIONS: Update context.evidenceLog[], set context.researchComplete = true"
|
|
260
|
+
]
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"id": "research-phase-validation",
|
|
264
|
+
"title": "Validation: Research Quality Check",
|
|
265
|
+
"prompt": "**OBJECTIVE**: After each research phase, perform a quick quality check.",
|
|
266
|
+
"agentRole": "Quality Analyst",
|
|
267
|
+
"guidance": [
|
|
268
|
+
"EVIDENCE CHECK: Have we gathered at least 3 new sources in this phase? (unless it was gap-filling).",
|
|
269
|
+
"QUALITY CHECK: Is there at least one 'High' or 'Medium' grade source?",
|
|
270
|
+
"SATURATION CHECK: Use checkSaturation() to assess if we are still gathering novel information. If not, we can consider exiting the loop early by setting context.researchComplete = true.",
|
|
271
|
+
"ACTIONS: Update context.qualityMetrics[]"
|
|
272
|
+
]
|
|
273
|
+
}
|
|
274
|
+
]
|
|
275
|
+
},
|
|
155
276
|
{
|
|
156
277
|
"id": "phase-3-context-documentation",
|
|
157
278
|
"runCondition": {"var": "explorationComplexity", "not_equals": "Simple"},
|
|
@@ -168,11 +289,71 @@
|
|
|
168
289
|
],
|
|
169
290
|
"requireConfirmation": false
|
|
170
291
|
},
|
|
292
|
+
{
|
|
293
|
+
"id": "phase-3a-prepare-solutions",
|
|
294
|
+
"title": "Phase 3a: Prepare Solution Generation",
|
|
295
|
+
"runCondition": {"var": "explorationComplexity", "not_equals": "Simple"},
|
|
296
|
+
"prompt": "**PREPARE SOLUTION GENERATION**\n\nBased on your research findings, prepare for systematic solution generation:\n\n**SETUP TASKS:**\n1. Review research synthesis from Phase 2c\n2. Identify top solution categories/approaches\n3. Create solution generation framework\n\n**CREATE SOLUTION APPROACHES ARRAY:**\nSet context.solutionApproaches with these 5 types:\n```json\n[\n {\"type\": \"Quick/Simple\", \"focus\": \"Minimal time, proven approaches, immediate value\"},\n {\"type\": \"Thorough/Proven\", \"focus\": \"Best practices, comprehensive, long-term sustainability\"},\n {\"type\": \"Creative/Novel\", \"focus\": \"Innovation, emerging tech, competitive advantage\"},\n {\"type\": \"Optimal/Balanced\", \"focus\": \"Best trade-offs, practical yet forward-thinking\"},\n {\"type\": \"Contrarian/Alternative\", \"focus\": \"Challenge assumptions, overlooked approaches\"}\n]\n```\n\n**Also set:**\n- context.solutionCriteria[] from research findings\n- context.evaluationFramework for comparing solutions\n- context.userConstraints from Phase 0a\n\n**This enables the next loop to generate each solution type systematically.**",
|
|
297
|
+
"agentRole": "You are preparing the solution generation phase by creating a structured framework based on research findings.",
|
|
298
|
+
"guidance": [
|
|
299
|
+
"This step makes the loop cleaner by preparing the array",
|
|
300
|
+
"Each solution type should address different user needs",
|
|
301
|
+
"Framework should incorporate research insights"
|
|
302
|
+
],
|
|
303
|
+
"requireConfirmation": false
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"id": "phase-3b-solution-generation-loop",
|
|
307
|
+
"type": "loop",
|
|
308
|
+
"title": "Phase 3b: Diverse Solution Portfolio Generation",
|
|
309
|
+
"runCondition": {"var": "explorationComplexity", "not_equals": "Simple"},
|
|
310
|
+
"loop": {
|
|
311
|
+
"type": "forEach",
|
|
312
|
+
"items": "solutionApproaches",
|
|
313
|
+
"itemVar": "approach",
|
|
314
|
+
"indexVar": "solutionIndex",
|
|
315
|
+
"maxIterations": 5
|
|
316
|
+
},
|
|
317
|
+
"body": [
|
|
318
|
+
{
|
|
319
|
+
"id": "generate-solution",
|
|
320
|
+
"title": "Generate {{approach.type}} Solution ({{solutionIndex + 1}}/5)",
|
|
321
|
+
"prompt": "**GENERATE SOLUTION: {{approach.type}}**\n\n**Focus for this solution type**: {{approach.focus}}\n\n**DIVERGENT THINKING MODE - NO JUDGMENT**\nYou are in pure generation mode. Do NOT evaluate, compare, or judge this solution against others. Focus solely on creating a complete solution that embodies the {{approach.type}} approach.\n\n**SOLUTION REQUIREMENTS:**\n1. Generate a solution that embodies the {{approach.type}} approach\n2. Base it on evidence from all research phases\n3. Make it genuinely different from other solutions (not just variations)\n4. DEFER ALL JUDGMENT - no scoring, ranking, or comparison\n\n**INCORPORATE USER CONTEXT:**\n- Apply all relevant rules from context.userRules[]\n- Respect constraints from context.constraints[]\n- Align with organizational standards and preferences\n- Consider environment-specific factors\n\n**SOLUTION STRUCTURE:**\n1. **Core Approach**: Clear description (what makes this {{approach.type}}?)\n2. **Implementation Path**: 3-5 key steps to execute\n3. **Evidence Base**: Which research findings support this approach?\n4. **Key Features**: What distinguishes this approach?\n5. **Resource Requirements**: What's needed to implement?\n6. **Success Indicators**: Observable outcomes when working\n\n**NO EVALUATION ELEMENTS:**\n- Do NOT include confidence scores\n- Do NOT compare to other solutions\n- Do NOT rank or judge quality\n- Simply generate and document\n\n**ACTIONS:**\n- generateSolution({{solutionIndex}}, '{{approach.type}}')\n- Store complete solution in context.solutions[{{solutionIndex}}]\n- Track which evidence supports this approach",
|
|
322
|
+
"agentRole": "You are in DIVERGENT THINKING mode, generating the {{approach.type}} solution. Focus on creation without judgment. Draw from research to build a complete solution.",
|
|
323
|
+
"guidance": [
|
|
324
|
+
"DIVERGENT PHASE: Generate without evaluating or comparing",
|
|
325
|
+
"Each solution should be genuinely different, not just variations",
|
|
326
|
+
"Ground each solution in evidence from research phases",
|
|
327
|
+
"Align with user rules and preferences from Phase 0a",
|
|
328
|
+
"Include enough detail to be actionable",
|
|
329
|
+
"Reference specific sources from evidenceLog",
|
|
330
|
+
"If a solution conflicts with user rules, note it factually without judgment",
|
|
331
|
+
"DEFER ALL EVALUATION until Phase 4"
|
|
332
|
+
],
|
|
333
|
+
"hasValidation": true,
|
|
334
|
+
"validationCriteria": {
|
|
335
|
+
"and": [
|
|
336
|
+
{
|
|
337
|
+
"type": "contains",
|
|
338
|
+
"value": "Evidence:",
|
|
339
|
+
"message": "Must include evidence section"
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
"type": "contains",
|
|
343
|
+
"value": "Key Features:",
|
|
344
|
+
"message": "Must describe distinguishing features"
|
|
345
|
+
}
|
|
346
|
+
]
|
|
347
|
+
},
|
|
348
|
+
"requireConfirmation": false
|
|
349
|
+
}
|
|
350
|
+
]
|
|
351
|
+
},
|
|
171
352
|
{
|
|
172
353
|
"id": "phase-4-option-evaluation",
|
|
173
354
|
"runCondition": {"var": "explorationComplexity", "not_equals": "Simple"},
|
|
174
|
-
"title": "Phase 4:
|
|
175
|
-
"prompt": "**PREP**: Define evaluation criteria based on clarified requirements, constraints, and priorities.\n\n**IMPLEMENT**: \n1. Create weighted scoring matrix with 4-6 evaluation criteria based on clarifications\n2. Score each option quantitatively (1-10 scale) with detailed rationale\n3. Calculate weighted scores and rank options\n4. Perform sensitivity analysis on key criteria weights\n5. Identify decision breakpoints and scenario dependencies\n6. Document evaluation methodology and assumptions\n\n**VERIFY**: Ensure evaluation is objective, comprehensive, and incorporates all clarified priorities.",
|
|
355
|
+
"title": "Phase 4: CONVERGENT THINKING - Option Evaluation & Ranking",
|
|
356
|
+
"prompt": "**TRANSITION TO CONVERGENT THINKING MODE**\n\nThe divergent generation phase is complete. Now shift to analytical, convergent thinking to systematically evaluate all solutions.\n\n**CONVERGENT THINKING PRINCIPLES:**\n- This is NOW the time for judgment and comparison\n- Apply critical analysis to all generated solutions\n- Use evidence-based evaluation criteria\n- Be rigorous and systematic\n\n**PREP**: Define evaluation criteria based on clarified requirements, constraints, and priorities.\n\n**IMPLEMENT**: \n1. Create weighted scoring matrix with 4-6 evaluation criteria based on clarifications\n2. Score each option quantitatively (1-10 scale) with detailed rationale\n3. Calculate weighted scores and rank options\n4. Perform sensitivity analysis on key criteria weights\n5. Identify decision breakpoints and scenario dependencies\n6. Document evaluation methodology and assumptions\n\n**VERIFY**: Ensure evaluation is objective, comprehensive, and incorporates all clarified priorities.",
|
|
176
357
|
"agentRole": "You are an objective decision analyst expert in multi-criteria evaluation and quantitative assessment. Your expertise lies in translating qualitative factors into structured, defensible evaluations.",
|
|
177
358
|
"guidance": [
|
|
178
359
|
"Use at least 4-6 evaluation criteria based on clarifications",
|
|
@@ -200,7 +381,7 @@
|
|
|
200
381
|
"id": "phase-4b-devil-advocate-review",
|
|
201
382
|
"runCondition": {"var": "explorationComplexity", "not_equals": "Simple"},
|
|
202
383
|
"title": "Phase 4b: Devil's Advocate Evaluation Review",
|
|
203
|
-
"prompt": "Perform a 'devil's advocate' review of your
|
|
384
|
+
"prompt": "Perform a rigorous 'devil's advocate' review of your solutions and evaluation. This is a mandatory adversarial self-challenge to prevent overconfidence and blind spots.\n\n**STRUCTURED ADVERSARIAL ANALYSIS:**\n\n1. **Evidence Challenge**: For each solution's top 3 claims:\n - Is the evidence truly supporting this claim?\n - Are there contradicting sources we dismissed?\n - What evidence grade did we assign vs. what it deserves?\n\n2. **Hidden Failure Modes**: For the top-ranked solution:\n - What could cause catastrophic failure?\n - What assumptions could be completely wrong?\n - What context changes would invalidate this approach?\n\n3. **Overlooked Alternatives**:\n - What hybrid approaches could combine solution strengths?\n - What completely different paradigm did we miss?\n - Are we solving the right problem?\n\n4. **Bias Detection**:\n - Did we favor familiar over novel?\n - Did recent sources overshadow established wisdom?\n - Did domain bias affect our evaluation?\n\n5. **Confidence Calibration**:\n - Where are we overconfident?\n - What unknowns are we treating as knowns?\n - calculateConfidence() with penalty for identified weaknesses\n\n**OUTPUT REQUIREMENTS:**\n- Identify at least 3 significant concerns\n- Propose specific remedies for each\n- Re-calculate confidence scores\n- Set context.confidenceScore (1-10) for overall analysis quality\n- Set context.criticalIssues[] with must-address items\n\ntriggerDeepDive() if confidence drops below 0.7",
|
|
204
385
|
"agentRole": "You are a skeptical but fair senior research analyst with 15+ years of experience in strategic decision analysis. Your role is to identify potential blind spots, biases, and overlooked factors in evaluation methodologies. You excel at constructive criticism that strengthens analysis rather than destroys it.",
|
|
205
386
|
"guidance": [
|
|
206
387
|
"This is critical thinking step to find weaknesses in your own analysis",
|