groove-dev 0.27.174 → 0.27.179
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/AUTONOMOUS_AGENT_FRAMEWORK.md +654 -0
- package/innerchat/Screenshot_2026-06-09_at_12.09.42_PM.png +0 -0
- package/innerchat/Screenshot_2026-06-09_at_2.19.42_PM.png +0 -0
- package/node_modules/@groove-dev/cli/package.json +1 -1
- package/node_modules/@groove-dev/daemon/package.json +1 -1
- package/node_modules/@groove-dev/daemon/src/api.js +3 -1
- package/node_modules/@groove-dev/daemon/src/autostate.js +198 -0
- package/node_modules/@groove-dev/daemon/src/index.js +6 -0
- package/node_modules/@groove-dev/daemon/src/orchestrator.js +585 -0
- package/node_modules/@groove-dev/daemon/src/process.js +27 -2
- package/node_modules/@groove-dev/daemon/src/registry.js +2 -1
- package/node_modules/@groove-dev/daemon/src/routes/auto-agents.js +264 -0
- package/node_modules/@groove-dev/daemon/src/validate.js +6 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-CTer01Vg.js +1065 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-DTFtRtkx.css +1 -0
- package/node_modules/@groove-dev/gui/dist/index.html +2 -2
- package/node_modules/@groove-dev/gui/package.json +1 -1
- package/node_modules/@groove-dev/gui/src/App.jsx +2 -0
- package/node_modules/@groove-dev/gui/src/components/agents/agent-config.jsx +53 -0
- package/node_modules/@groove-dev/gui/src/components/agents/agent-feed.jsx +4 -4
- package/node_modules/@groove-dev/gui/src/components/agents/agent-panel.jsx +95 -2
- package/node_modules/@groove-dev/gui/src/components/agents/spawn-wizard.jsx +50 -1
- package/node_modules/@groove-dev/gui/src/components/auto-agents/auto-agent-card.jsx +139 -0
- package/node_modules/@groove-dev/gui/src/components/auto-agents/auto-agent-detail.jsx +286 -0
- package/node_modules/@groove-dev/gui/src/components/auto-agents/setup-wizard.jsx +284 -0
- package/node_modules/@groove-dev/gui/src/components/fleet/fleet-pane.jsx +16 -3
- package/node_modules/@groove-dev/gui/src/components/layout/activity-bar.jsx +2 -1
- package/node_modules/@groove-dev/gui/src/stores/groove.js +14 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/agents-slice.js +2 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/auto-agents-slice.js +149 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/ui-slice.js +14 -11
- package/node_modules/@groove-dev/gui/src/views/auto-agents.jsx +70 -0
- package/node_modules/@groove-dev/gui/src/views/settings.jsx +13 -6
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/daemon/package.json +1 -1
- package/packages/daemon/src/api.js +3 -1
- package/packages/daemon/src/autostate.js +198 -0
- package/packages/daemon/src/index.js +6 -0
- package/packages/daemon/src/orchestrator.js +585 -0
- package/packages/daemon/src/process.js +27 -2
- package/packages/daemon/src/registry.js +2 -1
- package/packages/daemon/src/routes/auto-agents.js +264 -0
- package/packages/daemon/src/validate.js +6 -0
- package/packages/gui/dist/assets/index-CTer01Vg.js +1065 -0
- package/packages/gui/dist/assets/index-DTFtRtkx.css +1 -0
- package/packages/gui/dist/index.html +2 -2
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/App.jsx +2 -0
- package/packages/gui/src/components/agents/agent-config.jsx +53 -0
- package/packages/gui/src/components/agents/agent-feed.jsx +4 -4
- package/packages/gui/src/components/agents/agent-panel.jsx +95 -2
- package/packages/gui/src/components/agents/spawn-wizard.jsx +50 -1
- package/packages/gui/src/components/auto-agents/auto-agent-card.jsx +139 -0
- package/packages/gui/src/components/auto-agents/auto-agent-detail.jsx +286 -0
- package/packages/gui/src/components/auto-agents/setup-wizard.jsx +284 -0
- package/packages/gui/src/components/fleet/fleet-pane.jsx +16 -3
- package/packages/gui/src/components/layout/activity-bar.jsx +2 -1
- package/packages/gui/src/stores/groove.js +14 -0
- package/packages/gui/src/stores/slices/agents-slice.js +2 -0
- package/packages/gui/src/stores/slices/auto-agents-slice.js +149 -0
- package/packages/gui/src/stores/slices/ui-slice.js +14 -11
- package/packages/gui/src/views/auto-agents.jsx +70 -0
- package/packages/gui/src/views/settings.jsx +13 -6
- package/node_modules/@groove-dev/gui/dist/assets/index-BvJwMNAX.css +0 -1
- package/node_modules/@groove-dev/gui/dist/assets/index-DZY-EWPs.js +0 -1030
- package/packages/gui/dist/assets/index-BvJwMNAX.css +0 -1
- package/packages/gui/dist/assets/index-DZY-EWPs.js +0 -1030
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// GROOVE — Auto Agent State Persistence
|
|
2
|
+
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
3
|
+
//
|
|
4
|
+
// Manages the persistent state layer for autonomous agents:
|
|
5
|
+
// .groove/auto/<agentDefId>/
|
|
6
|
+
// state.json — phase, cycle, history, champion
|
|
7
|
+
// journal.jsonl — append-only accumulated knowledge
|
|
8
|
+
// roadmap.md — staged goals with graduation criteria
|
|
9
|
+
// prompt.md — system prompt (identity + tools + rules)
|
|
10
|
+
// runs/ — per-run logs and output
|
|
11
|
+
|
|
12
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, appendFileSync, readdirSync, renameSync, copyFileSync, statSync, rmSync } from 'fs';
|
|
13
|
+
import { resolve } from 'path';
|
|
14
|
+
import { randomUUID } from 'crypto';
|
|
15
|
+
|
|
16
|
+
const MAX_HISTORY = 200;
|
|
17
|
+
const MAX_JOURNAL_ENTRIES = 500;
|
|
18
|
+
|
|
19
|
+
function safeJsonParse(str, fallback) {
|
|
20
|
+
try { return JSON.parse(str); } catch { return fallback; }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function safeDict(obj, key) {
|
|
24
|
+
const v = obj?.[key];
|
|
25
|
+
return v && typeof v === 'object' && !Array.isArray(v) ? v : {};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class AutoState {
|
|
29
|
+
constructor(grooveDir) {
|
|
30
|
+
this.baseDir = resolve(grooveDir, 'auto');
|
|
31
|
+
mkdirSync(this.baseDir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
_agentDir(defId) {
|
|
35
|
+
const dir = resolve(this.baseDir, defId);
|
|
36
|
+
mkdirSync(dir, { recursive: true });
|
|
37
|
+
mkdirSync(resolve(dir, 'runs'), { recursive: true });
|
|
38
|
+
return dir;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// --- State (state.json) ---
|
|
42
|
+
|
|
43
|
+
getState(defId) {
|
|
44
|
+
const p = resolve(this._agentDir(defId), 'state.json');
|
|
45
|
+
if (!existsSync(p)) return this._defaultState();
|
|
46
|
+
return safeJsonParse(readFileSync(p, 'utf8'), this._defaultState());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
setState(defId, updates) {
|
|
50
|
+
const dir = this._agentDir(defId);
|
|
51
|
+
const p = resolve(dir, 'state.json');
|
|
52
|
+
const bak = resolve(dir, 'state.json.bak');
|
|
53
|
+
const current = this.getState(defId);
|
|
54
|
+
|
|
55
|
+
const merged = { ...current };
|
|
56
|
+
const allowed = ['phase', 'phase_note', 'cycle', 'current_run', 'champion', 'paused', 'error'];
|
|
57
|
+
for (const key of allowed) {
|
|
58
|
+
if (key in updates) merged[key] = updates[key];
|
|
59
|
+
}
|
|
60
|
+
merged.updatedAt = new Date().toISOString();
|
|
61
|
+
|
|
62
|
+
if (existsSync(p)) {
|
|
63
|
+
try { copyFileSync(p, bak); } catch { /* best effort */ }
|
|
64
|
+
}
|
|
65
|
+
const tmp = resolve(dir, `state.${randomUUID().slice(0, 8)}.tmp`);
|
|
66
|
+
writeFileSync(tmp, JSON.stringify(merged, null, 2));
|
|
67
|
+
renameSync(tmp, p);
|
|
68
|
+
return merged;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
appendHistory(defId, entry) {
|
|
72
|
+
const state = this.getState(defId);
|
|
73
|
+
if (!Array.isArray(state.history)) state.history = [];
|
|
74
|
+
state.history.push({
|
|
75
|
+
...entry,
|
|
76
|
+
timestamp: new Date().toISOString(),
|
|
77
|
+
});
|
|
78
|
+
if (state.history.length > MAX_HISTORY) {
|
|
79
|
+
state.history = state.history.slice(-MAX_HISTORY);
|
|
80
|
+
}
|
|
81
|
+
this.setState(defId, { history: state.history });
|
|
82
|
+
return state.history;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
_defaultState() {
|
|
86
|
+
return {
|
|
87
|
+
phase: 'idle',
|
|
88
|
+
phase_note: '',
|
|
89
|
+
cycle: 0,
|
|
90
|
+
current_run: null,
|
|
91
|
+
champion: null,
|
|
92
|
+
history: [],
|
|
93
|
+
paused: false,
|
|
94
|
+
error: null,
|
|
95
|
+
createdAt: new Date().toISOString(),
|
|
96
|
+
updatedAt: new Date().toISOString(),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// --- Journal (journal.jsonl) ---
|
|
101
|
+
|
|
102
|
+
getJournal(defId, { limit = 50, since } = {}) {
|
|
103
|
+
const p = resolve(this._agentDir(defId), 'journal.jsonl');
|
|
104
|
+
if (!existsSync(p)) return [];
|
|
105
|
+
const lines = readFileSync(p, 'utf8').trim().split('\n').filter(Boolean);
|
|
106
|
+
let entries = lines.map(l => safeJsonParse(l, null)).filter(Boolean);
|
|
107
|
+
if (since) {
|
|
108
|
+
entries = entries.filter(e => e.timestamp >= since);
|
|
109
|
+
}
|
|
110
|
+
return entries.slice(-limit);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
appendJournal(defId, entry) {
|
|
114
|
+
const p = resolve(this._agentDir(defId), 'journal.jsonl');
|
|
115
|
+
const record = {
|
|
116
|
+
...entry,
|
|
117
|
+
timestamp: new Date().toISOString(),
|
|
118
|
+
};
|
|
119
|
+
appendFileSync(p, JSON.stringify(record) + '\n');
|
|
120
|
+
this._pruneJournal(defId);
|
|
121
|
+
return record;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
_pruneJournal(defId) {
|
|
125
|
+
const p = resolve(this._agentDir(defId), 'journal.jsonl');
|
|
126
|
+
if (!existsSync(p)) return;
|
|
127
|
+
const lines = readFileSync(p, 'utf8').trim().split('\n').filter(Boolean);
|
|
128
|
+
if (lines.length > MAX_JOURNAL_ENTRIES) {
|
|
129
|
+
writeFileSync(p, lines.slice(-MAX_JOURNAL_ENTRIES).join('\n') + '\n');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// --- Roadmap (roadmap.md) ---
|
|
134
|
+
|
|
135
|
+
getRoadmap(defId) {
|
|
136
|
+
const p = resolve(this._agentDir(defId), 'roadmap.md');
|
|
137
|
+
if (!existsSync(p)) return '';
|
|
138
|
+
return readFileSync(p, 'utf8');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
setRoadmap(defId, content) {
|
|
142
|
+
const p = resolve(this._agentDir(defId), 'roadmap.md');
|
|
143
|
+
writeFileSync(p, content);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// --- Prompt (prompt.md) ---
|
|
147
|
+
|
|
148
|
+
getPrompt(defId) {
|
|
149
|
+
const p = resolve(this._agentDir(defId), 'prompt.md');
|
|
150
|
+
if (!existsSync(p)) return '';
|
|
151
|
+
return readFileSync(p, 'utf8');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
setPrompt(defId, content) {
|
|
155
|
+
const p = resolve(this._agentDir(defId), 'prompt.md');
|
|
156
|
+
writeFileSync(p, content);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// --- Run Logs ---
|
|
160
|
+
|
|
161
|
+
logRun(defId, runId, data) {
|
|
162
|
+
const dir = resolve(this._agentDir(defId), 'runs');
|
|
163
|
+
const p = resolve(dir, `${runId}.json`);
|
|
164
|
+
writeFileSync(p, JSON.stringify(data, null, 2));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
getRunLog(defId, runId) {
|
|
168
|
+
const p = resolve(this._agentDir(defId), 'runs', `${runId}.json`);
|
|
169
|
+
if (!existsSync(p)) return null;
|
|
170
|
+
return safeJsonParse(readFileSync(p, 'utf8'), null);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
listRuns(defId, { limit = 20 } = {}) {
|
|
174
|
+
const dir = resolve(this._agentDir(defId), 'runs');
|
|
175
|
+
if (!existsSync(dir)) return [];
|
|
176
|
+
const files = readdirSync(dir)
|
|
177
|
+
.filter(f => f.endsWith('.json'))
|
|
178
|
+
.map(f => {
|
|
179
|
+
const stat = statSync(resolve(dir, f));
|
|
180
|
+
return { runId: f.replace('.json', ''), mtime: stat.mtimeMs };
|
|
181
|
+
})
|
|
182
|
+
.sort((a, b) => b.mtime - a.mtime)
|
|
183
|
+
.slice(0, limit);
|
|
184
|
+
return files.map(f => {
|
|
185
|
+
const data = safeJsonParse(readFileSync(resolve(dir, `${f.runId}.json`), 'utf8'), {});
|
|
186
|
+
return { runId: f.runId, ...data };
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// --- Cleanup ---
|
|
191
|
+
|
|
192
|
+
deleteAll(defId) {
|
|
193
|
+
const dir = resolve(this.baseDir, defId);
|
|
194
|
+
if (existsSync(dir)) {
|
|
195
|
+
rmSync(dir, { recursive: true, force: true });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -47,6 +47,8 @@ import { RepoImporter } from './repo-import.js';
|
|
|
47
47
|
import { ConversationManager } from './conversations.js';
|
|
48
48
|
import { Toys } from './toys.js';
|
|
49
49
|
import { InnerChat } from './innerchat.js';
|
|
50
|
+
import { AutoState } from './autostate.js';
|
|
51
|
+
import { Orchestrator } from './orchestrator.js';
|
|
50
52
|
import { TrajectoryCapture, ConsentManager } from '../../../moe-training/client/index.js';
|
|
51
53
|
import { isFirstRun, runFirstTimeSetup, loadConfig, saveConfig, printWelcome } from './firstrun.js';
|
|
52
54
|
import { bindDaemon as bindGrooveNetworkDaemon } from './providers/groove-network.js';
|
|
@@ -160,6 +162,8 @@ export class Daemon {
|
|
|
160
162
|
this.modelLab = new ModelLab(this);
|
|
161
163
|
this.toys = new Toys(this);
|
|
162
164
|
this.innerchat = new InnerChat(this);
|
|
165
|
+
this.autoState = new AutoState(this.grooveDir);
|
|
166
|
+
this.orchestrator = new Orchestrator(this);
|
|
163
167
|
this.trajectoryCapture = null;
|
|
164
168
|
|
|
165
169
|
// Hook teams.delete to clean up agent-loop session files
|
|
@@ -613,6 +617,7 @@ export class Daemon {
|
|
|
613
617
|
this.journalist.start();
|
|
614
618
|
this.rotator.start();
|
|
615
619
|
this.scheduler.start();
|
|
620
|
+
this.orchestrator.start();
|
|
616
621
|
this.timeline.start();
|
|
617
622
|
this.gateways.start();
|
|
618
623
|
this.federation.initialize();
|
|
@@ -837,6 +842,7 @@ export class Daemon {
|
|
|
837
842
|
this.journalist.stop();
|
|
838
843
|
this.rotator.stop();
|
|
839
844
|
this.scheduler.stop();
|
|
845
|
+
this.orchestrator.stop();
|
|
840
846
|
this.timeline.stop();
|
|
841
847
|
if (this._gcInterval) clearInterval(this._gcInterval);
|
|
842
848
|
if (this._stateSaveInterval) clearInterval(this._stateSaveInterval);
|