diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 4fcfdf7..2b6f978 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.9.0" + ".": "1.9.1" } diff --git a/.stats.yml b/.stats.yml index 29d23f7..f653725 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 10 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sambanova/sambanova-f9a2632e2ea9632e8b40258f57bfa8b529b926d72fd8b1f9550848fbb880e0de.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sambanova/sambanova-02c8f71d13f3bc185716a6e93aa9f75b1831c55aefba4d34bb1cab6060723528.yml openapi_spec_hash: 8df9e2ad31769c26c590dacf3517bc36 -config_hash: d33fc68f92caf09c6b3b40675a111114 +config_hash: 0213fb1509c3d860435ee9a49477d86f diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b6a1db..c6b44b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.9.1 (2026-06-17) + +Full Changelog: [v1.9.0...v1.9.1](https://github.com/sambanova/sambanova-python/compare/v1.9.0...v1.9.1) + +### Bug Fixes + +* **streaming:** resolve duplicate chunk emission in SSE event routing ([b031ad8](https://github.com/sambanova/sambanova-python/commit/b031ad8fefebf29b7b3b7448e8db0b40d16aa910)) + ## 1.9.0 (2026-05-26) Full Changelog: [v1.8.2...v1.9.0](https://github.com/sambanova/sambanova-python/compare/v1.8.2...v1.9.0) diff --git a/pyproject.toml b/pyproject.toml index 23fbe75..03915fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "sambanova" -version = "1.9.0" +version = "1.9.1" description = "The official Python library for the SambaNova API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/sambanova/_streaming.py b/src/sambanova/_streaming.py index 5f772ca..365c346 100644 --- a/src/sambanova/_streaming.py +++ b/src/sambanova/_streaming.py @@ -80,7 +80,67 @@ def __stream__(self) -> Iterator[_T]: response=self.response, ) - yield process_data(data=sse.json(), cast_to=cast_to, response=response) + if sse.event == "response.created": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.in_progress": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.output_item.added": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.content_part.added": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.reasoning_text.delta": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.reasoning_text.done": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.output_text.delta": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.output_text.done": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.function_call_arguments.delta": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.function_call_arguments.done": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.content_part.done": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.output_item.done": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.completed": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "message_start": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "content_block_start": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "content_block_delta": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "content_block_stop": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "message_delta": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "message_stop": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "ping": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + continue finally: # Ensure the response is closed even if the consumer doesn't read all data response.close() @@ -167,7 +227,67 @@ async def __stream__(self) -> AsyncIterator[_T]: response=self.response, ) - yield process_data(data=sse.json(), cast_to=cast_to, response=response) + if sse.event == "response.created": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.in_progress": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.output_item.added": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.content_part.added": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.reasoning_text.delta": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.reasoning_text.done": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.output_text.delta": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.output_text.done": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.function_call_arguments.delta": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.function_call_arguments.done": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.content_part.done": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.output_item.done": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "response.completed": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "message_start": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "content_block_start": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "content_block_delta": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "content_block_stop": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "message_delta": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "message_stop": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + if sse.event == "ping": + yield process_data(data=sse.json(), cast_to=cast_to, response=response) + + continue finally: # Ensure the response is closed even if the consumer doesn't read all data await response.aclose() diff --git a/src/sambanova/_version.py b/src/sambanova/_version.py index 48fad55..a352cb4 100644 --- a/src/sambanova/_version.py +++ b/src/sambanova/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "sambanova" -__version__ = "1.9.0" # x-release-please-version +__version__ = "1.9.1" # x-release-please-version