diff --git a/cmd/picoclaw/cmd_gateway.go b/cmd/picoclaw/cmd_gateway.go index 794924f19..315b4e4a0 100644 --- a/cmd/picoclaw/cmd_gateway.go +++ b/cmd/picoclaw/cmd_gateway.go @@ -115,8 +115,11 @@ func gatewayCmd() { if response == "HEARTBEAT_OK" { return tools.SilentResult("Heartbeat OK") } - // For heartbeat, always return silent - the subagent result will be - // sent to user via processSystemMessage when the async task completes + // Deliver response to user when a plan interview/review needs resuming. + // For async tasks (spawn), results are delivered separately via processSystemMessage. + if status := agentLoop.GetPlanStatus(); status == "interviewing" || status == "review" { + return tools.UserResult(response) + } return tools.SilentResult(response) }) diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index 6d76c6ae9..e3194869f 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -2301,6 +2301,15 @@ func (al *AgentLoop) GetPlanInfo() (hasPlan bool, status string, currentPhase, t return } +// GetPlanStatus returns the current plan status ("interviewing", "executing", "review", etc.) or "". +func (al *AgentLoop) GetPlanStatus() string { + agent := al.registry.GetDefaultAgent() + if agent == nil { + return "" + } + return agent.ContextBuilder.GetPlanStatus() +} + // GetPlanPhases returns structured phase/step data from the default agent's plan. func (al *AgentLoop) GetPlanPhases() []PlanPhase { agent := al.registry.GetDefaultAgent()