Files
Rocky 2cc81c4628 feat(keyboard): expand contextual skills and managed flows
Add local clipboard intent recommendations, webpage and phone actions, and safer host handoffs. Refine managed gateway, catalog refresh, onboarding, and adaptive polish behavior.
2026-08-23 14:02:33 +08:00

112 lines
4.6 KiB
Swift

// FlowCommand.swift
// OSGKeyboard · Shared
import Foundation
public struct FlowCommand: Codable, Equatable, Sendable {
public enum Action: String, Codable, Sendable {
case startRecording
case stopRecording
case abort
/// Light warm-up: ASR locale/assets only — no mic capture.
case prewarm
/// User has touched the mic; prime capture before tap/hold resolves.
case primeAudio
/// Touch ended without an utterance adopting the primed capture.
case cancelPrimeAudio
/// Remove one temporary AI conversation from host memory.
case endAIConversation
/// AI mode: submit a prefilled question and skip ASR.
case submitAIQuestion
}
/// Wire version that includes host-side webpage summary extraction.
public static let currentProtocolVersion = 10
public let protocolVersion: Int
public let sessionId: UUID
public let utteranceId: UUID
public let commandSeq: Int64
public let action: Action
public let localeId: String
public let createdAt: TimeInterval
public let fieldContext: FlowFieldContext?
/// Dictation (default) vs explicit edit mode. Absent on legacy v1 → dictation.
public let utteranceMode: FlowUtteranceMode?
/// Verified source for explicit last-input editing.
public let editSourceText: String?
public let sourceHistoryEntryID: UUID?
public let sourceHistoryEntryRevision: Int64?
/// Host-memory conversation used only by `.aiQuestion`.
public let aiConversationID: UUID?
/// Prefilled question used only by `.submitAIQuestion`.
public let aiQuestionText: String?
/// Public webpage fetched by the host for an explicit summary skill.
public let aiWebPageURL: URL?
/// Fine-grained managed-gateway intent for AI question submissions.
public let aiTaskKind: ManagedGatewayTaskKind?
/// Audited product entry point for managed usage attribution.
public let managedRequestSource: ManagedGatewayRequestSource?
/// Optional server-audited purpose for managed gateway billing policy.
public let managedRequestPurpose: ManagedGatewayRequestPurpose?
/// Required feature discriminator when `managedRequestPurpose == .oobe`.
public let managedOOBEFeature: ManagedGatewayOOBEFeature?
/// Clipboard-skill thinking override. Nil keeps AI-mode default (on).
public let aiThinkingEnabled: Bool?
/// Absolute wall-clock deadlines survive extension reconstruction.
public let startDeadlineAt: TimeInterval?
public let processingDeadlineAt: TimeInterval?
public init(
protocolVersion: Int = FlowCommand.currentProtocolVersion,
sessionId: UUID,
utteranceId: UUID,
commandSeq: Int64,
action: Action,
localeId: String,
createdAt: TimeInterval = Date().timeIntervalSince1970,
fieldContext: FlowFieldContext? = nil,
utteranceMode: FlowUtteranceMode? = nil,
editSourceText: String? = nil,
sourceHistoryEntryID: UUID? = nil,
sourceHistoryEntryRevision: Int64? = nil,
aiConversationID: UUID? = nil,
aiQuestionText: String? = nil,
aiWebPageURL: URL? = nil,
aiTaskKind: ManagedGatewayTaskKind? = nil,
managedRequestSource: ManagedGatewayRequestSource? = nil,
managedRequestPurpose: ManagedGatewayRequestPurpose? = nil,
managedOOBEFeature: ManagedGatewayOOBEFeature? = nil,
aiThinkingEnabled: Bool? = nil,
startDeadlineAt: TimeInterval? = nil,
processingDeadlineAt: TimeInterval? = nil
) {
self.protocolVersion = protocolVersion
self.sessionId = sessionId
self.utteranceId = utteranceId
self.commandSeq = commandSeq
self.action = action
self.localeId = localeId
self.createdAt = createdAt
self.fieldContext = fieldContext
self.utteranceMode = utteranceMode
self.editSourceText = editSourceText
self.sourceHistoryEntryID = sourceHistoryEntryID
self.sourceHistoryEntryRevision = sourceHistoryEntryRevision
self.aiConversationID = aiConversationID
self.aiQuestionText = aiQuestionText
self.aiWebPageURL = aiWebPageURL
self.aiTaskKind = aiTaskKind
self.managedRequestSource = managedRequestSource
self.managedRequestPurpose = managedRequestPurpose
self.managedOOBEFeature = managedOOBEFeature
self.aiThinkingEnabled = aiThinkingEnabled
self.startDeadlineAt = startDeadlineAt
self.processingDeadlineAt = processingDeadlineAt
}
public var resolvedUtteranceMode: FlowUtteranceMode {
utteranceMode ?? .dictation
}
}