- NSPanel-backed DevOverlayWindow (.floating + .nonactivating) hidden by default - SwiftUI DevOverlayView renders OBS-01 surface: state/turn, provider/model, token counts, cache creation/read + hit %, latency, last-5 tool calls - @Observable @MainActor DevOverlayViewModel — single write path via apply() - DevOverlayBridge pumps BoundedAsyncChannel<DevSnapshot> → ViewModel - DevSnapshot + ToolCallRow live in AgentOrchestrator target (Rule 3 deviation from plan's files_modified: DevSnapshotEmitter consumes both OrchestratorEvent and DevSnapshot, so parking both in AgentOrchestrator avoids the circular AgentOrchestrator→DevOverlay→AgentOrchestrator dep) - Additive OrchestratorEvent.usage(turnId:usage:) — surfaces TurnUsage to DevOverlay without reading replay; no nonce (SEC-06 preserved) - AgentOrchestrator now emits .usage on LLMEvent.usage alongside replay write - 14 DevOverlay tests pass; 114 AgentCore tests pass (no regression)
41 lines
1.1 KiB
Swift
41 lines
1.1 KiB
Swift
import Foundation
|
|
|
|
/// One row in the DevOverlay's "last 5 tool calls" table (OBS-01).
|
|
///
|
|
/// `id` == the `toolUseId` from the provider; the emitter dedupes on this
|
|
/// so repeated `.toolCardUpdate` events for the same tool_use update the
|
|
/// existing row rather than pushing a new one. `preview` is capped at 200
|
|
/// characters upstream (`ToolCardUpdate.resultPreview`, Plan 04-04).
|
|
public struct ToolCallRow: Sendable, Equatable, Identifiable {
|
|
public enum Status: Sendable, Equatable {
|
|
case pending
|
|
case running
|
|
case completed
|
|
case failed
|
|
case awaitingApproval
|
|
}
|
|
|
|
public let id: String
|
|
public let name: String
|
|
public let status: Status
|
|
public let durationMs: Int
|
|
public let preview: String?
|
|
public let error: String?
|
|
|
|
public init(
|
|
id: String,
|
|
name: String,
|
|
status: Status,
|
|
durationMs: Int,
|
|
preview: String?,
|
|
error: String? = nil
|
|
) {
|
|
self.id = id
|
|
self.name = name
|
|
self.status = status
|
|
self.durationMs = durationMs
|
|
self.preview = preview
|
|
self.error = error
|
|
}
|
|
}
|