groove-dev 0.27.145 → 0.27.147

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.
Files changed (73) hide show
  1. package/node_modules/@groove-dev/cli/package.json +1 -1
  2. package/node_modules/@groove-dev/daemon/package.json +1 -1
  3. package/node_modules/@groove-dev/daemon/src/api.js +12 -6
  4. package/node_modules/@groove-dev/daemon/src/conversations.js +41 -10
  5. package/node_modules/@groove-dev/daemon/src/introducer.js +20 -0
  6. package/node_modules/@groove-dev/daemon/src/process.js +262 -15
  7. package/node_modules/@groove-dev/daemon/src/providers/groove-network.js +1 -3
  8. package/node_modules/@groove-dev/daemon/src/rotator.js +15 -3
  9. package/node_modules/@groove-dev/daemon/src/routes/agents.js +43 -0
  10. package/node_modules/@groove-dev/daemon/templates/lab-general.json +12 -0
  11. package/node_modules/@groove-dev/daemon/templates/llama-cpp-setup.json +12 -0
  12. package/node_modules/@groove-dev/gui/dist/assets/index-BKbsE_hn.js +1011 -0
  13. package/node_modules/@groove-dev/gui/dist/assets/index-CEkPsSAm.css +1 -0
  14. package/node_modules/@groove-dev/gui/dist/index.html +2 -2
  15. package/node_modules/@groove-dev/gui/package.json +1 -1
  16. package/node_modules/@groove-dev/gui/src/components/agents/spawn-wizard.jsx +132 -4
  17. package/node_modules/@groove-dev/gui/src/components/chat/chat-header.jsx +1 -8
  18. package/node_modules/@groove-dev/gui/src/components/chat/chat-input.jsx +135 -13
  19. package/node_modules/@groove-dev/gui/src/components/chat/chat-messages.jsx +21 -4
  20. package/node_modules/@groove-dev/gui/src/components/chat/chat-view.jsx +6 -5
  21. package/node_modules/@groove-dev/gui/src/components/chat/model-picker.jsx +3 -3
  22. package/node_modules/@groove-dev/gui/src/components/lab/chat-playground.jsx +3 -3
  23. package/node_modules/@groove-dev/gui/src/components/lab/lab-assistant.jsx +9 -3
  24. package/node_modules/@groove-dev/gui/src/components/lab/metrics-panel.jsx +13 -3
  25. package/node_modules/@groove-dev/gui/src/components/lab/parameter-panel.jsx +5 -5
  26. package/node_modules/@groove-dev/gui/src/components/lab/runtime-config.jsx +1 -3
  27. package/node_modules/@groove-dev/gui/src/components/layout/app-shell.jsx +2 -0
  28. package/node_modules/@groove-dev/gui/src/components/layout/status-bar.jsx +24 -1
  29. package/node_modules/@groove-dev/gui/src/components/ui/question-modal.jsx +107 -0
  30. package/node_modules/@groove-dev/gui/src/components/ui/sheet.jsx +2 -2
  31. package/node_modules/@groove-dev/gui/src/stores/groove.js +32 -2
  32. package/node_modules/@groove-dev/gui/src/stores/slices/agents-slice.js +10 -1
  33. package/node_modules/@groove-dev/gui/src/stores/slices/chat-slice.js +1 -0
  34. package/node_modules/@groove-dev/gui/src/views/model-lab.jsx +27 -22
  35. package/package.json +1 -1
  36. package/packages/cli/package.json +1 -1
  37. package/packages/daemon/package.json +1 -1
  38. package/packages/daemon/src/api.js +12 -6
  39. package/packages/daemon/src/conversations.js +41 -10
  40. package/packages/daemon/src/introducer.js +20 -0
  41. package/packages/daemon/src/process.js +262 -15
  42. package/packages/daemon/src/providers/groove-network.js +1 -3
  43. package/packages/daemon/src/rotator.js +15 -3
  44. package/packages/daemon/src/routes/agents.js +43 -0
  45. package/packages/daemon/templates/lab-general.json +12 -0
  46. package/packages/daemon/templates/llama-cpp-setup.json +12 -0
  47. package/packages/gui/dist/assets/index-BKbsE_hn.js +1011 -0
  48. package/packages/gui/dist/assets/index-CEkPsSAm.css +1 -0
  49. package/packages/gui/dist/index.html +2 -2
  50. package/packages/gui/package.json +1 -1
  51. package/packages/gui/src/components/agents/spawn-wizard.jsx +132 -4
  52. package/packages/gui/src/components/chat/chat-header.jsx +1 -8
  53. package/packages/gui/src/components/chat/chat-input.jsx +135 -13
  54. package/packages/gui/src/components/chat/chat-messages.jsx +21 -4
  55. package/packages/gui/src/components/chat/chat-view.jsx +6 -5
  56. package/packages/gui/src/components/chat/model-picker.jsx +3 -3
  57. package/packages/gui/src/components/lab/chat-playground.jsx +3 -3
  58. package/packages/gui/src/components/lab/lab-assistant.jsx +9 -3
  59. package/packages/gui/src/components/lab/metrics-panel.jsx +13 -3
  60. package/packages/gui/src/components/lab/parameter-panel.jsx +5 -5
  61. package/packages/gui/src/components/lab/runtime-config.jsx +1 -3
  62. package/packages/gui/src/components/layout/app-shell.jsx +2 -0
  63. package/packages/gui/src/components/layout/status-bar.jsx +24 -1
  64. package/packages/gui/src/components/ui/question-modal.jsx +107 -0
  65. package/packages/gui/src/components/ui/sheet.jsx +2 -2
  66. package/packages/gui/src/stores/groove.js +32 -2
  67. package/packages/gui/src/stores/slices/agents-slice.js +10 -1
  68. package/packages/gui/src/stores/slices/chat-slice.js +1 -0
  69. package/packages/gui/src/views/model-lab.jsx +27 -22
  70. package/node_modules/@groove-dev/gui/dist/assets/index-Bxc0gU06.js +0 -1006
  71. package/node_modules/@groove-dev/gui/dist/assets/index-C0pztKBn.css +0 -1
  72. package/packages/gui/dist/assets/index-Bxc0gU06.js +0 -1006
  73. package/packages/gui/dist/assets/index-C0pztKBn.css +0 -1
