fix(mac): reflect agent activity in menu icon

main
Peter Steinberger 2025-12-12 17:20:06 +00:00
parent fd0314a6bd
commit c417517f43
1 changed files with 31 additions and 11 deletions

View File

@ -212,19 +212,13 @@ final class ControlChannel: ObservableObject {
let frame = note.object as? GatewayFrame else { return } let frame = note.object as? GatewayFrame else { return }
switch frame { switch frame {
case let .event(evt) where evt.event == "agent": case let .event(evt) where evt.event == "agent":
if let data = evt.payload?.value, if let payload = evt.payload,
JSONSerialization.isValidJSONObject(data), let payloadData = try? JSONEncoder().encode(payload),
let blob = try? JSONSerialization.data(withJSONObject: data), let agent = try? JSONDecoder().decode(ControlAgentEvent.self, from: payloadData)
let agent = try? JSONDecoder().decode(AgentEvent.self, from: blob)
{ {
Task { @MainActor in Task { @MainActor in
AgentEventStore.shared.append(ControlAgentEvent( AgentEventStore.shared.append(agent)
runId: agent.runid, self.routeWorkActivity(from: agent)
seq: agent.seq,
stream: agent.stream,
ts: Double(agent.ts),
data: agent.data.mapValues { Clawdis.AnyCodable($0.value) },
summary: nil))
} }
} }
case let .event(evt) where evt.event == "shutdown": case let .event(evt) where evt.event == "shutdown":
@ -242,6 +236,32 @@ final class ControlChannel: ObservableObject {
} }
self.eventTokens = [ev, tick] self.eventTokens = [ev, tick]
} }
private func routeWorkActivity(from event: ControlAgentEvent) {
// We currently treat VoiceWake as the "main" session for UI purposes.
// In the future, the gateway can include a sessionKey to distinguish runs.
let sessionKey = (event.data["sessionKey"]?.value as? String) ?? "main"
switch event.stream.lowercased() {
case "job":
if let state = event.data["state"]?.value as? String {
WorkActivityStore.shared.handleJob(sessionKey: sessionKey, state: state)
}
case "tool":
let phase = event.data["phase"]?.value as? String ?? ""
let name = event.data["name"]?.value as? String
let meta = event.data["meta"]?.value as? String
let args = event.data["args"]?.value as? [String: AnyCodable]
WorkActivityStore.shared.handleTool(
sessionKey: sessionKey,
phase: phase,
name: name,
meta: meta,
args: args)
default:
break
}
}
} }
extension Notification.Name { extension Notification.Name {