feat(monitor): agent.started + agent.complete channel notifications
- emitStartEvent fires when agent spawns (dispatch.go) - Monitor detects new "running" workspaces and pushes agent.started channel notification with repo and agent info - agent.complete already included blocked/failed status — no change - Both old and new workspace layouts supported Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
abe5ef342a
commit
4bcc04d890
3 changed files with 27 additions and 5 deletions
|
|
@ -145,6 +145,9 @@ func (s *PrepSubsystem) spawnAgent(agent, prompt, wsDir string) (int, string, er
|
|||
proc.CloseStdin()
|
||||
pid := proc.Info().PID
|
||||
|
||||
// Emit start event for channel notifications
|
||||
emitStartEvent(agent, core.PathBase(wsDir))
|
||||
|
||||
go func() {
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
|
|
|||
|
|
@ -22,14 +22,12 @@ type CompletionEvent struct {
|
|||
Timestamp string `json:"timestamp"`
|
||||
}
|
||||
|
||||
// emitCompletionEvent appends a completion event to the events log.
|
||||
// The plugin's hook watches this file to notify the orchestrating agent.
|
||||
// Status should be the actual terminal state: completed, failed, or blocked.
|
||||
func emitCompletionEvent(agent, workspace, status string) {
|
||||
// emitEvent appends an event to the events log.
|
||||
func emitEvent(eventType, agent, workspace, status string) {
|
||||
eventsFile := core.JoinPath(WorkspaceRoot(), "events.jsonl")
|
||||
|
||||
event := CompletionEvent{
|
||||
Type: "agent_completed",
|
||||
Type: eventType,
|
||||
Agent: agent,
|
||||
Workspace: workspace,
|
||||
Status: status,
|
||||
|
|
@ -50,3 +48,13 @@ func emitCompletionEvent(agent, workspace, status string) {
|
|||
defer wc.Close()
|
||||
wc.Write(append(data, '\n'))
|
||||
}
|
||||
|
||||
// emitStartEvent logs that an agent has been spawned.
|
||||
func emitStartEvent(agent, workspace string) {
|
||||
emitEvent("agent_started", agent, workspace, "running")
|
||||
}
|
||||
|
||||
// emitCompletionEvent logs that an agent has finished.
|
||||
func emitCompletionEvent(agent, workspace, status string) {
|
||||
emitEvent("agent_completed", agent, workspace, status)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ type Subsystem struct {
|
|||
// Track last seen state to only notify on changes
|
||||
lastCompletedCount int // completed workspaces seen on the last scan
|
||||
seenCompleted map[string]bool // workspace names we've already notified about
|
||||
seenRunning map[string]bool // workspace names we've already sent start notification for
|
||||
completionsSeeded bool // true after first completions check
|
||||
lastInboxMaxID int // highest message ID seen
|
||||
inboxSeeded bool // true after first inbox check
|
||||
|
|
@ -124,6 +125,7 @@ func New(opts ...Options) *Subsystem {
|
|||
interval: interval,
|
||||
poke: make(chan struct{}, 1),
|
||||
seenCompleted: make(map[string]bool),
|
||||
seenRunning: make(map[string]bool),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -304,6 +306,15 @@ func (m *Subsystem) checkCompletions() string {
|
|||
}
|
||||
case "running":
|
||||
running++
|
||||
if !m.seenRunning[wsName] && seeded {
|
||||
m.seenRunning[wsName] = true
|
||||
if m.notifier != nil {
|
||||
m.notifier.ChannelSend(context.Background(), "agent.started", map[string]any{
|
||||
"repo": st.Repo,
|
||||
"agent": st.Agent,
|
||||
})
|
||||
}
|
||||
}
|
||||
case "queued":
|
||||
queued++
|
||||
case "blocked", "failed":
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue