mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-03 14:21:39 +00:00
* feat(apple): complete media playback and uploads * fix(apple): preserve movie picker metadata * fix(apple): harden rendition and picker routing * style(apple): fix macOS media formatting
48 lines
1.4 KiB
Swift
48 lines
1.4 KiB
Swift
import Foundation
|
|
|
|
struct ChatMediaPlaybackRetryPolicy: Sendable {
|
|
/// Eleven waits total 120 seconds. The initial request plus these retries
|
|
/// gives transcoding time to finish without leaving a card pending forever.
|
|
static let bounded = ChatMediaPlaybackRetryPolicy(delays: [
|
|
.seconds(1),
|
|
.seconds(2),
|
|
.seconds(4),
|
|
.seconds(8),
|
|
.seconds(15),
|
|
.seconds(15),
|
|
.seconds(15),
|
|
.seconds(15),
|
|
.seconds(15),
|
|
.seconds(15),
|
|
.seconds(15),
|
|
])
|
|
|
|
let delays: [Duration]
|
|
}
|
|
|
|
enum ChatMediaPlaybackLoader {
|
|
typealias Load = @MainActor @Sendable () async throws -> OpenClawChatLoadedMedia?
|
|
typealias Sleep = @MainActor @Sendable (Duration) async throws -> Void
|
|
|
|
@MainActor
|
|
static func load(
|
|
policy: ChatMediaPlaybackRetryPolicy = .bounded,
|
|
request: Load,
|
|
onPreparing: @MainActor @Sendable () -> Void,
|
|
sleep: Sleep = { try await Task.sleep(for: $0) }) async throws -> OpenClawChatLoadedMedia?
|
|
{
|
|
var loaded = try await request()
|
|
guard case .preparing = loaded else { return loaded }
|
|
onPreparing()
|
|
|
|
for delay in policy.delays {
|
|
try Task.checkCancellation()
|
|
try await sleep(delay)
|
|
loaded = try await request()
|
|
guard case .preparing = loaded else { return loaded }
|
|
onPreparing()
|
|
}
|
|
return nil
|
|
}
|
|
}
|