groove-dev 0.27.181 → 0.27.183
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/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/scripts/repair-tokens.mjs +78 -0
- package/node_modules/@groove-dev/daemon/src/api.js +1 -1
- package/node_modules/@groove-dev/daemon/src/deliver.js +130 -0
- package/node_modules/@groove-dev/daemon/src/index.js +8 -3
- package/node_modules/@groove-dev/daemon/src/innerchat.js +213 -62
- package/node_modules/@groove-dev/daemon/src/journalist.js +15 -8
- package/node_modules/@groove-dev/daemon/src/process.js +59 -34
- package/node_modules/@groove-dev/daemon/src/providers/claude-code.js +9 -1
- package/node_modules/@groove-dev/daemon/src/registry.js +5 -1
- package/node_modules/@groove-dev/daemon/src/rename.js +72 -0
- package/node_modules/@groove-dev/daemon/src/rotator.js +62 -5
- package/node_modules/@groove-dev/daemon/src/routes/agents.js +22 -100
- package/node_modules/@groove-dev/daemon/src/routes/innerchat.js +12 -9
- package/node_modules/@groove-dev/daemon/src/teams.js +7 -1
- package/node_modules/@groove-dev/daemon/src/tokentracker.js +46 -6
- package/node_modules/@groove-dev/daemon/test/claude-code-provider.test.js +52 -0
- package/node_modules/@groove-dev/daemon/test/innerchat.test.js +197 -111
- package/node_modules/@groove-dev/daemon/test/journalist.test.js +4 -2
- package/node_modules/@groove-dev/daemon/test/rename.test.js +108 -0
- package/node_modules/@groove-dev/daemon/test/rotator.test.js +131 -0
- package/node_modules/@groove-dev/daemon/test/tokentracker.test.js +4 -0
- package/node_modules/@groove-dev/gui/dist/assets/{index-DTFtRtkx.css → index-CiOy7wVS.css} +1 -1
- package/node_modules/@groove-dev/gui/dist/assets/{index-CTer01Vg.js → index-DPjGBQ5X.js} +225 -225
- 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/components/agents/agent-panel.jsx +3 -68
- package/node_modules/@groove-dev/gui/src/components/agents/innerchat-relay.jsx +145 -0
- package/node_modules/@groove-dev/gui/src/components/chat/chat-messages.jsx +3 -1
- package/node_modules/@groove-dev/gui/src/components/fleet/fleet-pane.jsx +15 -1
- package/node_modules/@groove-dev/gui/src/components/fleet/fleet-sidebar.jsx +33 -1
- package/node_modules/@groove-dev/gui/src/stores/groove.js +29 -44
- package/node_modules/@groove-dev/gui/src/stores/slices/agents-slice.js +27 -4
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/daemon/package.json +1 -1
- package/packages/daemon/scripts/repair-tokens.mjs +78 -0
- package/packages/daemon/src/api.js +1 -1
- package/packages/daemon/src/deliver.js +130 -0
- package/packages/daemon/src/index.js +8 -3
- package/packages/daemon/src/innerchat.js +213 -62
- package/packages/daemon/src/journalist.js +15 -8
- package/packages/daemon/src/process.js +59 -34
- package/packages/daemon/src/providers/claude-code.js +9 -1
- package/packages/daemon/src/registry.js +5 -1
- package/packages/daemon/src/rename.js +72 -0
- package/packages/daemon/src/rotator.js +62 -5
- package/packages/daemon/src/routes/agents.js +22 -100
- package/packages/daemon/src/routes/innerchat.js +12 -9
- package/packages/daemon/src/teams.js +7 -1
- package/packages/daemon/src/tokentracker.js +46 -6
- package/packages/gui/dist/assets/{index-DTFtRtkx.css → index-CiOy7wVS.css} +1 -1
- package/packages/gui/dist/assets/{index-CTer01Vg.js → index-DPjGBQ5X.js} +225 -225
- package/packages/gui/dist/index.html +2 -2
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/components/agents/agent-panel.jsx +3 -68
- package/packages/gui/src/components/agents/innerchat-relay.jsx +145 -0
- package/packages/gui/src/components/chat/chat-messages.jsx +3 -1
- package/packages/gui/src/components/fleet/fleet-pane.jsx +15 -1
- package/packages/gui/src/components/fleet/fleet-sidebar.jsx +33 -1
- package/packages/gui/src/stores/groove.js +29 -44
- package/packages/gui/src/stores/slices/agents-slice.js +27 -4
|
@@ -12,6 +12,14 @@ const COLD_START_PER_FILE = 15;
|
|
|
12
12
|
const COLD_START_PER_DIR = 40;
|
|
13
13
|
// Estimated tokens wasted per file conflict (agent discovers, backs off, retries)
|
|
14
14
|
const CONFLICT_OVERHEAD = 500;
|
|
15
|
+
// Max per-agent session records kept. Aggregates are cumulative and unaffected;
|
|
16
|
+
// windowed queries (getVelocity/getTokensInWindow) only need the recent tail,
|
|
17
|
+
// which 500 records covers by orders of magnitude. Uncapped, tokens.json grew
|
|
18
|
+
// to 13.8MB and was rewritten on every assistant stream event.
|
|
19
|
+
const SESSION_CAP = 500;
|
|
20
|
+
// Debounce window for persisting to disk. record() fires per assistant event —
|
|
21
|
+
// writing the full ledger each time is a hot-path full-file rewrite.
|
|
22
|
+
const SAVE_DEBOUNCE_MS = 5_000;
|
|
15
23
|
|
|
16
24
|
export class TokenTracker {
|
|
17
25
|
constructor(grooveDir) {
|
|
@@ -23,6 +31,7 @@ export class TokenTracker {
|
|
|
23
31
|
this.coldStartsSkipped = 0;
|
|
24
32
|
this.projectFiles = 0; // Set from indexer stats
|
|
25
33
|
this.projectDirs = 0;
|
|
34
|
+
this._saveTimer = null;
|
|
26
35
|
this.load();
|
|
27
36
|
}
|
|
28
37
|
|
|
@@ -47,6 +56,7 @@ export class TokenTracker {
|
|
|
47
56
|
if (!entry.totalDurationMs) entry.totalDurationMs = 0;
|
|
48
57
|
if (!entry.totalTurns) entry.totalTurns = 0;
|
|
49
58
|
if (!entry.modelDistribution) entry.modelDistribution = {};
|
|
59
|
+
this._capSessions(entry);
|
|
50
60
|
}
|
|
51
61
|
} catch {
|
|
52
62
|
this.usage = {};
|
|
@@ -55,6 +65,10 @@ export class TokenTracker {
|
|
|
55
65
|
}
|
|
56
66
|
|
|
57
67
|
save() {
|
|
68
|
+
if (this._saveTimer) {
|
|
69
|
+
clearTimeout(this._saveTimer);
|
|
70
|
+
this._saveTimer = null;
|
|
71
|
+
}
|
|
58
72
|
writeFileSync(this.path, JSON.stringify({
|
|
59
73
|
usage: this.usage,
|
|
60
74
|
rotationSavings: this.rotationSavings,
|
|
@@ -64,6 +78,30 @@ export class TokenTracker {
|
|
|
64
78
|
}, null, 2));
|
|
65
79
|
}
|
|
66
80
|
|
|
81
|
+
// Debounced persistence for hot-path recording. In-memory state is always
|
|
82
|
+
// current; at most SAVE_DEBOUNCE_MS of records are at risk on a crash.
|
|
83
|
+
_scheduleSave() {
|
|
84
|
+
if (this._saveTimer) return;
|
|
85
|
+
this._saveTimer = setTimeout(() => {
|
|
86
|
+
this._saveTimer = null;
|
|
87
|
+
try { this.save(); } catch { /* best-effort */ }
|
|
88
|
+
}, SAVE_DEBOUNCE_MS);
|
|
89
|
+
this._saveTimer.unref?.();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Write any pending debounced state to disk. Call on daemon shutdown.
|
|
93
|
+
flush() {
|
|
94
|
+
if (this._saveTimer) {
|
|
95
|
+
try { this.save(); } catch { /* best-effort */ }
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
_capSessions(entry) {
|
|
100
|
+
if (Array.isArray(entry.sessions) && entry.sessions.length > SESSION_CAP) {
|
|
101
|
+
entry.sessions.splice(0, entry.sessions.length - SESSION_CAP);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
67
105
|
_initAgent(agentId) {
|
|
68
106
|
if (!this.usage[agentId]) {
|
|
69
107
|
this.usage[agentId] = {
|
|
@@ -89,7 +127,8 @@ export class TokenTracker {
|
|
|
89
127
|
if (typeof detail === 'number') {
|
|
90
128
|
entry.total += detail;
|
|
91
129
|
entry.sessions.push({ tokens: detail, timestamp: new Date().toISOString() });
|
|
92
|
-
this.
|
|
130
|
+
this._capSessions(entry);
|
|
131
|
+
this._scheduleSave();
|
|
93
132
|
return;
|
|
94
133
|
}
|
|
95
134
|
|
|
@@ -121,8 +160,9 @@ export class TokenTracker {
|
|
|
121
160
|
projectRoot: detail.projectRoot || null,
|
|
122
161
|
timestamp: new Date().toISOString(),
|
|
123
162
|
});
|
|
163
|
+
this._capSessions(entry);
|
|
124
164
|
|
|
125
|
-
this.
|
|
165
|
+
this._scheduleSave();
|
|
126
166
|
}
|
|
127
167
|
|
|
128
168
|
// Sum tokens recorded for an agent since a given timestamp.
|
|
@@ -152,25 +192,25 @@ export class TokenTracker {
|
|
|
152
192
|
if (costUsd) entry.totalCostUsd += costUsd;
|
|
153
193
|
if (durationMs) entry.totalDurationMs += durationMs;
|
|
154
194
|
if (turns) entry.totalTurns += turns;
|
|
155
|
-
this.
|
|
195
|
+
this._scheduleSave();
|
|
156
196
|
}
|
|
157
197
|
|
|
158
198
|
// Record that a rotation saved context tokens
|
|
159
199
|
recordRotation(agentId, tokensBefore) {
|
|
160
200
|
this.rotationSavings += Math.round(tokensBefore * 0.3); // ~30% of context was degraded
|
|
161
|
-
this.
|
|
201
|
+
this._scheduleSave();
|
|
162
202
|
}
|
|
163
203
|
|
|
164
204
|
// Record that a conflict was prevented (scope enforcement)
|
|
165
205
|
recordConflictPrevented() {
|
|
166
206
|
this.conflictsPrevented++;
|
|
167
|
-
this.
|
|
207
|
+
this._scheduleSave();
|
|
168
208
|
}
|
|
169
209
|
|
|
170
210
|
// Record that a cold-start was skipped (Journalist provided context)
|
|
171
211
|
recordColdStartSkipped() {
|
|
172
212
|
this.coldStartsSkipped++;
|
|
173
|
-
this.
|
|
213
|
+
this._scheduleSave();
|
|
174
214
|
}
|
|
175
215
|
|
|
176
216
|
// Set project size from indexer for dynamic cold-start estimation
|