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:
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user