From b2d1074e2ad13165d34ce7a948f7a9faf9f77c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=A5=E4=BB=99?= Date: Wed, 9 Sep 2026 11:17:35 +0800 Subject: [PATCH 1/2] feat(model/asr): support update input.context by continue-task --- dashscope/api_entities/websocket_request.py | 37 ++++++++++++--------- dashscope/audio/asr/recognition.py | 25 ++++++++++++-- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/dashscope/api_entities/websocket_request.py b/dashscope/api_entities/websocket_request.py index 13fc853..2358b4e 100644 --- a/dashscope/api_entities/websocket_request.py +++ b/dashscope/api_entities/websocket_request.py @@ -335,27 +335,34 @@ async def _send_finished_task(self, ws): await ws.send_str(message) async def _send_continue_task_data(self, ws): - headers = { - "task_id": self.task_headers["task_id"], - "action": "continue-task", - } + headers = {**self.task_headers, ACTION_KEY: ActionType.CONTINUE} for input_item in self.data.get_websocket_continue_data(): - if self.is_binary_input: - if len(input_item) > 0: - if isinstance(input_item, bytes): - await ws.send_bytes(input_item) + if len(input_item) > 0: + if self.is_binary_input and isinstance( + input_item, + (bytes, bytearray, memoryview), + ): + await ws.send_bytes(input_item) + logger.debug( + "Send continue task with bytes: %s", + len(input_item), + ) + elif self.is_binary_input and isinstance(input_item, dict): + binary_data = next(iter(input_item.values())) + if isinstance(binary_data, (bytes, bytearray, memoryview)): + await ws.send_bytes(binary_data) logger.debug( - "Send continue task with bytes: %s", + "Send continue task with list[byte]: %s", len(input_item), ) else: - await ws.send_bytes(list(input_item.values())[0]) - logger.debug( - "Send continue task with list[byte]: %s", - len(input_item), + message = self._build_up_message( + headers=headers, + payload=input_item, ) - else: - if len(input_item) > 0: + logger.debug("Send continue task: %s", message) + await ws.send_str(message) + else: message = self._build_up_message( headers=headers, payload=input_item, diff --git a/dashscope/audio/asr/recognition.py b/dashscope/audio/asr/recognition.py index 32f05ca..b9bf978 100644 --- a/dashscope/audio/asr/recognition.py +++ b/dashscope/audio/asr/recognition.py @@ -629,6 +629,27 @@ def send_audio_frame(self, buffer: bytes): logger.debug("send_audio_frame: %s", len(buffer)) self._stream_data.put(buffer) + def update_context(self, payload_input: dict): + """Update recognition context while the task is running. + + The context is sent through a ``continue-task`` event and takes effect + on subsequent audio frames. + + Args: + payload_input (dict): Conversation context messages. + + Raises: + InvalidParameter: Cannot update an uninitiated recognition, or the + context is None. + """ + if self._running is False: + raise InvalidParameter("Speech recognition has stopped.") + if payload_input is None: + raise InvalidParameter("Context is required.") + + logger.debug("update_context: %s", payload_input) + self._stream_data.put({"input": payload_input}) + def _tidy_kwargs(self): for k in self._kwargs.copy(): if self._kwargs[k] is None: @@ -656,7 +677,7 @@ def _input_stream_cycle(self): while not self._stream_data.empty(): frame = self._stream_data.get() - yield bytes(frame) + yield frame if isinstance(frame, dict) else bytes(frame) if self._recognition_once: self._running = False @@ -665,7 +686,7 @@ def _input_stream_cycle(self): if self._recognition_once is False: while not self._stream_data.empty(): frame = self._stream_data.get() - yield bytes(frame) + yield frame if isinstance(frame, dict) else bytes(frame) def _silence_stop_timer(self): """If audio data is not received for a long time, exit worker.""" From 76b63e3bf540240a72852ed635e21ce453437e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=A5=E4=BB=99?= Date: Wed, 9 Sep 2026 16:52:41 +0800 Subject: [PATCH 2/2] feat(model/omni):support video compactness --- dashscope/audio/qwen_omni/omni_realtime.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dashscope/audio/qwen_omni/omni_realtime.py b/dashscope/audio/qwen_omni/omni_realtime.py index 4bddc53..7b5b914 100644 --- a/dashscope/audio/qwen_omni/omni_realtime.py +++ b/dashscope/audio/qwen_omni/omni_realtime.py @@ -413,6 +413,7 @@ def update_session( transcription_params: TranscriptionParams = None, input_audio_config: AudioFormatConfig = None, output_audio_config: AudioFormatConfig = None, + input_video_representation_compactness: int = None, **kwargs, ) -> None: """ @@ -459,6 +460,11 @@ def update_session( type (pcm/wav) and sample rate (8000/16000/24000/48000), as well as free extension parameters via ``extra_params``. When provided, the request emits the ``session.audio.output.format`` structure. + input_video_representation_compactness: int + input video representation compactness. When provided, the request + emits ``session.video.input.representation_compactness``. No strict + client-side validation is performed so newly supported values can + be used without upgrading the SDK. Notes ----- @@ -509,6 +515,14 @@ def update_session( } if transcription_params is not None: self._apply_transcription_params(transcription_params) + if input_video_representation_compactness is not None: + self.config["video"] = { + "input": { + "representation_compactness": ( + input_video_representation_compactness + ), + }, + } self.config.update(kwargs) self.__send_str( json.dumps(