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.
This commit is contained in:
Rocky
2026-08-23 14:02:33 +08:00
parent 7df5bbdaa0
commit 2cc81c4628
68 changed files with 10368 additions and 7765 deletions
@@ -240,6 +240,14 @@ enum ManagedGatewayHTTP {
let code = decoded?.code ?? HTTPURLResponse.localizedString(forStatusCode: status)
let resolvedRequestId = decoded?.requestId ?? requestId
return error(code: code, status: status, requestId: resolvedRequestId)
}
static func error(
code: String,
status: Int,
requestId: String?
) -> ManagedGatewayError {
switch code.lowercased() {
case "insufficient_credits", "insufficient_balance", "credit_balance_insufficient":
return .insufficientCredits
@@ -247,8 +255,29 @@ enum ManagedGatewayHTTP {
return .oobeFeatureAlreadyUsed
case "unauthorized", "invalid_gateway_refresh", "gateway_grant_denied", "invalid_grant":
return .invalidGrant
case "provider_unavailable":
return .providerUnavailable(requestId: requestId)
case "provider_rate_limited":
return .providerRateLimited(requestId: requestId)
case "provider_timeout":
return .providerTimeout(requestId: requestId)
case "provider_failure", "provider_invalid_response", "provider_error", "gateway_failure":
return .providerFailure(requestId: requestId)
case "internal_failure":
return .internalFailure(requestId: requestId)
default:
return .server(code: code, status: status, requestId: resolvedRequestId)
switch status {
case 429:
return .providerRateLimited(requestId: requestId)
case 502:
return .providerFailure(requestId: requestId)
case 503:
return .providerUnavailable(requestId: requestId)
case 504:
return .providerTimeout(requestId: requestId)
default:
return .server(code: code, status: status, requestId: requestId)
}
}
}
@@ -25,6 +25,12 @@ public enum ManagedGatewayTaskKind: String, Codable, CaseIterable, Sendable {
case agentPlanning = "agent_planning"
}
/// Audited product entry point. It affects usage attribution, never provider
/// selection or billing authority.
public enum ManagedGatewayRequestSource: String, Codable, Sendable {
case hotword
}
/// Optional server-audited purpose. A purpose may affect billing only when the
/// authenticated gateway independently verifies its eligibility.
public enum ManagedGatewayRequestPurpose: String, Codable, Sendable {
@@ -107,6 +113,11 @@ public enum ManagedGatewayError: Error, LocalizedError, Equatable, Sendable {
case insufficientCredits
case oobeFeatureAlreadyUsed
case timeout
case providerUnavailable(requestId: String?)
case providerRateLimited(requestId: String?)
case providerTimeout(requestId: String?)
case providerFailure(requestId: String?)
case internalFailure(requestId: String?)
case server(code: String, status: Int, requestId: String?)
public var errorDescription: String? {
@@ -127,6 +138,16 @@ public enum ManagedGatewayError: Error, LocalizedError, Equatable, Sendable {
return SharedL10n.string("managed.error.oobeFeatureAlreadyUsed")
case .timeout:
return SharedL10n.string("managed.error.timeout")
case .providerUnavailable:
return SharedL10n.string("managed.error.providerUnavailable")
case .providerRateLimited:
return SharedL10n.string("managed.error.providerRateLimited")
case .providerTimeout:
return SharedL10n.string("managed.error.providerTimeout")
case .providerFailure:
return SharedL10n.string("managed.error.providerFailure")
case .internalFailure:
return SharedL10n.string("managed.error.internalFailure")
case .server(let code, let status, _):
return SharedL10n.format(
"managed.error.server",
@@ -172,6 +193,7 @@ struct ManagedGatewayTextRequest: Encodable, Sendable {
let temperature: Double
let stream: Bool
let taskKind: ManagedGatewayTaskKind
let requestSource: ManagedGatewayRequestSource?
let requestPurpose: ManagedGatewayRequestPurpose?
let oobeFeature: ManagedGatewayOOBEFeature?
}
@@ -50,6 +50,7 @@ public struct ManagedLLMClient: LLMClient {
public let capability: Capability
public let taskKind: ManagedGatewayTaskKind
public let requestSource: ManagedGatewayRequestSource?
public let requestPurpose: ManagedGatewayRequestPurpose?
public let oobeFeature: ManagedGatewayOOBEFeature?
public let requestTimeout: TimeInterval
@@ -63,6 +64,7 @@ public struct ManagedLLMClient: LLMClient {
public init(
capability: Capability,
taskKind: ManagedGatewayTaskKind? = nil,
requestSource: ManagedGatewayRequestSource? = nil,
requestPurpose: ManagedGatewayRequestPurpose? = nil,
oobeFeature: ManagedGatewayOOBEFeature? = nil,
grants: GatewayGrantCoordinator,
@@ -74,6 +76,7 @@ public struct ManagedLLMClient: LLMClient {
) {
self.capability = capability
self.taskKind = taskKind ?? capability.defaultTaskKind
self.requestSource = requestSource
self.requestPurpose = requestPurpose
self.oobeFeature = oobeFeature
self.grants = grants
@@ -324,6 +327,7 @@ public struct ManagedLLMClient: LLMClient {
temperature: min(max(attempt.options.temperature ?? 0.2, 0), 1),
stream: stream,
taskKind: taskKind,
requestSource: requestSource,
requestPurpose: requestPurpose,
oobeFeature: oobeFeature
)
@@ -452,16 +456,11 @@ public struct ManagedLLMClient: LLMClient {
object["message"] != nil || code.hasSuffix("_error") else {
return nil
}
if ["insufficient_credits", "insufficient_balance"].contains(code) {
return .insufficientCredits
}
if code == "oobe_feature_already_used" {
return .oobeFeatureAlreadyUsed
}
if ["unauthorized", "gateway_grant_denied", "invalid_grant"].contains(code) {
return .invalidGrant
}
return .server(code: code, status: 200, requestId: requestId)
return ManagedGatewayHTTP.error(
code: code,
status: 200,
requestId: object["requestId"] as? String ?? requestId
)
}
}