groove-dev 0.27.110 → 0.27.111
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/EMBEDDING_SERVICE_BUILD_PLAN.md +200 -0
- package/TRAINING_DATA_v2.md +9 -0
- package/moe-training/client/domain-tagger.js +3 -1
- package/moe-training/client/trajectory-capture.js +3 -2
- package/moe-training/shared/constants.js +1 -0
- package/moe-training/test/client/domain-tagger.test.js +6 -4
- 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 +16 -3
- package/node_modules/@groove-dev/gui/dist/assets/{index-B8JomvGM.js → index-CHu5w3i3.js} +1 -1
- package/node_modules/@groove-dev/gui/dist/index.html +1 -1
- package/node_modules/@groove-dev/gui/package.json +1 -1
- package/node_modules/@groove-dev/gui/src/stores/groove.js +1 -1
- package/node_modules/moe-training/client/domain-tagger.js +3 -1
- package/node_modules/moe-training/client/trajectory-capture.js +3 -2
- package/node_modules/moe-training/shared/constants.js +1 -0
- package/node_modules/moe-training/test/client/domain-tagger.test.js +6 -4
- 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 +16 -3
- package/packages/gui/dist/assets/{index-B8JomvGM.js → index-CHu5w3i3.js} +1 -1
- package/packages/gui/dist/index.html +1 -1
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/stores/groove.js +1 -1
- package/TRAINING_DATA.md +0 -12
- package/codex/browser-racing-game/README.md +0 -45
- package/codex/browser-racing-game/dist/assets/index-D-sGTraQ.js +0 -47
- package/codex/browser-racing-game/dist/assets/index-S75nJv69.css +0 -1
- package/codex/browser-racing-game/dist/index.html +0 -14
- package/codex/browser-racing-game/index.html +0 -13
- package/codex/browser-racing-game/package-lock.json +0 -841
- package/codex/browser-racing-game/package.json +0 -15
- package/codex/browser-racing-game/src/app.css +0 -359
- package/codex/browser-racing-game/src/main.ts +0 -913
- package/codex/browser-racing-game/tsconfig.json +0 -20
- package/codex/browser-racing-game/vite.config.ts +0 -12
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
|
8
8
|
<title>Groove GUI</title>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-CHu5w3i3.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/vendor-26L3JoZv.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/reactflow-DoBZjiHE.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/codemirror-CFF1Lrnz.js">
|
|
@@ -2702,7 +2702,7 @@ export const useGrooveStore = create((set, get) => ({
|
|
|
2702
2702
|
set({ trainingOptIn: enabled });
|
|
2703
2703
|
if (!enabled) set({ trainingStats: null });
|
|
2704
2704
|
} catch (e) {
|
|
2705
|
-
get().addToast('error', 'Failed to update training preference');
|
|
2705
|
+
get().addToast('error', 'Failed to update training preference', e.body?.detail || e.message);
|
|
2706
2706
|
}
|
|
2707
2707
|
},
|
|
2708
2708
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
2
|
|
|
3
|
+
import { EMBEDDING_SERVICE_URL } from '../shared/constants.js';
|
|
4
|
+
|
|
3
5
|
const DEFAULT_MODEL = 'sentence-transformers/all-MiniLM-L6-v2';
|
|
4
6
|
const DEFAULT_TOP_K = 3;
|
|
5
7
|
|
|
@@ -171,7 +173,7 @@ const DOMAIN_TAXONOMY = {
|
|
|
171
173
|
|
|
172
174
|
export class DomainTagger {
|
|
173
175
|
constructor(options = {}) {
|
|
174
|
-
this._serviceUrl = options.serviceUrl
|
|
176
|
+
this._serviceUrl = options.serviceUrl !== undefined ? options.serviceUrl : EMBEDDING_SERVICE_URL;
|
|
175
177
|
this._registryUrl = options.registryUrl || process.env.LEAF_REGISTRY_URL || null;
|
|
176
178
|
this._registry = options.registry || null;
|
|
177
179
|
this._model = options.model || DEFAULT_MODEL;
|
|
@@ -298,9 +298,10 @@ export class TrajectoryCapture {
|
|
|
298
298
|
|
|
299
299
|
if (this._domainTagger) {
|
|
300
300
|
const role = ctx.metadata.agent_role || '';
|
|
301
|
-
const firstPrompt = ctx.allSteps.find((s) => s.type === 'thought')?.content || '';
|
|
302
301
|
const thoughtSteps = ctx.allSteps.filter((s) => s.type === 'thought');
|
|
303
|
-
const
|
|
302
|
+
const firstPrompt = thoughtSteps[0]?.content || '';
|
|
303
|
+
const remainingThoughts = thoughtSteps.slice(1);
|
|
304
|
+
const routingText = DomainTagger.buildRoutingText(role, firstPrompt, remainingThoughts);
|
|
304
305
|
ctx.metadata.domain_tags = await this._domainTagger.tag(routingText);
|
|
305
306
|
ctx.metadata.session_embedding = await this._domainTagger.embed(routingText);
|
|
306
307
|
}
|
|
@@ -39,3 +39,4 @@ export const TRAINING_EXCLUSION_REASONS = ['too_few_steps', 'no_actions', 'no_ob
|
|
|
39
39
|
export const USER_MESSAGE_MAX_CHARS = 2000;
|
|
40
40
|
|
|
41
41
|
export const CENTRAL_COMMAND_URL = process.env.GROOVE_CENTRAL_URL || 'https://api.groovedev.ai';
|
|
42
|
+
export const EMBEDDING_SERVICE_URL = process.env.EMBEDDING_SERVICE_URL || `${CENTRAL_COMMAND_URL}/v1/embed`;
|
|
@@ -8,7 +8,7 @@ describe('DomainTagger', () => {
|
|
|
8
8
|
let tagger;
|
|
9
9
|
|
|
10
10
|
beforeEach(async () => {
|
|
11
|
-
tagger = new DomainTagger();
|
|
11
|
+
tagger = new DomainTagger({ serviceUrl: null });
|
|
12
12
|
await tagger.init();
|
|
13
13
|
});
|
|
14
14
|
|
|
@@ -176,7 +176,7 @@ describe('DomainTagger', () => {
|
|
|
176
176
|
});
|
|
177
177
|
|
|
178
178
|
it('returns null when not initialized', async () => {
|
|
179
|
-
const uninit = new DomainTagger();
|
|
179
|
+
const uninit = new DomainTagger({ serviceUrl: null });
|
|
180
180
|
const result = await uninit.tag('Build a Python Django app');
|
|
181
181
|
assert.equal(result, null);
|
|
182
182
|
});
|
|
@@ -203,6 +203,7 @@ describe('DomainTagger', () => {
|
|
|
203
203
|
|
|
204
204
|
it('accepts registry option and falls back to keyword mode without embedding service', async () => {
|
|
205
205
|
const registryTagger = new DomainTagger({
|
|
206
|
+
serviceUrl: null,
|
|
206
207
|
registry: [
|
|
207
208
|
{ id: 'quantum_computing', domain_description: 'Quantum computing, qubits, quantum gates' },
|
|
208
209
|
{ id: 'bioinformatics', domain_description: 'Biology, genomics, DNA analysis' },
|
|
@@ -215,6 +216,7 @@ describe('DomainTagger', () => {
|
|
|
215
216
|
|
|
216
217
|
it('accepts registryUrl option and falls back to keyword mode when unavailable', async () => {
|
|
217
218
|
const registryTagger = new DomainTagger({
|
|
219
|
+
serviceUrl: null,
|
|
218
220
|
registryUrl: 'http://localhost:99999/api/leaves',
|
|
219
221
|
});
|
|
220
222
|
await registryTagger.init();
|
|
@@ -223,7 +225,7 @@ describe('DomainTagger', () => {
|
|
|
223
225
|
});
|
|
224
226
|
|
|
225
227
|
it('uses expanded taxonomy — has 40 domains by default', async () => {
|
|
226
|
-
const defaultTagger = new DomainTagger();
|
|
228
|
+
const defaultTagger = new DomainTagger({ serviceUrl: null });
|
|
227
229
|
await defaultTagger.init();
|
|
228
230
|
assert.ok(defaultTagger._domains.length >= 35, `Expected 35+ domains, got ${defaultTagger._domains.length}`);
|
|
229
231
|
});
|
|
@@ -239,7 +241,7 @@ describe('DomainTagger', () => {
|
|
|
239
241
|
});
|
|
240
242
|
|
|
241
243
|
it('embed() returns null when not initialized', async () => {
|
|
242
|
-
const uninit = new DomainTagger();
|
|
244
|
+
const uninit = new DomainTagger({ serviceUrl: null });
|
|
243
245
|
const result = await uninit.embed('Build a Python app');
|
|
244
246
|
assert.equal(result, null);
|
|
245
247
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "groove-dev",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.111",
|
|
4
4
|
"description": "Open-source agent orchestration layer — the AI company OS. Local model agent engine (GGUF/Ollama/llama-server), HuggingFace model browser, MCP integrations (Slack, Gmail, Stripe, 15+), agent scheduling (cron), business roles (CMO, CFO, EA). GUI dashboard, multi-agent coordination, zero cold-start, infinite sessions. Works with Claude Code, Codex, Gemini CLI, Ollama, any local model.",
|
|
5
5
|
"license": "FSL-1.1-Apache-2.0",
|
|
6
6
|
"author": "Groove Dev <hello@groovedev.ai> (https://groovedev.ai)",
|
|
@@ -112,7 +112,7 @@ export function createApi(app, daemon) {
|
|
|
112
112
|
res.setHeader('Content-Security-Policy', "default-src * 'unsafe-inline' 'unsafe-eval' data: blob:; frame-ancestors 'self'");
|
|
113
113
|
} else {
|
|
114
114
|
res.setHeader('X-Frame-Options', 'DENY');
|
|
115
|
-
res.setHeader('Content-Security-Policy', "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; connect-src 'self' ws://localhost:* ws://127.0.0.1:* http://localhost:* http://127.0.0.1:*; font-src 'self' data:; object-src 'none'; base-uri 'self'; frame-src 'self'
|
|
115
|
+
res.setHeader('Content-Security-Policy', "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; connect-src 'self' ws://localhost:* ws://127.0.0.1:* http://localhost:* http://127.0.0.1:*; font-src 'self' data:; object-src 'none'; base-uri 'self'; frame-src 'self' http://127.0.0.1:* http://localhost:*; frame-ancestors 'none'");
|
|
116
116
|
}
|
|
117
117
|
next();
|
|
118
118
|
});
|
|
@@ -4869,11 +4869,18 @@ Keep responses concise. Help them think, don't lecture them about the system the
|
|
|
4869
4869
|
const { enabled } = req.body;
|
|
4870
4870
|
if (typeof enabled !== 'boolean') return res.status(400).json({ error: 'enabled must be boolean' });
|
|
4871
4871
|
|
|
4872
|
-
daemon.config.training_opt_in = enabled;
|
|
4873
4872
|
const { saveConfig } = await import('./firstrun.js');
|
|
4874
|
-
saveConfig(daemon.grooveDir, daemon.config);
|
|
4875
4873
|
|
|
4876
4874
|
if (enabled) {
|
|
4875
|
+
try {
|
|
4876
|
+
await import('better-sqlite3');
|
|
4877
|
+
} catch (modErr) {
|
|
4878
|
+
console.error('[training/opt-in] Native module load failed:', modErr);
|
|
4879
|
+
return res.status(500).json({
|
|
4880
|
+
error: 'Failed to enable data sharing',
|
|
4881
|
+
detail: 'Native SQLite module (better-sqlite3) is not available. On remote instances, ensure build tools are installed (gcc, g++, make, python3) and run: npm rebuild better-sqlite3',
|
|
4882
|
+
});
|
|
4883
|
+
}
|
|
4877
4884
|
try {
|
|
4878
4885
|
const userId = ConsentManager.getOrCreateUserId();
|
|
4879
4886
|
const consent = new ConsentManager();
|
|
@@ -4882,13 +4889,19 @@ Keep responses concise. Help them think, don't lecture them about the system the
|
|
|
4882
4889
|
} finally {
|
|
4883
4890
|
consent.close();
|
|
4884
4891
|
}
|
|
4892
|
+
daemon.config.training_opt_in = true;
|
|
4893
|
+
saveConfig(daemon.grooveDir, daemon.config);
|
|
4885
4894
|
await daemon._initTrajectoryCapture();
|
|
4886
4895
|
daemon.state.set('training_enrolled_at', new Date().toISOString());
|
|
4887
4896
|
} catch (e) {
|
|
4897
|
+
console.error('[training/opt-in] Failed to enable data sharing:', e);
|
|
4888
4898
|
daemon.config.training_opt_in = false;
|
|
4899
|
+
saveConfig(daemon.grooveDir, daemon.config);
|
|
4889
4900
|
return res.status(500).json({ error: 'Failed to enable data sharing', detail: e.message });
|
|
4890
4901
|
}
|
|
4891
4902
|
} else {
|
|
4903
|
+
daemon.config.training_opt_in = false;
|
|
4904
|
+
saveConfig(daemon.grooveDir, daemon.config);
|
|
4892
4905
|
if (daemon.trajectoryCapture) {
|
|
4893
4906
|
try { await daemon.trajectoryCapture.shutdown(); } catch (e) { /* */ }
|
|
4894
4907
|
daemon.trajectoryCapture = null;
|