agi-farm 1.5.0 → 1.5.2
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 +39 -0
- package/openclaw.plugin.json +6 -1
- package/package.json +9 -1
- package/scripts/validate-config.js +38 -1
- package/server/dashboard.js +51 -3
package/README.md
CHANGED
|
@@ -686,6 +686,45 @@ The embedded `skills/agi-farm/SKILL.md` provides documentation reference for age
|
|
|
686
686
|
|
|
687
687
|
---
|
|
688
688
|
|
|
689
|
+
## 🔄 OpenClaw Compatibility
|
|
690
|
+
|
|
691
|
+
AGI Farm ensures compatibility with OpenClaw through **automated testing** and **proactive monitoring**:
|
|
692
|
+
|
|
693
|
+
### Automated Compatibility Testing
|
|
694
|
+
- **Weekly testing** against multiple OpenClaw versions (latest, previous, oldest-supported, beta)
|
|
695
|
+
- **Performance benchmarks** to detect regressions (load time, validation time thresholds)
|
|
696
|
+
- **API deprecation scanning** with automated replacement suggestions
|
|
697
|
+
- **Automated PR creation** for compatibility fixes when breaking changes detected
|
|
698
|
+
|
|
699
|
+
### Supported Versions
|
|
700
|
+
- **Minimum**: OpenClaw 1.0.0+
|
|
701
|
+
- **Tested**: Latest stable + previous stable + beta (when available)
|
|
702
|
+
- **Status**: All compatibility tests run weekly via GitHub Actions
|
|
703
|
+
|
|
704
|
+
### For Users
|
|
705
|
+
Check compatibility before upgrading OpenClaw:
|
|
706
|
+
```bash
|
|
707
|
+
# Check current OpenClaw version
|
|
708
|
+
openclaw --version
|
|
709
|
+
|
|
710
|
+
# Run validation
|
|
711
|
+
npm run validate
|
|
712
|
+
|
|
713
|
+
# View compatibility matrix
|
|
714
|
+
cat OPENCLAW_COMPATIBILITY.md
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### For Maintainers
|
|
718
|
+
The enhanced compatibility system includes:
|
|
719
|
+
- Multi-version testing matrix (4 versions tested)
|
|
720
|
+
- Performance regression detection (<5s load time, <3s validation)
|
|
721
|
+
- Automated issue creation when incompatibility detected
|
|
722
|
+
- Optional automated PR generation with suggested fixes
|
|
723
|
+
|
|
724
|
+
**See:** [OPENCLAW_COMPATIBILITY.md](OPENCLAW_COMPATIBILITY.md) for complete compatibility guide.
|
|
725
|
+
|
|
726
|
+
---
|
|
727
|
+
|
|
689
728
|
## 🤝 Contributing
|
|
690
729
|
|
|
691
730
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,10 +2,15 @@
|
|
|
2
2
|
"id": "agi-farm",
|
|
3
3
|
"kind": "team-orchestration",
|
|
4
4
|
"name": "AGI Farm — Multi-Agent Team Builder",
|
|
5
|
-
"version": "1.5.
|
|
5
|
+
"version": "1.5.2",
|
|
6
6
|
"description": "Bootstrap complete multi-agent AI teams with auto-dispatcher, live dashboard, and infrastructure. Includes interactive wizard, SOUL.md generation, comms setup, cron registration, and React + SSE ops room.",
|
|
7
7
|
"author": "oabdelmaksoud",
|
|
8
8
|
"homepage": "https://github.com/oabdelmaksoud/AGI-FARM-PLUGIN",
|
|
9
|
+
"openclawVersion": ">=1.0.0",
|
|
10
|
+
"engines": {
|
|
11
|
+
"openclaw": ">=1.0.0",
|
|
12
|
+
"node": ">=20.0.0"
|
|
13
|
+
},
|
|
9
14
|
"configSchema": {
|
|
10
15
|
"type": "object",
|
|
11
16
|
"additionalProperties": false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agi-farm",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "Multi-agent AI team builder for OpenClaw — bootstrap complete teams with auto-dispatcher, dashboard, and infrastructure",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -43,6 +43,14 @@
|
|
|
43
43
|
"engines": {
|
|
44
44
|
"node": ">=20.0.0"
|
|
45
45
|
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"openclaw": ">=1.0.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"openclaw": {
|
|
51
|
+
"optional": true
|
|
52
|
+
}
|
|
53
|
+
},
|
|
46
54
|
"scripts": {
|
|
47
55
|
"build:dashboard": "cd dashboard-react && npm run build",
|
|
48
56
|
"build:all": "npm run build && npm run build:dashboard && rm -rf dashboard-dist && cp -r dashboard-react/dist dashboard-dist",
|
|
@@ -24,7 +24,7 @@ if (isCI) {
|
|
|
24
24
|
console.log(chalk.cyan('ℹ Running in CI environment'));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
// ── 1. Check OpenClaw Installation
|
|
27
|
+
// ── 1. Check OpenClaw Installation & Version ──────────────────────────────────
|
|
28
28
|
const openclawDir = path.join(os.homedir(), '.openclaw');
|
|
29
29
|
if (!fs.existsSync(openclawDir)) {
|
|
30
30
|
// In CI, OpenClaw won't be installed — treat as warning, not error
|
|
@@ -35,6 +35,43 @@ if (!fs.existsSync(openclawDir)) {
|
|
|
35
35
|
}
|
|
36
36
|
} else {
|
|
37
37
|
console.log(chalk.green('✓ OpenClaw directory found'));
|
|
38
|
+
|
|
39
|
+
// Check OpenClaw version
|
|
40
|
+
try {
|
|
41
|
+
const openclawVersion = execSync('openclaw --version', { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
42
|
+
console.log(chalk.green(`✓ OpenClaw version: ${openclawVersion}`));
|
|
43
|
+
|
|
44
|
+
// Extract version number (e.g., "openclaw/1.2.3" → "1.2.3")
|
|
45
|
+
const versionMatch = openclawVersion.match(/(\d+\.\d+\.\d+)/);
|
|
46
|
+
if (versionMatch) {
|
|
47
|
+
const version = versionMatch[1];
|
|
48
|
+
const [major, minor, patch] = version.split('.').map(Number);
|
|
49
|
+
|
|
50
|
+
// Define minimum compatible OpenClaw version
|
|
51
|
+
const MIN_OPENCLAW_VERSION = '1.0.0';
|
|
52
|
+
const [minMajor, minMinor, minPatch] = MIN_OPENCLAW_VERSION.split('.').map(Number);
|
|
53
|
+
|
|
54
|
+
// Check if version meets minimum requirement
|
|
55
|
+
if (major < minMajor || (major === minMajor && minor < minMinor) || (major === minMajor && minor === minMinor && patch < minPatch)) {
|
|
56
|
+
warnings.push(`OpenClaw ${version} is older than recommended ${MIN_OPENCLAW_VERSION}`);
|
|
57
|
+
warnings.push('Consider upgrading: npm install -g openclaw@latest');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Check for known incompatible versions
|
|
61
|
+
const INCOMPATIBLE_VERSIONS = [
|
|
62
|
+
// Add known incompatible versions here if discovered
|
|
63
|
+
// e.g., '2.0.0-beta.1'
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
if (INCOMPATIBLE_VERSIONS.includes(version)) {
|
|
67
|
+
errors.push(`OpenClaw ${version} has known incompatibilities with AGI Farm`);
|
|
68
|
+
errors.push('Please upgrade or downgrade OpenClaw');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
} catch (err) {
|
|
72
|
+
warnings.push('Could not determine OpenClaw version');
|
|
73
|
+
warnings.push('Ensure openclaw CLI is in PATH');
|
|
74
|
+
}
|
|
38
75
|
}
|
|
39
76
|
|
|
40
77
|
// ── 2. Check Node.js Version ──────────────────────────────────────────────────
|
package/server/dashboard.js
CHANGED
|
@@ -378,7 +378,7 @@ function toggleCronEnabled(id) {
|
|
|
378
378
|
const updateChecker = new UpdateChecker();
|
|
379
379
|
|
|
380
380
|
function buildWorkspaceSnapshot(cache, services) {
|
|
381
|
-
|
|
381
|
+
let tasks = asArray(readJson(path.join(WORKSPACE, 'TASKS.json')));
|
|
382
382
|
const agentStatus = asObject(readJson(path.join(WORKSPACE, 'AGENT_STATUS.json')));
|
|
383
383
|
const agentPerf = asObject(readJson(path.join(WORKSPACE, 'AGENT_PERFORMANCE.json')));
|
|
384
384
|
const budget = asObject(readJson(path.join(WORKSPACE, 'BUDGET.json')));
|
|
@@ -445,13 +445,61 @@ function buildWorkspaceSnapshot(cache, services) {
|
|
|
445
445
|
const jobs = flags.jobs ? services.jobs.list({}).slice(0, 100) : [];
|
|
446
446
|
const approvals = flags.approvals ? services.policy.listApprovals() : [];
|
|
447
447
|
const usage = flags.metering ? services.metering.getUsage() : { records: [], perAgent: {}, perModel: {}, totals: {} };
|
|
448
|
-
|
|
448
|
+
|
|
449
|
+
// Auto-derive tasks from jobs that have rootTaskId
|
|
450
|
+
const taskIds = new Set(tasks.map(t => t.id));
|
|
451
|
+
const derivedTasks = [];
|
|
452
|
+
for (const job of jobs) {
|
|
453
|
+
if (job.rootTaskId && !taskIds.has(job.rootTaskId)) {
|
|
454
|
+
derivedTasks.push({
|
|
455
|
+
id: job.rootTaskId,
|
|
456
|
+
title: job.title || `Task from job ${job.id.slice(0, 8)}`,
|
|
457
|
+
description: job.intent || '',
|
|
458
|
+
status: job.status === 'complete' ? 'complete' : (job.status === 'running' ? 'in-progress' : 'pending'),
|
|
459
|
+
assigned_to: job.assignedAgent || job.requestedBy || 'system',
|
|
460
|
+
project_id: job.projectId || null,
|
|
461
|
+
created_at: job.createdAt,
|
|
462
|
+
updated_at: job.updatedAt,
|
|
463
|
+
depends_on: [],
|
|
464
|
+
});
|
|
465
|
+
taskIds.add(job.rootTaskId);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
// Merge explicit tasks + auto-derived from jobs
|
|
469
|
+
const allTasks = [...tasks, ...derivedTasks];
|
|
470
|
+
|
|
471
|
+
// Auto-derive projects from jobs that have projectId
|
|
472
|
+
const jobProjects = {};
|
|
473
|
+
for (const job of jobs) {
|
|
474
|
+
if (job.projectId && !jobProjects[job.projectId]) {
|
|
475
|
+
jobProjects[job.projectId] = {
|
|
476
|
+
id: job.projectId,
|
|
477
|
+
name: job.title || job.projectId,
|
|
478
|
+
description: job.intent || '',
|
|
479
|
+
status: job.status === 'complete' ? 'complete' : 'active',
|
|
480
|
+
owner: job.requestedBy || 'system',
|
|
481
|
+
created_at: job.createdAt,
|
|
482
|
+
updated_at: job.updatedAt,
|
|
483
|
+
task_ids: job.rootTaskId ? [job.rootTaskId] : [],
|
|
484
|
+
job_ids: [job.id],
|
|
485
|
+
};
|
|
486
|
+
} else if (job.projectId && jobProjects[job.projectId]) {
|
|
487
|
+
jobProjects[job.projectId].job_ids.push(job.id);
|
|
488
|
+
if (job.rootTaskId && !jobProjects[job.projectId].task_ids.includes(job.rootTaskId)) {
|
|
489
|
+
jobProjects[job.projectId].task_ids.push(job.rootTaskId);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Merge: explicit projects from PROJECTS.json + auto-derived from jobs
|
|
495
|
+
const allProjectsRaw = [...projectsRaw, ...Object.values(jobProjects)];
|
|
496
|
+
const projects = enrichProjects(allProjectsRaw, tasks, agentPerf);
|
|
449
497
|
const projectEvents = services.timeline ? services.timeline.list(null, { limit: 120 }) : [];
|
|
450
498
|
|
|
451
499
|
return {
|
|
452
500
|
timestamp: new Date().toISOString(),
|
|
453
501
|
workspace: WORKSPACE,
|
|
454
|
-
tasks,
|
|
502
|
+
tasks: allTasks,
|
|
455
503
|
task_counts: taskCounts,
|
|
456
504
|
hitl_tasks: hitlTasks,
|
|
457
505
|
sla_at_risk: slaAtRisk,
|