Skip to content

Commit 71e63cc

Browse files
lawrence-forooghianGregHolmes
authored andcommitted
Fix the Swift translations in the AIT guides
Translated using the translate-examples-to-swift skill in the as-yet-unmerged PR #3192. I've reviewed them.
1 parent 095f0fd commit 71e63cc

2 files changed

Lines changed: 137 additions & 78 deletions

File tree

src/pages/docs/guides/ai-transport/anthropic/anthropic-message-per-response.mdx

Lines changed: 87 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,14 @@ await channel.subscribe((message) => {
645645
console.log('Subscriber ready, waiting for tokens...');
646646
```
647647

648+
{/* Swift example test harness
649+
ID: anthropic-message-per-response-1
650+
To verify: copy this comment into a Swift file, paste the example code into the function body, run `swift build`
651+
652+
@MainActor
653+
func example_anthropic_message_per_response_1() async throws {
654+
// --- example code starts here ---
655+
*/}
648656
```client_swift
649657
import Ably
650658
@@ -657,37 +665,48 @@ let channel = realtime.channels.get("ai:{{RANDOM_CHANNEL_NAME}}")
657665
// Track responses by message serial
658666
var responses: [String: String] = [:]
659667
660-
// Subscribe to receive messages
661-
channel.subscribe { message in
662-
guard let serial = message.serial else { return }
663-
664-
switch message.action {
665-
case .create:
666-
// New response started
667-
print("\n[Response started] \(serial)")
668-
responses[serial] = message.data as? String ?? ""
669-
670-
case .append:
671-
// Append token to existing response
672-
let current = responses[serial] ?? ""
673-
let token = message.data as? String ?? ""
674-
responses[serial] = current + token
675-
676-
// Display token as it arrives
677-
print(token, terminator: "")
678-
679-
case .update:
680-
// Replace entire response content
681-
responses[serial] = message.data as? String ?? ""
682-
print("\n[Response updated with full content]")
683-
684-
default:
685-
break
686-
}
668+
// Subscribe to receive messages and wait for the channel to attach
669+
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, any Error>) in
670+
channel.subscribe(attachCallback: { error in
671+
if let error {
672+
continuation.resume(throwing: error)
673+
} else {
674+
continuation.resume()
675+
}
676+
}, callback: { message in
677+
MainActor.assumeIsolated {
678+
guard let serial = message.serial else { return }
679+
guard let data = message.data as? String else { return }
680+
681+
switch message.action {
682+
case .create:
683+
// New response started
684+
print("\n[Response started] \(serial)")
685+
responses[serial] = data
686+
687+
case .append:
688+
// Append token to existing response
689+
let current = responses[serial] ?? ""
690+
responses[serial] = current + data
691+
692+
// Display token as it arrives
693+
print(data, terminator: "")
694+
695+
case .update:
696+
// Replace entire response content
697+
responses[serial] = data
698+
print("\n[Response updated with full content]")
699+
700+
default:
701+
break
702+
}
703+
}
704+
})
687705
}
688706
689707
print("Subscriber ready, waiting for tokens...")
690708
```
709+
{/* --- end example code --- */}
691710

692711
```client_java
693712
import io.ably.lib.realtime.AblyRealtime;
@@ -932,6 +951,14 @@ await channel.subscribe((message) => {
932951
});
933952
```
934953

954+
{/* Swift example test harness
955+
ID: anthropic-message-per-response-2
956+
To verify: copy this comment into a Swift file, paste the example code into the function body, run `swift build`
957+
958+
@MainActor
959+
func example_anthropic_message_per_response_2(realtime: ARTRealtime) async throws {
960+
// --- example code starts here ---
961+
*/}
935962
```client_swift
936963
// Use rewind to receive recent historical messages
937964
let channelOptions = ARTRealtimeChannelOptions()
@@ -941,29 +968,41 @@ let channel = realtime.channels.get("ai:{{RANDOM_CHANNEL_NAME}}", options: chann
941968
942969
var responses: [String: String] = [:]
943970
944-
channel.subscribe { message in
945-
guard let serial = message.serial else { return }
946-
947-
switch message.action {
948-
case .create:
949-
responses[serial] = message.data as? String ?? ""
950-
951-
case .append:
952-
let current = responses[serial] ?? ""
953-
let token = message.data as? String ?? ""
954-
responses[serial] = current + token
955-
print(token, terminator: "")
956-
957-
case .update:
958-
// Historical messages contain full concatenated response
959-
responses[serial] = message.data as? String ?? ""
960-
print("\n[Historical response]: \(responses[serial] ?? "")")
961-
962-
default:
963-
break
964-
}
971+
// Subscribe and wait for the channel to attach
972+
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, any Error>) in
973+
channel.subscribe(attachCallback: { error in
974+
if let error {
975+
continuation.resume(throwing: error)
976+
} else {
977+
continuation.resume()
978+
}
979+
}, callback: { message in
980+
MainActor.assumeIsolated {
981+
guard let serial = message.serial else { return }
982+
guard let data = message.data as? String else { return }
983+
984+
switch message.action {
985+
case .create:
986+
responses[serial] = data
987+
988+
case .append:
989+
let current = responses[serial] ?? ""
990+
responses[serial] = current + data
991+
print(data, terminator: "")
992+
993+
case .update:
994+
// Historical messages contain full concatenated response
995+
responses[serial] = data
996+
print("\n[Historical response]: \(responses[serial] ?? "")")
997+
998+
default:
999+
break
1000+
}
1001+
}
1002+
})
9651003
}
9661004
```
1005+
{/* --- end example code --- */}
9671006

9681007
```client_java
9691008
import io.ably.lib.realtime.AblyRealtime;

src/pages/docs/guides/ai-transport/anthropic/anthropic-message-per-token.mdx

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,14 @@ await channel.subscribe('stop', (message) => {
613613
console.log('Subscriber ready, waiting for tokens...');
614614
```
615615

616+
{/* Swift example test harness
617+
ID: anthropic-message-per-token-1
618+
To verify: copy this comment into a Swift file, paste the example code into the function body, run `swift build`
619+
620+
@MainActor
621+
func example_anthropic_message_per_token_1() async throws {
622+
// --- example code starts here ---
623+
*/}
616624
```client_swift
617625
import Ably
618626
@@ -625,40 +633,52 @@ let channel = realtime.channels.get("{{RANDOM_CHANNEL_NAME}}")
625633
// Track responses by ID
626634
var responses: [String: String] = [:]
627635
628-
// Handle response start
629-
channel.subscribe("start") { message in
630-
guard let extras = message.extras as? NSDictionary,
631-
let headers = extras["headers"] as? [String: Any],
632-
let responseId = headers["responseId"] as? String else { return }
633-
print("\n[Response started] \(responseId)")
634-
responses[responseId] = ""
635-
}
636-
637-
// Handle tokens
638-
channel.subscribe("token") { message in
639-
guard let extras = message.extras as? NSDictionary,
640-
let headers = extras["headers"] as? [String: Any],
641-
let responseId = headers["responseId"] as? String,
642-
let token = message.data as? String else { return }
643-
644-
// Append token to response
645-
responses[responseId, default: ""] += token
646-
647-
// Display token as it arrives
648-
print(token, terminator: "")
649-
}
650-
651-
// Handle response stop
652-
channel.subscribe("stop") { message in
653-
guard let extras = message.extras as? NSDictionary,
654-
let headers = extras["headers"] as? [String: Any],
655-
let responseId = headers["responseId"] as? String else { return }
656-
let finalText = responses[responseId] ?? ""
657-
print("\n[Response completed] \(responseId)")
636+
// Subscribe to all events and handle by message name
637+
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, any Error>) in
638+
channel.subscribe(attachCallback: { error in
639+
if let error {
640+
continuation.resume(throwing: error)
641+
} else {
642+
continuation.resume()
643+
}
644+
}) { message in
645+
MainActor.assumeIsolated {
646+
guard let extras = (try? message.extras?.toJSON()) as? [String: Any],
647+
let headers = extras["headers"] as? [String: Any],
648+
let responseID = headers["responseId"] as? String else { return }
649+
650+
switch message.name {
651+
case "start":
652+
// Handle response start
653+
print("\n[Response started] \(responseID)")
654+
responses[responseID] = ""
655+
656+
case "token":
657+
// Handle tokens
658+
guard let token = message.data as? String else { return }
659+
660+
// Append token to response
661+
let currentText = responses[responseID] ?? ""
662+
responses[responseID] = currentText + token
663+
664+
// Display token as it arrives
665+
print(token, terminator: "")
666+
667+
case "stop":
668+
// Handle response stop
669+
let finalText = responses[responseID]
670+
print("\n[Response completed] \(responseID)")
671+
672+
default:
673+
break
674+
}
675+
}
676+
}
658677
}
659678
660679
print("Subscriber ready, waiting for tokens...")
661680
```
681+
{/* --- end example code --- */}
662682

663683
```client_java
664684
import io.ably.lib.realtime.AblyRealtime;

0 commit comments

Comments
 (0)