AI Assistant (TSAIAssistantInterface)
The AI Assistant provides streaming text summarization and long-running, device-microphone voice-chat sessions.
Prerequisites
TSAIContext *context = [TSAIKit sharedInstance].activeContext;
id<TSAIAssistantInterface> assistant = context.assistant;
Query TSAIFeatureAISummary or TSAIFeatureAIChat before using the corresponding API. Voice chat also requires a connected device and a supported audio path.
Data models
Text summary
| Model | Main properties | Description |
|---|---|---|
TSAISummaryPartialResult | taskId, text | Cumulative streaming text |
TSAISummaryResult | taskId, text, duration | Final summary |
Voice chat
| Model | Main properties | Description |
|---|---|---|
TSAIChatConfig | audioRouteConfiguration, languageHint, initialPrompt, agentId, speakerId | Audio route, language, role, and prompt configuration |
TSAIChatConfig | enableVoiceOutput, allowUserInterrupt | Voice output and interruption options |
TSAIChatConfig | silenceBeforeReplyInterval, autoEndSessionTimeout | VAD wait and automatic session timeout |
TSAIChatContent | contentType, roundIndex, text, isTextFinal | Question or answer text and finality |
TSAIChatContent | audioChunk, audioFormat, isAudioFinal, intent | Incremental audio, its format, and business intent |
TSAIChatIntent | type, intentId, query, value, valueDictionary | Structured device-control or business intent |
TSAIChatEvent | eventType, timestamp | VAD, playback, network, and session events |
TSAIChatReport | startTime, endTime, roundCount, endReason | Final session report |
Create a configuration with [TSAIChatConfig defaultConfig].
Callback types
| Callback | Description |
|---|---|
TSAISummaryPartialBlock | Zero or more cumulative summary updates |
TSAISummaryCompletionBlock | Invoked once on success, failure, or cancellation |
TSAIChatContentBlock | High-frequency text, audio, or intent content |
TSAIChatEventBlock | Low-frequency session events |
TSAIChatCompletionBlock | Final report or error |
TSAIChatStateBlock | App-facing chat state |
Text summary
- (NSString *)summarizeText:(NSString *)text
onPartialResult:(nullable TSAISummaryPartialBlock)onPartialResult
completion:(nullable TSAISummaryCompletionBlock)completion;
- (void)cancelSummarizeWithTaskId:(NSString *)taskId;
NSString *taskId = [assistant summarizeText:sourceText
onPartialResult:^(TSAISummaryPartialResult *partial) {
TSLog(@"Summary: %@", partial.text);
}
completion:^(TSAISummaryResult *result, NSError *error) {
if (error) {
TSLog(@"Summary failed: %@", error.localizedDescription);
return;
}
TSLog(@"Final summary: %@", result.text);
}];
// [assistant cancelSummarizeWithTaskId:taskId];
The synchronously returned client task ID is echoed by every partial and final result. Text that exceeds the provider context window fails validation and is not silently truncated.
Voice chat
- (NSString *)startChatWithConfig:(TSAIChatConfig *)config
onContent:(nullable TSAIChatContentBlock)onContent
onEvent:(nullable TSAIChatEventBlock)onEvent
completion:(nullable TSAIChatCompletionBlock)completion;
- (void)stopChatWithTaskId:(NSString *)taskId;
TSAIChatConfig *config = [TSAIChatConfig defaultConfig];
config.languageHint = @"en-US";
config.enableVoiceOutput = YES;
config.audioRouteConfiguration = [TSAIAudioRouteConfiguration defaultConfiguration];
NSString *chatTaskId = [assistant startChatWithConfig:config
onContent:^(TSAIChatContent *content) {
if (content.text.length > 0) {
TSLog(@"Chat content: %@", content.text);
}
}
onEvent:^(TSAIChatEvent *event) {
TSLog(@"Chat event: %ld", (long)event.eventType);
}
completion:^(TSAIChatReport *report, NSError *error) {
if (error) {
TSLog(@"Chat ended with error: %@", error.localizedDescription);
return;
}
TSLog(@"Chat rounds: %ld", (long)report.roundCount);
}];
// Gracefully flush and stop.
// [assistant stopChatWithTaskId:chatTaskId];
The SDK manages device activation, microphone audio, and the ASR → LLM → TTS pipeline. VAD segments multiple rounds. Stop the session explicitly or configure autoEndSessionTimeout.
Device events and state
- (void)registerOnAIChatDeviceEvent:(nullable void (^)(TSAIChatDeviceEvent event))deviceEventBlock;
- (void)registerAIChatStateDidChanged:(nullable TSAIChatStateBlock)stateBlock;
[assistant registerOnAIChatDeviceEvent:^(TSAIChatDeviceEvent event) {
if (event == TSAIChatDeviceEventRequestStart) {
TSLog(@"The device requested AI chat");
}
}];
A device event is a request signal; it does not change SDK state automatically. On RequestStart, call startChatWithConfig: to prepare but do not present UI yet. Present it only after onEvent receives TSAIChatEventTypeSessionStarted, confirming device synchronization. Handle RequestEnd with stopChatWithTaskId:.
Key enums
TSAIChatContentType
| Value | Raw value | Meaning |
|---|---|---|
TSAIChatContentTypeUnknown | -1 | Unknown content |
TSAIChatContentTypeQuestion | 1 | User question text |
TSAIChatContentTypeAnswer | 2 | AI answer text |
TSAIChatContentTypeAudioChunk | 3 | Incremental AI answer audio |
TSAIChatContentTypeIntent | 4 | Device-control or business intent |
TSAIChatEventType
| Value | Raw value | Meaning |
|---|---|---|
TSAIChatEventTypeUnknown | -1 | Unknown event |
TSAIChatEventTypeSessionStarted | 1 | Session started |
TSAIChatEventTypeUserSpeechStarted | 2 | User speech started |
TSAIChatEventTypeUserSpeechEnded | 3 | User speech ended |
TSAIChatEventTypeAIPlaybackStarted | 4 | AI playback started |
TSAIChatEventTypeAIPlaybackEnded | 5 | AI playback ended |
TSAIChatEventTypeAIPlaybackInterrupted | 6 | AI playback was interrupted |
TSAIChatEventTypeNetworkError | 7 | Network error |
TSAIChatEventTypeBleDisconnected | 8 | BLE device disconnected |
TSAIChatEventTypeAutoEnding | 9 | Session is about to end automatically |
Device events, session states, and end reasons
| Enum | Values and raw values |
|---|---|
TSAIChatDeviceEvent | RequestStart = 0, RequestEnd = 1, Interrupted = 2 |
TSAIChatState | DeviceClosed = 0, DeviceOpened = 1, Started = 2, Ended = 3, Interrupted = 255 |
TSAIChatEndReason | Unknown = -1, UserStop = 1, Timeout = 2, Cancelled = 3, Error = 4 |
Add the corresponding enum prefix to shortened values in this table, for example TSAIChatStateStarted.
Important notes
- Completion is the authoritative terminal signal.
stopChatWithTaskId:is graceful; an unknown or completed task ID is a no-op.- Unregister device-event and state callbacks when the owning screen is destroyed.
- Avoid blocking I/O in high-frequency audio callbacks.