From fee2a9a6e63d36a17b549fe33eaa816ee9a539b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=A5=E4=BB=99?= Date: Wed, 15 Jul 2026 10:31:12 +0800 Subject: [PATCH 1/3] feat(model/cosyvoice): support cancel in finish-task --- dashscope/audio/tts_v2/speech_synthesizer.py | 39 +++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/dashscope/audio/tts_v2/speech_synthesizer.py b/dashscope/audio/tts_v2/speech_synthesizer.py index 2265cd2..33cfdac 100644 --- a/dashscope/audio/tts_v2/speech_synthesizer.py +++ b/dashscope/audio/tts_v2/speech_synthesizer.py @@ -242,7 +242,7 @@ def get_continue_request(self, text): } return json.dumps(cmd) - def get_finish_request(self): + def get_finish_request(self, directive: str = None): cmd = { HEADER: { ACTION_KEY: ActionType.FINISHED, @@ -253,6 +253,8 @@ def get_finish_request(self): "input": {}, }, } + if directive is not None: + cmd["payload"]["input"]["directive"] = directive return json.dumps(cmd) def get_flush_request(self): @@ -671,21 +673,46 @@ def async_streaming_complete(self, complete_timeout_millis=600000): ) thread.start() - def streaming_cancel(self): + def streaming_cancel(self, complete_timeout_millis=10000): """ Immediately terminate the streaming input speech synthesis task and discard any remaining audio that is not yet delivered. + + A finish-task message with payload.input.directive=cancel is sent + to notify the server to stop synthesis in advance. The server will + then respond with a task-finished message, after which the + connection is closed. + + Parameters: + ----------- + complete_timeout_millis: int + Throws TimeoutError exception if it times out waiting for the + server's task-finished message. If the timeout is not None and + greater than zero, it will wait for the corresponding number of + milliseconds; otherwise, it will wait indefinitely. """ if not self._is_started: raise InvalidTask("speech synthesizer has not been started.") if self._stopped.is_set(): return - request = self.request.get_finish_request() + request = self.request.get_finish_request(directive="cancel") self.__send_str(request) - self.ws.close() - self.start_event.set() - self.complete_event.set() + if complete_timeout_millis is not None and complete_timeout_millis > 0: + if not self.complete_event.wait( + timeout=complete_timeout_millis / 1000, + ): + logger.warning( + "speech synthesizer wait for task-finished " + "after cancel timeout %sms, force closing.", + complete_timeout_millis, + ) + else: + self.complete_event.wait() + if self._close_ws_after_use: + self.close() + self._stopped.set() + self._is_started = False # Callback for listening to messages def on_message( # pylint: disable=unused-argument,too-many-branches From 8484e4a5d11f6157cd9a0af58dd5642e6e639fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=A5=E4=BB=99?= Date: Wed, 15 Jul 2026 10:42:46 +0800 Subject: [PATCH 2/3] feat(agent/multimodal-dialog): support payload.parameters when requestToRespond --- dashscope/multimodal/multimodal_request_params.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dashscope/multimodal/multimodal_request_params.py b/dashscope/multimodal/multimodal_request_params.py index 1caf609..74c7392 100644 --- a/dashscope/multimodal/multimodal_request_params.py +++ b/dashscope/multimodal/multimodal_request_params.py @@ -308,6 +308,7 @@ def to_dict(self): class RequestToRespondParameters(DashPayloadParameters): images: list = field(default=None) # type: ignore[arg-type] biz_params: BizParams = field(default=None) + pass_through_params: dict = field(default=None) # type: ignore[arg-type] def to_dict(self): params = {} @@ -315,6 +316,8 @@ def to_dict(self): params["images"] = self.images if self.biz_params is not None: params["biz_params"] = self.biz_params.to_dict() + if self.pass_through_params is not None: + params.update(self.pass_through_params) return params From 094435daacc651b714e1e1af04529fc0cf447df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=A5=E4=BB=99?= Date: Wed, 15 Jul 2026 12:11:19 +0800 Subject: [PATCH 3/3] fix:streaming_cancel change for cosyvoice --- dashscope/audio/tts_v2/speech_synthesizer.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/dashscope/audio/tts_v2/speech_synthesizer.py b/dashscope/audio/tts_v2/speech_synthesizer.py index 33cfdac..a5f3b02 100644 --- a/dashscope/audio/tts_v2/speech_synthesizer.py +++ b/dashscope/audio/tts_v2/speech_synthesizer.py @@ -686,10 +686,11 @@ def streaming_cancel(self, complete_timeout_millis=10000): Parameters: ----------- complete_timeout_millis: int - Throws TimeoutError exception if it times out waiting for the - server's task-finished message. If the timeout is not None and - greater than zero, it will wait for the corresponding number of - milliseconds; otherwise, it will wait indefinitely. + If it times out waiting for the server's task-finished message, + the connection is force-closed and a warning is logged. If the + timeout is not None and greater than zero, it will wait for the + corresponding number of milliseconds; otherwise, it will wait + indefinitely. """ if not self._is_started: @@ -707,10 +708,13 @@ def streaming_cancel(self, complete_timeout_millis=10000): "after cancel timeout %sms, force closing.", complete_timeout_millis, ) + self.close() + elif self._close_ws_after_use: + self.close() else: self.complete_event.wait() - if self._close_ws_after_use: - self.close() + if self._close_ws_after_use: + self.close() self._stopped.set() self._is_started = False