@@ -314,6 +314,11 @@ export const useGrooveStore = create((set, get) => ({
314
314
  }
315
315
 
316
316
  case 'agent:exit': {
317
+ if (msg.status === 'waiting_for_input') {
318
+ const waitAgent = get().agents.find((a) => a.id === msg.agentId);
319
+ get().addToast('info', `${waitAgent?.name || msg.agentId.slice(0, 8)} needs your input`, 'Check the question popup below');
320
+ break;
321
+ }
317
322
  const agent = get().agents.find((a) => a.id === msg.agentId);
318
323
  const name = agent?.name || msg.agentId;
319
324
  const isKill = msg.status === 'killed' || msg.code === 143 || msg.code === 137;
@@ -415,6 +420,14 @@ export const useGrooveStore = create((set, get) => ({
415
420
  get().addChatMessage(msg.agentId, 'system', 'Agent is working — message will be delivered when it finishes.');
416
421
  break;
417
422
 
423
+ case 'agent:question':
424
+ set((s) => ({ pendingQuestions: [...s.pendingQuestions, msg.data] }));
425
+ break;
426
+
427
+ case 'agent:question:resolved':
428
+ set((s) => ({ pendingQuestions: s.pendingQuestions.filter((q) => q.agentId !== msg.agentId) }));
429
+ break;
430
+
418
431
  case 'ollama:pull:progress':
419
432
  set({ ollamaPullProgress: { ...get().ollamaPullProgress, [msg.model]: { status: 'pulling', progress: msg.progress } } });
420
433
  break;
@@ -450,6 +463,8 @@ export const useGrooveStore = create((set, get) => ({
450
463
  case 'lab:runtime:added':
451
464
  case 'lab:runtime:updated':
452
465
  case 'lab:runtime:removed':
466
+ case 'lab:runtime:started':
467
+ case 'lab:runtime:stopped':
453
468
  case 'llama:server:stopped':
454
469
  get().fetchLabRuntimes();
455
470
  break;
@@ -888,6 +903,17 @@ export const useGrooveStore = create((set, get) => ({
888
903
  break;
889
904
  }
890
905
 
906
+ case 'conversation:tool': {
907
+ const { conversationId, name, summary } = msg.data || msg;
908
+ if (!conversationId) break;
909
+ set((s) => {
910
+ const tools = { ...s.conversationActiveTools };
911
+ tools[conversationId] = { name: name || 'Tool', summary: summary || null, timestamp: Date.now() };
912
+ return { conversationActiveTools: tools };
913
+ });
914
+ break;
915
+ }
916
+
891
917
  case 'conversation:chunk': {
892
918
  const { conversationId, text } = msg.data || msg;
893
919
  if (!conversationId || !text) break;
@@ -902,7 +928,9 @@ export const useGrooveStore = create((set, get) => ({
902
928
  arr.push({ from: 'assistant', text, timestamp: Date.now() });
903
929
  }
904
930
  msgs[conversationId] = arr.slice(-200);
905
- return { conversationMessages: msgs, streamingConversationId: conversationId };
931
+ const tools = { ...s.conversationActiveTools };
932
+ delete tools[conversationId];
933
+ return { conversationMessages: msgs, streamingConversationId: conversationId, conversationActiveTools: tools };
906
934
  });
907
935
  break;
908
936
  }
@@ -910,7 +938,9 @@ export const useGrooveStore = create((set, get) => ({
910
938
  case 'conversation:complete': {
911
939
  const { conversationId } = msg.data || msg;
912
940
  if (conversationId && get().streamingConversationId === conversationId) {
913
- set({ sendingMessage: false, streamingConversationId: null });
941
+ const tools = { ...get().conversationActiveTools };
942
+ delete tools[conversationId];
943
+ set({ sendingMessage: false, streamingConversationId: null, conversationActiveTools: tools });
914
944
  }
915
945
  if (conversationId) persistJSON('groove:conversationMessages', get().conversationMessages);
916
946
  break;
@@ -14,6 +14,15 @@ export const createAgentsSlice = (set, get) => ({
14
14
  // Track which agents are thinking (sent a message, waiting for response)
15
15
  thinkingAgents: new Set(),
16
16
 
17
+ // Pending questions from agents awaiting user input
18
+ pendingQuestions: [],
19
+
20
+ answerQuestion(agentId, answers) {
21
+ return api.post(`/agents/${agentId}/answer`, { answers }).then(() => {
22
+ set((s) => ({ pendingQuestions: s.pendingQuestions.filter((q) => q.agentId !== agentId) }));
23
+ });
24
+ },
25
+
17
26
  // ── Workspace Mode ────────────────────────────────────────
18
27
  workspaceMode: localStorage.getItem('groove:workspaceMode') === 'true',
19
28
  workspaceAgentId: null,
@@ -38,7 +47,7 @@ export const createAgentsSlice = (set, get) => ({
38
47
 
39
48
  async spawnAgent(config) {
40
49
  try {
41
- const teamId = get().activeTeamId;
50
+ const teamId = config.teamId || get().activeTeamId;
42
51
  const agent = await api.post('/agents', { ...config, teamId });
43
52
  get().addToast('success', `Spawned ${agent.name}`);
44
53
  return agent;
@@ -10,6 +10,7 @@ export const createChatSlice = (set, get) => ({
10
10
  conversations: [],
11
11
  activeConversationId: localStorage.getItem('groove:activeConversationId') || null,
12
12
  conversationMessages: loadJSON('groove:conversationMessages'),
13
+ conversationActiveTools: {},
13
14
  sendingMessage: false,
14
15
  streamingConversationId: null,
15
16
  conversationRoles: loadJSON('groove:conversationRoles'),
@@ -135,6 +135,7 @@ export default function ModelLabView() {
135
135
  const labAssistantAgentId = useGrooveStore((s) => s.labAssistantAgentId);
136
136
  const labAssistantMode = useGrooveStore((s) => s.labAssistantMode);
137
137
  const setLabAssistantMode = useGrooveStore((s) => s.setLabAssistantMode);
138
+ const launchLabAssistant = useGrooveStore((s) => s.launchLabAssistant);
138
139
 
139
140
  useEffect(() => { fetchLabRuntimes(); }, [fetchLabRuntimes]);
140
141
 
@@ -234,28 +235,32 @@ export default function ModelLabView() {
234
235
  {leftCollapsed && (
235
236
  <PanelToggle collapsed onClick={() => setLeftCollapsed(false)} side="left" />
236
237
  )}
237
- {labAssistantAgentId && (
238
- <div className="flex items-center gap-px bg-surface-2 rounded p-px">
239
- <button
240
- onClick={() => setLabAssistantMode(false)}
241
- className={cn(
242
- 'px-3 py-1 text-2xs font-sans font-medium rounded-sm transition-colors cursor-pointer',
243
- !labAssistantMode ? 'text-text-0 bg-surface-4' : 'text-text-3 hover:text-text-1',
244
- )}
245
- >
246
- Playground
247
- </button>
248
- <button
249
- onClick={() => setLabAssistantMode(true)}
250
- className={cn(
251
- 'px-3 py-1 text-2xs font-sans font-medium rounded-sm transition-colors cursor-pointer',
252
- labAssistantMode ? 'text-text-0 bg-surface-4' : 'text-text-3 hover:text-text-1',
253
- )}
254
- >
255
- Assistant
256
- </button>
257
- </div>
258
- )}
238
+ <div className="flex items-center gap-px bg-surface-2 rounded p-px">
239
+ <button
240
+ onClick={() => setLabAssistantMode(false)}
241
+ className={cn(
242
+ 'px-3 py-1 text-2xs font-sans font-medium rounded-sm transition-colors cursor-pointer',
243
+ !labAssistantMode ? 'text-text-0 bg-surface-4' : 'text-text-3 hover:text-text-1',
244
+ )}
245
+ >
246
+ Playground
247
+ </button>
248
+ <button
249
+ onClick={() => {
250
+ if (labAssistantAgentId) {
251
+ setLabAssistantMode(true);
252
+ } else {
253
+ launchLabAssistant('lab-general');
254
+ }
255
+ }}
256
+ className={cn(
257
+ 'px-3 py-1 text-2xs font-sans font-medium rounded-sm transition-colors cursor-pointer',
258
+ labAssistantMode ? 'text-text-0 bg-surface-4' : 'text-text-3 hover:text-text-1',
259
+ )}
260
+ >
261
+ Assistant
262
+ </button>
263
+ </div>
259
264
  <div className="flex-1" />
260
265
  {rightCollapsed && (
261
266
  <PanelToggle collapsed onClick={() => setRightCollapsed(false)} side="right" />