Mac: type agent events end-to-end
This commit is contained in:
@@ -97,7 +97,8 @@ struct AgentEventsWindow_Previews: PreviewProvider {
|
|||||||
seq: 1,
|
seq: 1,
|
||||||
stream: "tool",
|
stream: "tool",
|
||||||
ts: Date().timeIntervalSince1970 * 1000,
|
ts: Date().timeIntervalSince1970 * 1000,
|
||||||
data: ["phase": AnyCodable("start"), "name": AnyCodable("bash")])
|
data: ["phase": AnyCodable("start"), "name": AnyCodable("bash")],
|
||||||
|
summary: nil)
|
||||||
AgentEventStore.shared.append(sample)
|
AgentEventStore.shared.append(sample)
|
||||||
return AgentEventsWindow()
|
return AgentEventsWindow()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,14 @@ struct ControlHeartbeatEvent: Codable {
|
|||||||
let reason: String?
|
let reason: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ControlAgentEvent: Codable, Sendable {
|
struct ControlAgentEvent: Codable, Sendable, Identifiable {
|
||||||
|
var id: String { "\(runId)-\(seq)" }
|
||||||
let runId: String
|
let runId: String
|
||||||
let seq: Int
|
let seq: Int
|
||||||
let stream: String
|
let stream: String
|
||||||
let ts: Double
|
let ts: Double
|
||||||
let data: [String: AnyCodable]
|
let data: [String: AnyCodable]
|
||||||
|
let summary: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ControlChannelError: Error, LocalizedError {
|
enum ControlChannelError: Error, LocalizedError {
|
||||||
@@ -135,31 +137,24 @@ final class ControlChannel: ObservableObject {
|
|||||||
queue: .main)
|
queue: .main)
|
||||||
{ [weak self] note in
|
{ [weak self] note in
|
||||||
guard let self,
|
guard let self,
|
||||||
let obj = note.userInfo as? [String: Any],
|
let frame = note.object as? GatewayFrame else { return }
|
||||||
let event = obj["event"] as? String else { return }
|
switch frame {
|
||||||
switch event {
|
case let .event(evt) where evt.event == "agent":
|
||||||
case "agent":
|
if let data = evt.payload?.value,
|
||||||
if let payload = obj["payload"] as? [String: Any],
|
JSONSerialization.isValidJSONObject(data),
|
||||||
let runId = payload["runId"] as? String,
|
let blob = try? JSONSerialization.data(withJSONObject: data),
|
||||||
let seq = payload["seq"] as? Int,
|
let agent = try? JSONDecoder().decode(AgentEvent.self, from: blob) {
|
||||||
let stream = payload["stream"] as? String,
|
|
||||||
let ts = payload["ts"] as? Double,
|
|
||||||
let dataDict = payload["data"] as? [String: Any]
|
|
||||||
{
|
|
||||||
let wrapped = dataDict.mapValues { AnyCodable($0) }
|
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
AgentEventStore.shared.append(ControlAgentEvent(
|
AgentEventStore.shared.append(ControlAgentEvent(
|
||||||
runId: runId,
|
runId: agent.runid,
|
||||||
seq: seq,
|
seq: agent.seq,
|
||||||
stream: stream,
|
stream: agent.stream,
|
||||||
ts: ts,
|
ts: Double(agent.ts),
|
||||||
data: wrapped))
|
data: agent.data.mapValues { Clawdis.AnyCodable($0.value) },
|
||||||
|
summary: nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "presence":
|
case let .event(evt) where evt.event == "shutdown":
|
||||||
// InstancesStore listens separately via notification
|
|
||||||
break
|
|
||||||
case "shutdown":
|
|
||||||
Task { @MainActor in self.state = .degraded("gateway shutdown") }
|
Task { @MainActor in self.state = .degraded("gateway shutdown") }
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user