Skip to content

1.2.0

Latest

Choose a tag to compare

@JinHyeong0709 JinHyeong0709 released this 20 Jul 07:11

Highlights

This release adds streaming Text-to-Speech, richer avatar layout controls, and Speech-to-Text text normalization, alongside several error-handling improvements.

Upgrading from 1.1.1? This release changes a few public error cases — see Migration below.

Added

  • Streaming Text-to-Speech. When the session's TTS model supports streaming (TTSType.streamable), the built-in synthesizer now streams audio in chunks so playback starts with lower latency. No configuration is required. Custom SpeechSynthesizable providers can return .stream(_:) to stream audio as well.
  • PersoInteractiveSession.prompt. Exposes the prompt resolved from the Perso AI backoffice at session start, including the system prompt and intro message.
  • PersoInteractiveVideoView.offsetX. Applies a horizontal offset, in points, to the video content (companion to the existing offsetY).
  • PersoInteractiveVideoView.scaleAnchor and the ScaleAnchor enum (.top, .center, .bottom). Determines which edge stays fixed while scaleFactor is applied. Defaults to .bottom.
  • Speech-to-Text text normalization. SessionCapability.speechToText now accepts optional normalizationConfigID and normalizationLocale parameters, and SessionTemplate exposes sttTextNormalizationConfig / sttTextNormalizationLocale.
  • PersoInteractiveSession.logSessionEvent(_:file:). Optionally attach a local file to a logged session event; the file is viewable in the Perso AI backoffice.
  • New error cases PersoInteractiveError.doesNotExist(attribute:detail:) and PersoInteractiveError.notInOrganization(attribute:detail:) for clearer server-side failures (e.g. a missing tts_type/prompt, or a resource outside your organization).

Changed

  • scaleFactor maximum raised from 1.5 to 2.0 (clamped to 0.1...2.0).
  • contentHeightFactor now also applies in .aspectFill mode (cropping from the bottom) and is clamped to 0.1...1.0.
  • transcribeAudio(audio:language:) now throws PersoInteractiveError.speechRecognitionNoSpeechDetected when the audio is empty, silent, or contains no recognizable speech.
  • push(text:) ignores text that is empty (or emoji-only) after normalization.
  • Public enums now explicitly conform to Sendable (SessionCapability, SessionStatus, TerminatedReason, PersoInteractiveMLComputeUnits, ScaleAnchor, VideoContentMode), removing strict-concurrency warnings for Swift 6 clients. ScaleAnchor and VideoContentMode are additionally @frozen, allowing exhaustive switch statements.

Fixed

  • .aspectFill mode incorrectly used the viewport height when computing width.

Deprecated

  • PersoInteractiveVideoView.playIntro(_:). Read session.prompt?.introMessage directly and speak it via push(text:) to align with the normal assistant message flow.

Removed

  • The SDK no longer vends any public AVAudioPCMBuffer helpers.

Documentation

  • Updated and expanded the DocC articles and the README to cover this release's features.

Migration from 1.1.1

  • Replace PersoInteractiveError.featureUnavailable(type:) in your catch / switch statements with .doesNotExist(attribute:detail:) and/or .notInOrganization(attribute:detail:).
  • invalidSessionState, sessionCapabilityNotGranted, and validationError now carry attribute / detail associated values. Pattern matches that bind the payload need updating (e.g. case .validationError(let detail)case .validationError(_, let detail)).
  • Replace playIntro(_:) with session.prompt?.introMessage + push(text:).
  • If you called any of the now-internal AVAudioPCMBuffer helpers (including AVAudioPCMBuffer(buffers:format:)), replace them with the standard AVFoundation APIs. Passing audio to the SDK does not require manual format conversion — provide any PCM buffer to push(audioData:) or a custom provider and the SDK converts it.