Browse Source

Merge pull request #725 from umi008/fix/669-herdr-subagent-idle

fix: track busy Herdr subagents without known agent name
Alvin 4 weeks ago
parent
commit
fee42939c1
2 changed files with 29 additions and 3 deletions
  1. 25 1
      src/companion/manager.test.ts
  2. 4 2
      src/companion/manager.ts

+ 25 - 1
src/companion/manager.test.ts

@@ -202,12 +202,36 @@ describe('CompanionManager', () => {
     expect(readState().sessions[0].active_agents).toEqual(['intro']);
   });
 
-  it('ignores status events without agent or with unknown status', () => {
+  it('ignores status events with unknown status but tracks busy without agent', () => {
     const m = make();
     m.onLoad();
     m.onSessionStatus({ sessionId: 'ses_x', agent: undefined, status: 'busy' });
     m.onSessionStatus({ sessionId: 'ses_y', agent: 'fixer', status: 'retry' });
+    // ses_x is now tracked because Herdr subagents often lack
+    // the agent field; the session ID is used as a fallback name.
+    expect(readState().sessions[0].active_agents).toEqual(['ses_x']);
+  });
+
+  it('accepts busy sessions from agents without a known name (Herdr subagents)', () => {
+    const m = make();
+    m.onLoad();
+    // Simulate a Herdr subagent: busy event fires but agent is undefined
+    m.onSessionStatus({
+      sessionId: 'herdr_ses',
+      agent: undefined,
+      status: 'busy',
+    });
+    expect(readState().sessions[0].active_agents).toEqual(['herdr_ses']);
+    // The overall status stays 'idle' — only the orchestrator drives
+    // that field. Herdr subagents appear in active_agents.
+    // When the session goes idle it is removed even without a known agent name
+    m.onSessionStatus({
+      sessionId: 'herdr_ses',
+      agent: undefined,
+      status: 'idle',
+    });
     expect(readState().sessions[0].active_agents).toEqual(['intro']);
+    expect(readState().sessions[0].status).toBe('idle');
   });
 
   it('shows input gif while waiting for user input', () => {

+ 4 - 2
src/companion/manager.ts

@@ -321,8 +321,10 @@ export class CompanionManager {
     }
 
     if (status === 'busy') {
-      if (!agent) return;
-      this.busyAgentSessions.set(sessionId, agent);
+      // Accept busy sessions even without a known agent name — Herdr
+      // subagents (spawned via opencode attach) often lack the agent
+      // field, and dropping the event leaves them shown as idle.
+      this.busyAgentSessions.set(sessionId, agent ?? sessionId);
     } else {
       // Remove by session even when the agent name is unknown, so a
       // finished specialist can never get stuck on screen.