@stackmemoryai/stackmemory 0.3.22 → 0.3.24
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/cli/commands/ralph.js +294 -0
- package/dist/cli/commands/ralph.js.map +7 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +2 -2
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js +586 -0
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js.map +7 -0
- package/dist/integrations/ralph/context/context-budget-manager.js +297 -0
- package/dist/integrations/ralph/context/context-budget-manager.js.map +7 -0
- package/dist/integrations/ralph/context/stackmemory-context-loader.js +356 -0
- package/dist/integrations/ralph/context/stackmemory-context-loader.js.map +7 -0
- package/dist/integrations/ralph/index.js +14 -0
- package/dist/integrations/ralph/index.js.map +7 -0
- package/dist/integrations/ralph/learning/pattern-learner.js +397 -0
- package/dist/integrations/ralph/learning/pattern-learner.js.map +7 -0
- package/dist/integrations/ralph/lifecycle/iteration-lifecycle.js +444 -0
- package/dist/integrations/ralph/lifecycle/iteration-lifecycle.js.map +7 -0
- package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js +459 -0
- package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js.map +7 -0
- package/dist/integrations/ralph/performance/performance-optimizer.js +354 -0
- package/dist/integrations/ralph/performance/performance-optimizer.js.map +7 -0
- package/dist/integrations/ralph/ralph-integration-demo.js +178 -0
- package/dist/integrations/ralph/ralph-integration-demo.js.map +7 -0
- package/dist/integrations/ralph/state/state-reconciler.js +400 -0
- package/dist/integrations/ralph/state/state-reconciler.js.map +7 -0
- package/dist/integrations/ralph/swarm/swarm-coordinator.js +487 -0
- package/dist/integrations/ralph/swarm/swarm-coordinator.js.map +7 -0
- package/dist/integrations/ralph/types.js +1 -0
- package/dist/integrations/ralph/types.js.map +7 -0
- package/dist/integrations/ralph/visualization/ralph-debugger.js +581 -0
- package/dist/integrations/ralph/visualization/ralph-debugger.js.map +7 -0
- package/package.json +1 -1
- package/scripts/deploy-ralph-swarm.sh +365 -0
- package/scripts/ralph-integration-test.js +274 -0
- package/scripts/ralph-loop-implementation.js +404 -0
- package/scripts/swarm-monitor.js +509 -0
- package/scripts/test-parallel-swarms.js +443 -0
- package/scripts/testing/ralph-cli-test.js +88 -0
- package/scripts/testing/ralph-integration-validation.js +727 -0
- package/scripts/testing/ralph-swarm-test-scenarios.js +613 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Ralph Swarm Deployment Script
|
|
4
|
+
# Ensures parallel execution and monitoring capabilities
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
9
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
10
|
+
SWARM_DIR="$PROJECT_ROOT/.swarm"
|
|
11
|
+
SWARM_LOGS="$SWARM_DIR/logs"
|
|
12
|
+
SWARM_PIDS="$SWARM_DIR/pids"
|
|
13
|
+
SWARM_STATUS="$SWARM_DIR/status"
|
|
14
|
+
|
|
15
|
+
# Colors for output
|
|
16
|
+
RED='\033[0;31m'
|
|
17
|
+
GREEN='\033[0;32m'
|
|
18
|
+
YELLOW='\033[1;33m'
|
|
19
|
+
BLUE='\033[0;34m'
|
|
20
|
+
NC='\033[0m' # No Color
|
|
21
|
+
|
|
22
|
+
# Ensure directories exist
|
|
23
|
+
mkdir -p "$SWARM_LOGS" "$SWARM_PIDS" "$SWARM_STATUS"
|
|
24
|
+
|
|
25
|
+
# Function to print colored output
|
|
26
|
+
print_status() {
|
|
27
|
+
echo -e "${GREEN}[SWARM]${NC} $1"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
print_error() {
|
|
31
|
+
echo -e "${RED}[ERROR]${NC} $1"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
print_warning() {
|
|
35
|
+
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
print_info() {
|
|
39
|
+
echo -e "${BLUE}[INFO]${NC} $1"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# Function to check prerequisites
|
|
43
|
+
check_prerequisites() {
|
|
44
|
+
print_status "Checking prerequisites..."
|
|
45
|
+
|
|
46
|
+
# Check Node.js
|
|
47
|
+
if ! command -v node &> /dev/null; then
|
|
48
|
+
print_error "Node.js is not installed"
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Check if project is built
|
|
53
|
+
if [ ! -d "$PROJECT_ROOT/dist" ]; then
|
|
54
|
+
print_warning "Project not built. Building now..."
|
|
55
|
+
cd "$PROJECT_ROOT"
|
|
56
|
+
npm run build
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Check database connection
|
|
60
|
+
if [ -z "$DATABASE_URL" ] && [ ! -f "$HOME/.stackmemory/projects.db" ]; then
|
|
61
|
+
print_warning "No database configured. Using SQLite fallback."
|
|
62
|
+
export DATABASE_URL="sqlite://$HOME/.stackmemory/projects.db"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
print_status "Prerequisites check complete"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
# Function to initialize swarm environment
|
|
69
|
+
initialize_swarm() {
|
|
70
|
+
print_status "Initializing swarm environment..."
|
|
71
|
+
|
|
72
|
+
# Create swarm configuration
|
|
73
|
+
cat > "$SWARM_DIR/config.json" <<EOF
|
|
74
|
+
{
|
|
75
|
+
"maxAgents": 10,
|
|
76
|
+
"coordinationInterval": 30000,
|
|
77
|
+
"driftDetectionThreshold": 5,
|
|
78
|
+
"freshStartInterval": 3600000,
|
|
79
|
+
"conflictResolutionStrategy": "expertise",
|
|
80
|
+
"enableDynamicPlanning": true,
|
|
81
|
+
"pathologicalBehaviorDetection": true,
|
|
82
|
+
"parallelExecution": true,
|
|
83
|
+
"monitoring": {
|
|
84
|
+
"enabled": true,
|
|
85
|
+
"port": 3456,
|
|
86
|
+
"metricsInterval": 5000
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
EOF
|
|
90
|
+
|
|
91
|
+
print_status "Swarm configuration created"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Function to launch swarm with project
|
|
95
|
+
launch_swarm() {
|
|
96
|
+
local project="$1"
|
|
97
|
+
local agents="${2:-architect,developer,tester,reviewer}"
|
|
98
|
+
local max_agents="${3:-5}"
|
|
99
|
+
|
|
100
|
+
print_status "Launching swarm for project: $project"
|
|
101
|
+
print_info "Agents: $agents"
|
|
102
|
+
print_info "Max agents: $max_agents"
|
|
103
|
+
|
|
104
|
+
# Generate swarm ID
|
|
105
|
+
local swarm_id="swarm-$(date +%Y%m%d-%H%M%S)-$$"
|
|
106
|
+
local log_file="$SWARM_LOGS/$swarm_id.log"
|
|
107
|
+
local pid_file="$SWARM_PIDS/$swarm_id.pid"
|
|
108
|
+
|
|
109
|
+
# Launch swarm in background
|
|
110
|
+
nohup node "$PROJECT_ROOT/dist/cli/index.js" ralph swarm \
|
|
111
|
+
"$project" \
|
|
112
|
+
--agents "$agents" \
|
|
113
|
+
--max-agents "$max_agents" \
|
|
114
|
+
> "$log_file" 2>&1 &
|
|
115
|
+
|
|
116
|
+
local pid=$!
|
|
117
|
+
echo $pid > "$pid_file"
|
|
118
|
+
|
|
119
|
+
# Store swarm metadata
|
|
120
|
+
cat > "$SWARM_STATUS/$swarm_id.json" <<EOF
|
|
121
|
+
{
|
|
122
|
+
"id": "$swarm_id",
|
|
123
|
+
"pid": $pid,
|
|
124
|
+
"project": "$project",
|
|
125
|
+
"agents": "$agents",
|
|
126
|
+
"maxAgents": $max_agents,
|
|
127
|
+
"startTime": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
|
|
128
|
+
"status": "running",
|
|
129
|
+
"logFile": "$log_file"
|
|
130
|
+
}
|
|
131
|
+
EOF
|
|
132
|
+
|
|
133
|
+
print_status "Swarm launched with ID: $swarm_id (PID: $pid)"
|
|
134
|
+
echo "$swarm_id"
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
# Function to launch parallel swarms
|
|
138
|
+
launch_parallel_swarms() {
|
|
139
|
+
print_status "Launching parallel swarms..."
|
|
140
|
+
|
|
141
|
+
local swarm_ids=()
|
|
142
|
+
|
|
143
|
+
# Swarm 1: Architecture and design
|
|
144
|
+
swarm_ids+=("$(launch_swarm "Design system architecture" "architect,developer" 3)")
|
|
145
|
+
sleep 2
|
|
146
|
+
|
|
147
|
+
# Swarm 2: Core implementation
|
|
148
|
+
swarm_ids+=("$(launch_swarm "Implement core features" "developer,tester" 4)")
|
|
149
|
+
sleep 2
|
|
150
|
+
|
|
151
|
+
# Swarm 3: Testing and quality
|
|
152
|
+
swarm_ids+=("$(launch_swarm "Create comprehensive test suite" "tester,reviewer" 3)")
|
|
153
|
+
sleep 2
|
|
154
|
+
|
|
155
|
+
# Swarm 4: Documentation
|
|
156
|
+
swarm_ids+=("$(launch_swarm "Generate documentation" "documenter,developer" 2)")
|
|
157
|
+
|
|
158
|
+
print_status "Launched ${#swarm_ids[@]} parallel swarms"
|
|
159
|
+
|
|
160
|
+
# Return swarm IDs for monitoring
|
|
161
|
+
echo "${swarm_ids[@]}"
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# Function to monitor swarm status
|
|
165
|
+
monitor_swarm() {
|
|
166
|
+
local swarm_id="$1"
|
|
167
|
+
|
|
168
|
+
if [ ! -f "$SWARM_STATUS/$swarm_id.json" ]; then
|
|
169
|
+
print_error "Swarm $swarm_id not found"
|
|
170
|
+
return 1
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
local pid=$(jq -r '.pid' "$SWARM_STATUS/$swarm_id.json")
|
|
174
|
+
local project=$(jq -r '.project' "$SWARM_STATUS/$swarm_id.json")
|
|
175
|
+
local log_file=$(jq -r '.logFile' "$SWARM_STATUS/$swarm_id.json")
|
|
176
|
+
|
|
177
|
+
if ps -p $pid > /dev/null 2>&1; then
|
|
178
|
+
print_status "Swarm $swarm_id (PID: $pid) is RUNNING"
|
|
179
|
+
print_info "Project: $project"
|
|
180
|
+
print_info "Recent logs:"
|
|
181
|
+
tail -n 5 "$log_file" | sed 's/^/ /'
|
|
182
|
+
else
|
|
183
|
+
print_warning "Swarm $swarm_id (PID: $pid) has STOPPED"
|
|
184
|
+
# Update status
|
|
185
|
+
jq '.status = "stopped"' "$SWARM_STATUS/$swarm_id.json" > "$SWARM_STATUS/$swarm_id.json.tmp"
|
|
186
|
+
mv "$SWARM_STATUS/$swarm_id.json.tmp" "$SWARM_STATUS/$swarm_id.json"
|
|
187
|
+
fi
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
# Function to monitor all active swarms
|
|
191
|
+
monitor_all_swarms() {
|
|
192
|
+
print_status "Monitoring all active swarms..."
|
|
193
|
+
|
|
194
|
+
for status_file in "$SWARM_STATUS"/*.json; do
|
|
195
|
+
if [ -f "$status_file" ]; then
|
|
196
|
+
local swarm_id=$(basename "$status_file" .json)
|
|
197
|
+
monitor_swarm "$swarm_id"
|
|
198
|
+
echo ""
|
|
199
|
+
fi
|
|
200
|
+
done
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
# Function to stop swarm
|
|
204
|
+
stop_swarm() {
|
|
205
|
+
local swarm_id="$1"
|
|
206
|
+
|
|
207
|
+
if [ ! -f "$SWARM_PIDS/$swarm_id.pid" ]; then
|
|
208
|
+
print_error "Swarm $swarm_id not found"
|
|
209
|
+
return 1
|
|
210
|
+
fi
|
|
211
|
+
|
|
212
|
+
local pid=$(cat "$SWARM_PIDS/$swarm_id.pid")
|
|
213
|
+
|
|
214
|
+
if ps -p $pid > /dev/null 2>&1; then
|
|
215
|
+
print_status "Stopping swarm $swarm_id (PID: $pid)..."
|
|
216
|
+
kill -TERM $pid
|
|
217
|
+
sleep 2
|
|
218
|
+
|
|
219
|
+
# Force kill if still running
|
|
220
|
+
if ps -p $pid > /dev/null 2>&1; then
|
|
221
|
+
print_warning "Force stopping swarm $swarm_id..."
|
|
222
|
+
kill -KILL $pid
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
print_status "Swarm $swarm_id stopped"
|
|
226
|
+
else
|
|
227
|
+
print_info "Swarm $swarm_id is not running"
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
# Update status
|
|
231
|
+
if [ -f "$SWARM_STATUS/$swarm_id.json" ]; then
|
|
232
|
+
jq '.status = "stopped"' "$SWARM_STATUS/$swarm_id.json" > "$SWARM_STATUS/$swarm_id.json.tmp"
|
|
233
|
+
mv "$SWARM_STATUS/$swarm_id.json.tmp" "$SWARM_STATUS/$swarm_id.json"
|
|
234
|
+
fi
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
# Function to clean up old swarms
|
|
238
|
+
cleanup_swarms() {
|
|
239
|
+
print_status "Cleaning up old swarm data..."
|
|
240
|
+
|
|
241
|
+
local count=0
|
|
242
|
+
for status_file in "$SWARM_STATUS"/*.json; do
|
|
243
|
+
if [ -f "$status_file" ]; then
|
|
244
|
+
local status=$(jq -r '.status' "$status_file")
|
|
245
|
+
if [ "$status" = "stopped" ]; then
|
|
246
|
+
local swarm_id=$(basename "$status_file" .json)
|
|
247
|
+
rm -f "$status_file"
|
|
248
|
+
rm -f "$SWARM_PIDS/$swarm_id.pid"
|
|
249
|
+
count=$((count + 1))
|
|
250
|
+
fi
|
|
251
|
+
fi
|
|
252
|
+
done
|
|
253
|
+
|
|
254
|
+
print_status "Cleaned up $count stopped swarms"
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
# Function to show swarm dashboard
|
|
258
|
+
show_dashboard() {
|
|
259
|
+
clear
|
|
260
|
+
echo "========================================"
|
|
261
|
+
echo " RALPH SWARM DASHBOARD"
|
|
262
|
+
echo "========================================"
|
|
263
|
+
echo ""
|
|
264
|
+
|
|
265
|
+
local running=0
|
|
266
|
+
local stopped=0
|
|
267
|
+
local total=0
|
|
268
|
+
|
|
269
|
+
for status_file in "$SWARM_STATUS"/*.json; do
|
|
270
|
+
if [ -f "$status_file" ]; then
|
|
271
|
+
total=$((total + 1))
|
|
272
|
+
local status=$(jq -r '.status' "$status_file")
|
|
273
|
+
if [ "$status" = "running" ]; then
|
|
274
|
+
running=$((running + 1))
|
|
275
|
+
else
|
|
276
|
+
stopped=$((stopped + 1))
|
|
277
|
+
fi
|
|
278
|
+
fi
|
|
279
|
+
done
|
|
280
|
+
|
|
281
|
+
echo "Total Swarms: $total"
|
|
282
|
+
echo "Running: $running"
|
|
283
|
+
echo "Stopped: $stopped"
|
|
284
|
+
echo ""
|
|
285
|
+
echo "----------------------------------------"
|
|
286
|
+
echo "Active Swarms:"
|
|
287
|
+
echo "----------------------------------------"
|
|
288
|
+
|
|
289
|
+
for status_file in "$SWARM_STATUS"/*.json; do
|
|
290
|
+
if [ -f "$status_file" ]; then
|
|
291
|
+
local status=$(jq -r '.status' "$status_file")
|
|
292
|
+
if [ "$status" = "running" ]; then
|
|
293
|
+
local swarm_id=$(basename "$status_file" .json)
|
|
294
|
+
local project=$(jq -r '.project' "$status_file")
|
|
295
|
+
local agents=$(jq -r '.agents' "$status_file")
|
|
296
|
+
echo ""
|
|
297
|
+
echo "ID: $swarm_id"
|
|
298
|
+
echo "Project: $project"
|
|
299
|
+
echo "Agents: $agents"
|
|
300
|
+
echo "----------------------------------------"
|
|
301
|
+
fi
|
|
302
|
+
fi
|
|
303
|
+
done
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
# Main command handler
|
|
307
|
+
case "${1:-}" in
|
|
308
|
+
"start")
|
|
309
|
+
check_prerequisites
|
|
310
|
+
initialize_swarm
|
|
311
|
+
shift
|
|
312
|
+
launch_swarm "$@"
|
|
313
|
+
;;
|
|
314
|
+
"parallel")
|
|
315
|
+
check_prerequisites
|
|
316
|
+
initialize_swarm
|
|
317
|
+
launch_parallel_swarms
|
|
318
|
+
;;
|
|
319
|
+
"monitor")
|
|
320
|
+
if [ -n "${2:-}" ]; then
|
|
321
|
+
monitor_swarm "$2"
|
|
322
|
+
else
|
|
323
|
+
monitor_all_swarms
|
|
324
|
+
fi
|
|
325
|
+
;;
|
|
326
|
+
"stop")
|
|
327
|
+
if [ -z "${2:-}" ]; then
|
|
328
|
+
print_error "Please provide swarm ID"
|
|
329
|
+
exit 1
|
|
330
|
+
fi
|
|
331
|
+
stop_swarm "$2"
|
|
332
|
+
;;
|
|
333
|
+
"cleanup")
|
|
334
|
+
cleanup_swarms
|
|
335
|
+
;;
|
|
336
|
+
"dashboard")
|
|
337
|
+
show_dashboard
|
|
338
|
+
;;
|
|
339
|
+
"help"|"--help"|"-h"|"")
|
|
340
|
+
echo "Ralph Swarm Deployment Script"
|
|
341
|
+
echo ""
|
|
342
|
+
echo "Usage: $0 [command] [options]"
|
|
343
|
+
echo ""
|
|
344
|
+
echo "Commands:"
|
|
345
|
+
echo " start <project> [agents] [max] Launch a swarm for a project"
|
|
346
|
+
echo " parallel Launch multiple parallel swarms"
|
|
347
|
+
echo " monitor [swarm_id] Monitor swarm(s) status"
|
|
348
|
+
echo " stop <swarm_id> Stop a specific swarm"
|
|
349
|
+
echo " cleanup Clean up stopped swarms"
|
|
350
|
+
echo " dashboard Show swarm dashboard"
|
|
351
|
+
echo " help Show this help message"
|
|
352
|
+
echo ""
|
|
353
|
+
echo "Examples:"
|
|
354
|
+
echo " $0 start \"Build a todo app\" \"developer,tester\" 4"
|
|
355
|
+
echo " $0 parallel"
|
|
356
|
+
echo " $0 monitor swarm-20240120-123456-1234"
|
|
357
|
+
echo " $0 stop swarm-20240120-123456-1234"
|
|
358
|
+
echo " $0 dashboard"
|
|
359
|
+
;;
|
|
360
|
+
*)
|
|
361
|
+
print_error "Unknown command: $1"
|
|
362
|
+
echo "Run '$0 help' for usage information"
|
|
363
|
+
exit 1
|
|
364
|
+
;;
|
|
365
|
+
esac
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Ralph-StackMemory Integration Test Script
|
|
5
|
+
* Simple CLI to test the integration functionality
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { RalphIntegrationDemo } from '../dist/integrations/ralph/ralph-integration-demo.js';
|
|
9
|
+
import { performance } from 'perf_hooks';
|
|
10
|
+
|
|
11
|
+
async function main() {
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
const command = args[0] || 'demo';
|
|
14
|
+
|
|
15
|
+
console.log('\n🧪 Ralph-StackMemory Integration Test');
|
|
16
|
+
console.log('=====================================\n');
|
|
17
|
+
|
|
18
|
+
const startTime = performance.now();
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
switch (command) {
|
|
22
|
+
case 'demo':
|
|
23
|
+
await runDemo();
|
|
24
|
+
break;
|
|
25
|
+
case 'quick':
|
|
26
|
+
await runQuickTest();
|
|
27
|
+
break;
|
|
28
|
+
case 'validate':
|
|
29
|
+
await runValidation();
|
|
30
|
+
break;
|
|
31
|
+
default:
|
|
32
|
+
showUsage();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const endTime = performance.now();
|
|
37
|
+
const duration = Math.round(endTime - startTime);
|
|
38
|
+
|
|
39
|
+
console.log(`\n✅ Test completed successfully in ${duration}ms`);
|
|
40
|
+
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error(`\n❌ Test failed: ${error.message}`);
|
|
43
|
+
|
|
44
|
+
if (process.env.DEBUG) {
|
|
45
|
+
console.error('\nDebug info:');
|
|
46
|
+
console.error(error.stack);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function runDemo() {
|
|
54
|
+
console.log('🎬 Running full integration demo...\n');
|
|
55
|
+
|
|
56
|
+
const demo = new RalphIntegrationDemo();
|
|
57
|
+
await demo.run();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function runQuickTest() {
|
|
61
|
+
console.log('⚡ Running quick validation test...\n');
|
|
62
|
+
|
|
63
|
+
// Import the core classes to test they load correctly
|
|
64
|
+
try {
|
|
65
|
+
await import('../dist/integrations/ralph/index.js');
|
|
66
|
+
console.log('✓ Core bridge class loaded');
|
|
67
|
+
|
|
68
|
+
const { ContextBudgetManager } = await import('../dist/integrations/ralph/index.js');
|
|
69
|
+
console.log('✓ Context budget manager loaded');
|
|
70
|
+
|
|
71
|
+
const { StateReconciler } = await import('../dist/integrations/ralph/index.js');
|
|
72
|
+
console.log('✓ State reconciler loaded');
|
|
73
|
+
|
|
74
|
+
await import('../dist/integrations/ralph/index.js');
|
|
75
|
+
console.log('✓ Iteration lifecycle loaded');
|
|
76
|
+
|
|
77
|
+
await import('../dist/integrations/ralph/index.js');
|
|
78
|
+
console.log('✓ Performance optimizer loaded');
|
|
79
|
+
|
|
80
|
+
// Test basic instantiation
|
|
81
|
+
const budgetManager = new ContextBudgetManager();
|
|
82
|
+
const tokenEstimate = budgetManager.estimateTokens('Hello, world!');
|
|
83
|
+
console.log(`✓ Token estimation working: ${tokenEstimate} tokens`);
|
|
84
|
+
|
|
85
|
+
new StateReconciler();
|
|
86
|
+
console.log('✓ State reconciler instantiated');
|
|
87
|
+
|
|
88
|
+
console.log('\n🎯 All core components validated successfully!');
|
|
89
|
+
|
|
90
|
+
} catch (error) {
|
|
91
|
+
throw new Error(`Component loading failed: ${error.message}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function runValidation() {
|
|
96
|
+
console.log('🔍 Running detailed validation...\n');
|
|
97
|
+
|
|
98
|
+
// Test context budget manager
|
|
99
|
+
await testContextBudgetManager();
|
|
100
|
+
|
|
101
|
+
// Test state reconciler
|
|
102
|
+
await testStateReconciler();
|
|
103
|
+
|
|
104
|
+
// Test performance optimizer
|
|
105
|
+
await testPerformanceOptimizer();
|
|
106
|
+
|
|
107
|
+
console.log('\n✨ All validation tests passed!');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function testContextBudgetManager() {
|
|
111
|
+
console.log('📊 Testing Context Budget Manager...');
|
|
112
|
+
|
|
113
|
+
const { ContextBudgetManager } = await import('../dist/integrations/ralph/index.js');
|
|
114
|
+
|
|
115
|
+
const manager = new ContextBudgetManager({
|
|
116
|
+
maxTokens: 100,
|
|
117
|
+
compressionEnabled: true
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Test token estimation
|
|
121
|
+
const shortText = 'Short text';
|
|
122
|
+
const longText = 'This is a much longer piece of text that should have more tokens estimated for it than the shorter version above.';
|
|
123
|
+
|
|
124
|
+
const shortTokens = manager.estimateTokens(shortText);
|
|
125
|
+
const longTokens = manager.estimateTokens(longText);
|
|
126
|
+
|
|
127
|
+
if (longTokens <= shortTokens) {
|
|
128
|
+
throw new Error('Token estimation not working correctly');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Test empty text
|
|
132
|
+
const emptyTokens = manager.estimateTokens('');
|
|
133
|
+
if (emptyTokens !== 0) {
|
|
134
|
+
throw new Error('Empty text should have 0 tokens');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
console.log(' ✓ Token estimation working correctly');
|
|
138
|
+
|
|
139
|
+
// Test usage tracking
|
|
140
|
+
const usage = manager.getUsage();
|
|
141
|
+
if (typeof usage.used !== 'number' || typeof usage.available !== 'number') {
|
|
142
|
+
throw new Error('Usage tracking not working');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
console.log(' ✓ Usage tracking functional');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function testStateReconciler() {
|
|
149
|
+
console.log('🔄 Testing State Reconciler...');
|
|
150
|
+
|
|
151
|
+
const { StateReconciler } = await import('../dist/integrations/ralph/index.js');
|
|
152
|
+
|
|
153
|
+
const reconciler = new StateReconciler({
|
|
154
|
+
precedence: ['git', 'files', 'memory'],
|
|
155
|
+
conflictResolution: 'automatic'
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Test conflict detection
|
|
159
|
+
const sources = [
|
|
160
|
+
{
|
|
161
|
+
type: 'git',
|
|
162
|
+
state: { iteration: 5, status: 'running' },
|
|
163
|
+
timestamp: Date.now(),
|
|
164
|
+
confidence: 0.9
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
type: 'files',
|
|
168
|
+
state: { iteration: 5, status: 'running' },
|
|
169
|
+
timestamp: Date.now(),
|
|
170
|
+
confidence: 0.95
|
|
171
|
+
}
|
|
172
|
+
];
|
|
173
|
+
|
|
174
|
+
const conflicts = reconciler.detectConflicts(sources);
|
|
175
|
+
if (conflicts.length !== 0) {
|
|
176
|
+
throw new Error('Should not detect conflicts in matching sources');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
console.log(' ✓ Conflict detection working');
|
|
180
|
+
|
|
181
|
+
// Test state sources
|
|
182
|
+
const gitState = await reconciler.getGitState();
|
|
183
|
+
const fileState = await reconciler.getFileState();
|
|
184
|
+
const memoryState = await reconciler.getMemoryState('test-loop');
|
|
185
|
+
|
|
186
|
+
if (gitState.type !== 'git' || fileState.type !== 'files' || memoryState.type !== 'memory') {
|
|
187
|
+
throw new Error('State source types incorrect');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
console.log(' ✓ State source loading functional');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async function testPerformanceOptimizer() {
|
|
194
|
+
console.log('⚡ Testing Performance Optimizer...');
|
|
195
|
+
|
|
196
|
+
const { PerformanceOptimizer } = await import('../dist/integrations/ralph/index.js');
|
|
197
|
+
|
|
198
|
+
const optimizer = new PerformanceOptimizer({
|
|
199
|
+
asyncSaves: true,
|
|
200
|
+
compressionLevel: 1,
|
|
201
|
+
cacheEnabled: true
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Test metrics
|
|
205
|
+
const metrics = optimizer.getMetrics();
|
|
206
|
+
const requiredMetrics = ['iterationTime', 'contextLoadTime', 'stateSaveTime', 'memoryUsage', 'tokenCount', 'cacheHitRate'];
|
|
207
|
+
|
|
208
|
+
for (const metric of requiredMetrics) {
|
|
209
|
+
if (typeof metrics[metric] !== 'number') {
|
|
210
|
+
throw new Error(`Missing or invalid metric: ${metric}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
console.log(' ✓ Performance metrics available');
|
|
215
|
+
|
|
216
|
+
// Test compression
|
|
217
|
+
const testData = { message: 'Hello, world!', array: [1, 2, 3, 4, 5] };
|
|
218
|
+
const compressed = await optimizer.compressData(testData);
|
|
219
|
+
|
|
220
|
+
if (compressed.compressed !== true) {
|
|
221
|
+
throw new Error('Data compression not working');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const decompressed = await optimizer.decompressData(compressed);
|
|
225
|
+
if (JSON.stringify(decompressed) !== JSON.stringify(testData)) {
|
|
226
|
+
throw new Error('Data decompression failed');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
console.log(' ✓ Compression/decompression working');
|
|
230
|
+
|
|
231
|
+
// Cleanup
|
|
232
|
+
optimizer.cleanup();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function showUsage() {
|
|
236
|
+
console.log(`
|
|
237
|
+
Usage: node ralph-integration-test.js [command]
|
|
238
|
+
|
|
239
|
+
Commands:
|
|
240
|
+
demo Run the full integration demonstration (default)
|
|
241
|
+
quick Quick validation of core components
|
|
242
|
+
validate Detailed validation of all functionality
|
|
243
|
+
|
|
244
|
+
Examples:
|
|
245
|
+
node ralph-integration-test.js
|
|
246
|
+
node ralph-integration-test.js quick
|
|
247
|
+
DEBUG=1 node ralph-integration-test.js validate
|
|
248
|
+
|
|
249
|
+
Environment Variables:
|
|
250
|
+
DEBUG=1 Show detailed error information
|
|
251
|
+
`);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Handle unhandled promise rejections
|
|
255
|
+
process.on('unhandledRejection', (reason, _promise) => {
|
|
256
|
+
console.error('\n💥 Unhandled Promise Rejection:');
|
|
257
|
+
console.error(reason);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// Handle uncaught exceptions
|
|
262
|
+
process.on('uncaughtException', (error) => {
|
|
263
|
+
console.error('\n💥 Uncaught Exception:');
|
|
264
|
+
console.error(error.message);
|
|
265
|
+
if (process.env.DEBUG) {
|
|
266
|
+
console.error(error.stack);
|
|
267
|
+
}
|
|
268
|
+
process.exit(1);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// Run if called directly
|
|
272
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
273
|
+
main().catch(console.error);
|
|
274
|
+
}
|