mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-16 00:40:49 +08:00
重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。
同时收敛启动与运维脚本默认行为(含 wiki worker)、更新 Admin 可观测性与相关测试,降低首轮时延并提高运行稳定性。 Made-with: Cursor
This commit is contained in:
parent
4a23b715a2
commit
dbbe3add6a
14438 changed files with 2693620 additions and 2546 deletions
62
openclaw/apps/macos/Sources/OpenClaw/VoiceWakeOverlay.swift
Normal file
62
openclaw/apps/macos/Sources/OpenClaw/VoiceWakeOverlay.swift
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import AppKit
|
||||
import Observation
|
||||
import SwiftUI
|
||||
|
||||
/// Lightweight, borderless panel that shows the current voice wake transcript near the menu bar.
|
||||
@MainActor
|
||||
@Observable
|
||||
final class VoiceWakeOverlayController {
|
||||
static let shared = VoiceWakeOverlayController()
|
||||
|
||||
let logger = Logger(subsystem: "ai.openclaw", category: "voicewake.overlay")
|
||||
let enableUI: Bool
|
||||
|
||||
/// Keep the voice wake overlay above any other OpenClaw windows, but below the system’s pop-up menus.
|
||||
/// (Menu bar menus typically live at `.popUpMenu`.)
|
||||
static let preferredWindowLevel = NSWindow.Level(rawValue: NSWindow.Level.popUpMenu.rawValue - 4)
|
||||
|
||||
enum Source: String { case wakeWord, pushToTalk }
|
||||
|
||||
var model = Model()
|
||||
var isVisible: Bool {
|
||||
self.model.isVisible
|
||||
}
|
||||
|
||||
struct Model {
|
||||
var text: String = ""
|
||||
var isFinal: Bool = false
|
||||
var isVisible: Bool = false
|
||||
var forwardEnabled: Bool = false
|
||||
var isSending: Bool = false
|
||||
var attributed: NSAttributedString = .init(string: "")
|
||||
var isOverflowing: Bool = false
|
||||
var isEditing: Bool = false
|
||||
var level: Double = 0 // normalized 0...1 speech level for UI
|
||||
}
|
||||
|
||||
var window: NSPanel?
|
||||
var hostingView: NSHostingView<VoiceWakeOverlayView>?
|
||||
var autoSendTask: Task<Void, Never>?
|
||||
var autoSendToken: UUID?
|
||||
var activeToken: UUID?
|
||||
var activeSource: Source?
|
||||
var lastLevelUpdate: TimeInterval = 0
|
||||
|
||||
let width: CGFloat = 360
|
||||
let padding: CGFloat = 10
|
||||
let buttonWidth: CGFloat = 36
|
||||
let spacing: CGFloat = 8
|
||||
let verticalPadding: CGFloat = 8
|
||||
let maxHeight: CGFloat = 400
|
||||
let minHeight: CGFloat = 48
|
||||
let closeOverflow: CGFloat = 10
|
||||
let levelUpdateInterval: TimeInterval = 1.0 / 12.0
|
||||
|
||||
enum DismissReason { case explicit, empty }
|
||||
enum SendOutcome { case sent, empty }
|
||||
enum GuardOutcome { case accept, dropMismatch, dropNoActive }
|
||||
|
||||
init(enableUI: Bool = true) {
|
||||
self.enableUI = enableUI
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue