From 729fc143afe3e9110c4b36e3f146ca848dcebcbe Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 21 Jul 2026 19:28:19 -0400 Subject: [PATCH] feat: ship chats.stream_chat() with SSE support The registry spec labels the stream endpoint application/x-ndjson, which Speakeasy skips during codegen (jsonlResponses is enterprise-tier) - the method was documented but never generated. The endpoint is served by demo2's platform v2 SSE handler emitting {result: Cell} / {error: Status} envelopes. Map the operation to chats.streamChat and normalize the response to the SSE envelope contract; regenerate. stream_chat() / stream_chat_async() now return EventStream[StreamChatEvent]. The overlay normalization becomes a harmless no-op once demo2 (TextQLLabs/demo2#13014) publishes the SSE spec at the source. --- .speakeasy/gen.lock | 89 ++++-- .speakeasy/gen.yaml | 2 +- .speakeasy/out.openapi.yaml | 27 +- .../speakeasy-modifications-overlay.yaml | 53 +++- .speakeasy/workflow.lock | 10 +- README.md | 37 +++ docs/models/chatservicestreamchatrequest.md | 9 + docs/models/chatservicestreamchatresponse.md | 17 ++ docs/models/googleprotobufany.md | 9 + docs/models/googlerpcstatus.md | 10 + docs/models/streamchatevent.md | 10 + docs/models/streamchateventdata.md | 11 + ...lrpcpublicchatchatservicestreamchatbody.md | 12 + docs/sdks/chats/README.md | 46 +++ pyproject.toml | 2 +- src/textql_sdk/_version.py | 4 +- src/textql_sdk/chats.py | 268 +++++++++++++++++- src/textql_sdk/models/__init__.py | 44 +++ .../models/chatservice_streamchatop.py | 107 +++++++ src/textql_sdk/models/google_protobuf_any.py | 54 ++++ src/textql_sdk/models/google_rpc_status.py | 38 +++ ..._public_chat_chatservice_streamchatbody.py | 55 ++++ 22 files changed, 877 insertions(+), 37 deletions(-) create mode 100644 docs/models/chatservicestreamchatrequest.md create mode 100644 docs/models/chatservicestreamchatresponse.md create mode 100644 docs/models/googleprotobufany.md create mode 100644 docs/models/googlerpcstatus.md create mode 100644 docs/models/streamchatevent.md create mode 100644 docs/models/streamchateventdata.md create mode 100644 docs/models/textqlrpcpublicchatchatservicestreamchatbody.md create mode 100644 src/textql_sdk/models/chatservice_streamchatop.py create mode 100644 src/textql_sdk/models/google_protobuf_any.py create mode 100644 src/textql_sdk/models/google_rpc_status.py create mode 100644 src/textql_sdk/models/textql_rpc_public_chat_chatservice_streamchatbody.py diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index dbbc521..1eda63a 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,21 +1,22 @@ lockVersion: 2.0.0 id: 140336b3-3873-4a19-9c47-b02749d85f10 management: - docChecksum: 7af31010839ddf9f6108f7b04695952b + docChecksum: 330893ae97b9fade74fe34c6db0c6f4c docVersion: 1.0.0 speakeasyVersion: 1.790.3 generationVersion: 2.918.4 - releaseVersion: 1.0.4 - configChecksum: 5d76ed4c4784296080be6c5bf8a8ac60 + releaseVersion: 1.1.0 + configChecksum: 52d0aa28e2d264fdb134a290cffb3645 repoURL: https://github.com/TextQLLabs/textql-python-v3.git installationURL: https://github.com/TextQLLabs/textql-python-v3.git published: true persistentEdits: - generation_id: 8ca8c294-e771-475e-8278-7fd514acdf04 - pristine_commit_hash: 790c65752561275be4d2589da0459cf9ce75ee32 - pristine_tree_hash: e52aed69a55e1940a5ddc0fd44509137df3cff30 + generation_id: be1199a6-c60f-4515-a24c-060a07dbf2af + pristine_commit_hash: a6dc51433bb327989ca2088373e583ba8eb68a8d + pristine_tree_hash: c6a69173f43a157af43ebb2a97221051e55d9860 features: python: + acceptHeaders: 3.0.0 additionalDependencies: 1.1.0 additionalProperties: 1.0.2 constsAndDefaults: 1.0.7 @@ -39,6 +40,7 @@ features: responseFormat: 1.1.0 retries: 3.0.7 sdkHooks: 1.3.0 + serverEvents: 1.1.1 unions: 3.1.7 trackedFiles: .devcontainer/README.md: @@ -793,6 +795,14 @@ trackedFiles: id: dd417097cb26 last_write_checksum: sha1:e13d9118b73e3fcfc16ad72cac5ecd0f13d152a7 pristine_git_object: 224109bd7ce9c31a0e0ec9b321709da5757ff69a + docs/models/chatservicestreamchatrequest.md: + id: 8f819f8d66b6 + last_write_checksum: sha1:f31442bc43fd5948add0c11739b4afe43f6b33f8 + pristine_git_object: 3cfd9141aaa07b2ce065912b308b6c8b7937ebe0 + docs/models/chatservicestreamchatresponse.md: + id: d9142392077f + last_write_checksum: sha1:a87a221219f18a33c21339dea5c5b63422dc232c + pristine_git_object: 7e30c5d78b62ff5496174bd07b3faf328e253561 docs/models/chatservicesubmitcontextpromptchangerequest.md: id: 2a3a5b7f33fe last_write_checksum: sha1:c7343feea34a6942bff780a12e10777dc04cf6da @@ -1497,6 +1507,10 @@ trackedFiles: id: b476baec5e3a last_write_checksum: sha1:3c135b4345679dc3fd3ea3b80b5484d92bcaad3a pristine_git_object: a574c89a1f3f8568983a586c7f254aa5c76d4f3b + docs/models/googleprotobufany.md: + id: b93fd2cc6d2a + last_write_checksum: sha1:a2a79b154425b1c1a530d02f364cc266be61f0b4 + pristine_git_object: 956321fe1698918877567950cea048407164cdbc docs/models/googleprotobufempty.md: id: b10d2e6805a8 last_write_checksum: sha1:d685744083ecb837652b826e497a9f8fa0135a2c @@ -1505,6 +1519,10 @@ trackedFiles: id: 03599b62e4b7 last_write_checksum: sha1:d8134311fe7849ac42109ba5d61a45cc60211a18 pristine_git_object: cf1fe583c8823272b17efcdf20a8758a0c81bc35 + docs/models/googlerpcstatus.md: + id: 253aa396284a + last_write_checksum: sha1:ca729b600569932801046bcf502b8cdc576f61e4 + pristine_git_object: 6170e73d330a3a285aa6add4edfb42c5f0f5b456 docs/models/handoffpending.md: id: cf913e481d9d last_write_checksum: sha1:9c361575fbaa3aefcc773e290ec47abdfbed9d8d @@ -3809,6 +3827,14 @@ trackedFiles: id: 29c094b730e9 last_write_checksum: sha1:e989aa14e9475540b444b3aed48707d26d0b3d48 pristine_git_object: 46d79099bbe4be154976241aa7617356f4f65ede + docs/models/streamchatevent.md: + id: 8a1e6f6fdcef + last_write_checksum: sha1:29f35ba687ad794bf3b395019e49894124525217 + pristine_git_object: afe71e9bb0a1b675a3e754fa4ed505fa1b5f570c + docs/models/streamchateventdata.md: + id: 6686028c9e8c + last_write_checksum: sha1:3e3dc588f6a540d8ec1845e9a0d337730ef0c743 + pristine_git_object: e2c977d9608d96b0e19c84c309133038fca21db5 docs/models/streamlit.md: id: 54ac96e9d7f9 last_write_checksum: sha1:e78a84f7bc27f338eeb0b9a199d258eb8a8d610f @@ -5321,6 +5347,10 @@ trackedFiles: id: 0561d15fd709 last_write_checksum: sha1:ceef89d2e51b2349099dcc19aad791b289c5fcc1 pristine_git_object: 7959c3d2e920d20602d49285b61f7f4e5c6c3cb0 + docs/models/textqlrpcpublicchatchatservicestreamchatbody.md: + id: 66a3675e11be + last_write_checksum: sha1:b7d77f2dd6fea32c6d6234a4cc29042c1fe5f90f + pristine_git_object: bad20a9438bc7753e2453082be288652ed7eb3c4 docs/models/textqlrpcpublicchatchatsortdirection.md: id: b7219904288f last_write_checksum: sha1:f28a05f52dedc5c9b24fe9d6617ef46d3ac8e435 @@ -9507,8 +9537,8 @@ trackedFiles: pristine_git_object: e299e2f663e14f92bd1c24b4f4804de37a806968 docs/sdks/chats/README.md: id: ea139ac0a476 - last_write_checksum: sha1:803a13b302b45ea8f204165f547113a5d1db5eed - pristine_git_object: 5c923e72a812188f1b6704365a9ab46ac60c4f93 + last_write_checksum: sha1:50ad75d04d9ea530d851ffd012c1ce754f299837 + pristine_git_object: 1fd7f387741594b680408b787afcf0953e92e6f7 docs/sdks/connectors/README.md: id: 7633a87d946d last_write_checksum: sha1:4c83d0e8527b35fd8b48973a5db2e0ee25c0eb81 @@ -9599,8 +9629,8 @@ trackedFiles: pristine_git_object: 14a5ab5a0178bf5f37c25306ec11372c1dfc1f4e pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:8be6d844046a001e831785f9c222d0fcc90a002b - pristine_git_object: d14db9dfba1cc886b31e3eb325484acb799de3b7 + last_write_checksum: sha1:6ee4675cf4541d382c0f6e0158b294f4ec05f5ea + pristine_git_object: 889b7bb92274bb0ceb5c0e4457241a0c02f61f20 scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:d5a0f1ce09f7b890340fdb6f26345fce7dc9a70d @@ -9627,8 +9657,8 @@ trackedFiles: pristine_git_object: a9e63d694ae036ae9a43efc262dd124a2e1062e7 src/textql_sdk/_version.py: id: "226928447e58" - last_write_checksum: sha1:953f7dbefde624a88e7fbce1c3a22e09a0147f04 - pristine_git_object: 4f3a413671111209dcba43a2a812a1d5eba0e517 + last_write_checksum: sha1:6786cdd02af62c239e8c8091ae36ae70bcac62da + pristine_git_object: a53939b1aa7dcbfe900bc2ebbded042e18a2b5ad src/textql_sdk/agents.py: id: 4ff492529583 last_write_checksum: sha1:61b0b5714598af35b733276cfd32fa30225d2229 @@ -9651,8 +9681,8 @@ trackedFiles: pristine_git_object: 92ed65818f40afafbfb5a9dc6f2e0fef9e0228b4 src/textql_sdk/chats.py: id: 592608eb13b1 - last_write_checksum: sha1:a1e0b2369ef30e60c651c77df83c738d9f5c5778 - pristine_git_object: 3457bc27aaf200decc48628e76f244b99cac730c + last_write_checksum: sha1:4354469381b04fdcc38db4224f6cbe442e7a8fa5 + pristine_git_object: 946030aa92cf983d45759dbec01f59c84c8e672a src/textql_sdk/connectors.py: id: 44f63753a16d last_write_checksum: sha1:93920758e4fbfa92b0ec51fb0a5f3a80792fdc2b @@ -9699,8 +9729,8 @@ trackedFiles: pristine_git_object: f5227a747725a68f1c9b6ebffe42ac0d2436f77f src/textql_sdk/models/__init__.py: id: c8cef98ef3e7 - last_write_checksum: sha1:3f9052f05e4054de4d0ba4cdd42bd0b4f0ebd76e - pristine_git_object: 30e628404956b04a768ef847a77d25aca4f013fe + last_write_checksum: sha1:3a99553381e158ad6aa1d88a5c254d343a614251 + pristine_git_object: 7f4a27f9137b5b64d351d45da2737b7d9d1b0f3e src/textql_sdk/models/agentservice_createagentop.py: id: c31d4c4b52ae last_write_checksum: sha1:eb9ab95a772110d0f587963a73ff3ab4a6f11859 @@ -10013,6 +10043,10 @@ trackedFiles: id: e4a2de997033 last_write_checksum: sha1:1ed30d13acb33c72f9afe15625d60f1ca76fac0e pristine_git_object: 68b3c51a7a8a906af17ee7a7864e3acb527823ba + src/textql_sdk/models/chatservice_streamchatop.py: + id: 65593d3627ff + last_write_checksum: sha1:e2c811ce3e1d75c245a0b4a220c6f6616cbdd169 + pristine_git_object: 148177c2ee2fef6779af8195634cfaf145d0e8a2 src/textql_sdk/models/chatservice_submitcontextpromptchangeop.py: id: 99d899c5a108 last_write_checksum: sha1:9c17b344c58a79c96366b5b65735911132ecbf02 @@ -10257,6 +10291,10 @@ trackedFiles: id: 775d31d0d703 last_write_checksum: sha1:08ec43f9e99c865832bd3829d7c6fd8de8331095 pristine_git_object: 46b9ffc2dc5adbd768313e0c6f2f5150277faf09 + src/textql_sdk/models/google_protobuf_any.py: + id: 350d2deee9ed + last_write_checksum: sha1:b68abc158d904789a23476eaea50bf7cf78155f9 + pristine_git_object: 93eee506597f90c0275cbdea9d0b70cdfbd5ea83 src/textql_sdk/models/google_protobuf_empty.py: id: a0e1ed8a0e04 last_write_checksum: sha1:a86402c54753d1e68cf956f4e4ec0376f0a73fdc @@ -10265,6 +10303,10 @@ trackedFiles: id: ff6b0abb72e9 last_write_checksum: sha1:271f0309e11d36e7b6c7930dd27e38fcac75c781 pristine_git_object: 0fa0dfbb8ebeede25529568b8d9367bbc983c236 + src/textql_sdk/models/google_rpc_status.py: + id: 47f71d0bbe34 + last_write_checksum: sha1:3687002a728fb52b39de10447d5f68f141dc11ba + pristine_git_object: 43708b10ad231f118e68f51ddc7957a58dee4bd0 src/textql_sdk/models/mcpservice_clearoauthtokenop.py: id: f07243fa2a6a last_write_checksum: sha1:924fb1807f8533cfc4a9279fb13137f11f0b0187 @@ -12301,6 +12343,10 @@ trackedFiles: id: 09b334ca10c6 last_write_checksum: sha1:47410826f563a307f405ad82a6df9f9836ff22c1 pristine_git_object: 3ce75ccf5609bb136f4c388f40915115ff887f70 + src/textql_sdk/models/textql_rpc_public_chat_chatservice_streamchatbody.py: + id: a471eae92c27 + last_write_checksum: sha1:b1f986b773a7060623132e81ebf5678af90ac5dc + pristine_git_object: 87b6cbb88db7fa50eaa64646b72576601af834af src/textql_sdk/models/textql_rpc_public_chat_chatsortdirection.py: id: 1c4af1bdb02b last_write_checksum: sha1:294ca4a6df3de552868695149410952341eed0d1 @@ -26970,5 +27016,14 @@ examples: application/json: {} default: application/json: {"code": "not_found"} + ChatService_StreamChat: + speakeasy-default-chat-service-stream-chat: + parameters: + path: + chat_id: "" + requestBody: + application/json: {} + responses: + default: + application/json: {} examplesVersion: 1.0.2 -releaseNotes: "## Python SDK Changes:\n* `textql.observability_service.observability_service_get_member_signal_trend()`: **Added**\n* `textql.chats.get_all()`: \n * `request.thread_warning_types[]` **Changed**\n* `textql.observability.get_billing_stats()`: `response.member_stats[]` **Changed**\n* `textql.observability.get_observability_stats()`: `response` **Changed**\n* `textql.observability.get_thread_warnings()`: `response.warnings_by_chat.Map.warnings[].warning_type` **Changed**\n" diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 879c3c4..656784f 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -34,7 +34,7 @@ generation: generateNewTests: true skipResponseBodyAssertions: false python: - version: 1.0.4 + version: 1.1.0 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index d4c25a9..d851dbf 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -14791,21 +14791,31 @@ paths: "200": description: A successful response.(streaming responses) content: - application/x-ndjson: + text/event-stream: schema: + title: StreamChatEvent type: object + required: + - data properties: - result: - $ref: '#/components/schemas/textql.rpc.public.chat.Cell' - error: - $ref: '#/components/schemas/google.rpc.Status' - title: Stream result of textql.rpc.public.chat.Cell + data: + title: StreamChatEventData + description: >- + One stream envelope: `result` carries the next cell, `error` reports a failure that ended the stream. + type: object + properties: + result: + $ref: "#/components/schemas/textql.rpc.public.chat.Cell" + error: + $ref: "#/components/schemas/google.rpc.Status" default: description: An unexpected error response. content: - application/x-ndjson: + application/json: schema: - $ref: '#/components/schemas/google.rpc.Status' + $ref: "#/components/schemas/google.rpc.Status" + x-speakeasy-group: chats + x-speakeasy-name-override: streamChat components: schemas: connect-protocol-version: @@ -14815,6 +14825,7 @@ components: - 1 description: Define the version of the Connect protocol const: 1 + default: 1 connect-timeout-header: type: number title: Connect-Timeout-Ms diff --git a/.speakeasy/speakeasy-modifications-overlay.yaml b/.speakeasy/speakeasy-modifications-overlay.yaml index 00623c3..fa22527 100644 --- a/.speakeasy/speakeasy-modifications-overlay.yaml +++ b/.speakeasy/speakeasy-modifications-overlay.yaml @@ -8,8 +8,6 @@ info: before: "" type: speakeasy-modifications actions: - - target: $["paths"]["/textql.rpc.public.chat.ChatService/StreamChat"] - remove: true - target: $["paths"]["/textql.rpc.public.chat.ChatService/WatchChat"] remove: true - target: $["paths"]["/textql.rpc.public.agent.AgentService/StreamAgentStatus"] @@ -715,6 +713,16 @@ actions: created_at: 1784134047110 reviewed_at: 1784134060142 type: method-name + - target: $["paths"]["/v2/chats/{chat_id}/cells/stream"]["post"] + update: + x-speakeasy-group: chats + x-speakeasy-name-override: streamChat + x-speakeasy-metadata: + after: sdk.chats.streamChat() + before: sdk.ChatService.ChatService_StreamChat() + created_at: 1784134047110 + reviewed_at: 1784134060142 + type: method-name - target: $["paths"]["/textql.rpc.public.chat.ChatService/GetChatHistory"]["post"] update: x-speakeasy-group: chats @@ -4025,3 +4033,44 @@ actions: created_at: 1784134047111 reviewed_at: 1784134060143 type: method-name + # StreamChat: the endpoint is served by a platform v2 handler + # (demo2 compute/pkg/platform/v2/chat.go StreamChatCells) that emits + # Server-Sent Events of {result: Cell} / {error: Status} envelopes. Older + # registry snapshots label the response application/x-ndjson (a shape + # Speakeasy skips during codegen); normalize whatever is there to the SSE + # contract. Redundant (but harmless) once demo2 publishes the SSE spec. + - target: $["paths"]["/v2/chats/{chat_id}/cells/stream"]["post"]["responses"]["200"]["content"]["application/x-ndjson"] + remove: true + - target: $["paths"]["/v2/chats/{chat_id}/cells/stream"]["post"]["responses"]["200"]["content"]["application/jsonl"] + remove: true + - target: $["paths"]["/v2/chats/{chat_id}/cells/stream"]["post"]["responses"]["200"]["content"]["text/event-stream"] + remove: true + - target: $["paths"]["/v2/chats/{chat_id}/cells/stream"]["post"]["responses"]["200"]["content"] + update: + text/event-stream: + schema: + title: StreamChatEvent + type: object + required: + - data + properties: + data: + title: StreamChatEventData + description: >- + One stream envelope: `result` carries the next cell, + `error` reports a failure that ended the stream. + type: object + properties: + result: + $ref: "#/components/schemas/textql.rpc.public.chat.Cell" + error: + $ref: "#/components/schemas/google.rpc.Status" + - target: $["paths"]["/v2/chats/{chat_id}/cells/stream"]["post"]["responses"]["default"]["content"]["application/x-ndjson"] + remove: true + - target: $["paths"]["/v2/chats/{chat_id}/cells/stream"]["post"]["responses"]["default"]["content"]["text/event-stream"] + remove: true + - target: $["paths"]["/v2/chats/{chat_id}/cells/stream"]["post"]["responses"]["default"]["content"] + update: + application/json: + schema: + $ref: "#/components/schemas/google.rpc.Status" diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 8b97a80..1514268 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -2,8 +2,8 @@ speakeasyVersion: 1.790.3 sources: TextQL API: sourceNamespace: textql-api - sourceRevisionDigest: sha256:4670139a5c81225de992f691ed6fbf6b6b9c8aa247bf10a814122d31ee4aa7f9 - sourceBlobDigest: sha256:36f2082198add8377892deccf7b11f316071b020fb93a7d67238d343b2ba09f8 + sourceRevisionDigest: sha256:990df81d252b03a82295de9e317cefc430b33993d67c1568439a4b3ae874c2c6 + sourceBlobDigest: sha256:b2941b9d6b0d93879ca94eeb75d3212c686a531fbe33bbebcd0fb9afa52dc7e8 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: textql: source: TextQL API sourceNamespace: textql-api - sourceRevisionDigest: sha256:4670139a5c81225de992f691ed6fbf6b6b9c8aa247bf10a814122d31ee4aa7f9 - sourceBlobDigest: sha256:36f2082198add8377892deccf7b11f316071b020fb93a7d67238d343b2ba09f8 + sourceRevisionDigest: sha256:990df81d252b03a82295de9e317cefc430b33993d67c1568439a4b3ae874c2c6 + sourceBlobDigest: sha256:b2941b9d6b0d93879ca94eeb75d3212c686a531fbe33bbebcd0fb9afa52dc7e8 codeSamplesNamespace: textql-api-python-code-samples - codeSamplesRevisionDigest: sha256:a4cb1fefd23216743c990187aa31125abd71546077d42c122db5b566b4c67967 + codeSamplesRevisionDigest: sha256:9dc66a65eb38313adc312eba3f33c83724e27af3c132485821a4d8ef11584113 workflow: workflowVersion: 1.0.0 speakeasyVersion: latest diff --git a/README.md b/README.md index ed3e455..86f4ee6 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ endpoints are excluded via google.api.visibility / file_visibility. * [SDK Example Usage](#sdk-example-usage) * [Authentication](#authentication) * [Available Resources and Operations](#available-resources-and-operations) + * [Server-sent event streaming](#server-sent-event-streaming) * [Retries](#retries) * [Error Handling](#error-handling) * [Server Selection](#server-selection) @@ -284,6 +285,7 @@ with Textql( * [submit_questions](docs/sdks/chats/README.md#submit_questions) - Resolve a halted questions cell. Submit hands the answers to the agent and resumes it; Dismiss hands over only the answered count and does NOT resume (the user's next message becomes the dismissal reason). * [unbookmark](docs/sdks/chats/README.md#unbookmark) - UnbookmarkChat * [update](docs/sdks/chats/README.md#update) - UpdateChat +* [stream_chat](docs/sdks/chats/README.md#stream_chat) ### [Connectors](docs/sdks/connectors/README.md) @@ -666,6 +668,41 @@ with Textql( + +## Server-sent event streaming + +[Server-sent events][mdn-sse] are used to stream content from certain +operations. These operations will expose the stream as [Generator][generator] that +can be consumed using a simple `for` loop. The loop will +terminate when the server no longer has any events to send and closes the +underlying connection. + +The stream is also a [Context Manager][context-manager] and can be used with the `with` statement and will close the +underlying connection when the context is exited. + +```python +import os +from textql_sdk import Textql + + +with Textql( + api_key=os.getenv("TEXTQL_API_KEY", ""), +) as textql: + + res = textql.chats.stream_chat(chat_id="") + + with res as event_stream: + for event in event_stream: + # handle event + print(event, flush=True) + +``` + +[mdn-sse]: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events +[generator]: https://book.pythontips.com/en/latest/generators.html +[context-manager]: https://book.pythontips.com/en/latest/context_managers.html + + ## Retries diff --git a/docs/models/chatservicestreamchatrequest.md b/docs/models/chatservicestreamchatrequest.md new file mode 100644 index 0000000..3cfd914 --- /dev/null +++ b/docs/models/chatservicestreamchatrequest.md @@ -0,0 +1,9 @@ +# ChatServiceStreamChatRequest + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| `chat_id` | *str* | :heavy_check_mark: | N/A | +| `body` | [models.TextqlRPCPublicChatChatServiceStreamChatBody](../models/textqlrpcpublicchatchatservicestreamchatbody.md) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/chatservicestreamchatresponse.md b/docs/models/chatservicestreamchatresponse.md new file mode 100644 index 0000000..7e30c5d --- /dev/null +++ b/docs/models/chatservicestreamchatresponse.md @@ -0,0 +1,17 @@ +# ChatServiceStreamChatResponse + + +## Supported Types + +### `Union[eventstreaming.EventStream[models.StreamChatEvent], eventstreaming.EventStreamAsync[models.StreamChatEvent]]` + +```python +value: Union[eventstreaming.EventStream[models.StreamChatEvent], eventstreaming.EventStreamAsync[models.StreamChatEvent]] = /* values here */ +``` + +### `models.GoogleRPCStatus` + +```python +value: models.GoogleRPCStatus = /* values here */ +``` + diff --git a/docs/models/googleprotobufany.md b/docs/models/googleprotobufany.md new file mode 100644 index 0000000..956321f --- /dev/null +++ b/docs/models/googleprotobufany.md @@ -0,0 +1,9 @@ +# GoogleProtobufAny + + +## Fields + +| Field | Type | Required | Description | +| -------------------- | -------------------- | -------------------- | -------------------- | +| `at_type` | *Optional[str]* | :heavy_minus_sign: | N/A | +| `__pydantic_extra__` | Dict[str, *Any*] | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/googlerpcstatus.md b/docs/models/googlerpcstatus.md new file mode 100644 index 0000000..6170e73 --- /dev/null +++ b/docs/models/googlerpcstatus.md @@ -0,0 +1,10 @@ +# GoogleRPCStatus + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- | +| `code` | *Optional[int]* | :heavy_minus_sign: | N/A | +| `message` | *Optional[str]* | :heavy_minus_sign: | N/A | +| `details` | List[[models.GoogleProtobufAny](../models/googleprotobufany.md)] | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/streamchatevent.md b/docs/models/streamchatevent.md new file mode 100644 index 0000000..afe71e9 --- /dev/null +++ b/docs/models/streamchatevent.md @@ -0,0 +1,10 @@ +# StreamChatEvent + +A successful response.(streaming responses) + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `data` | [models.StreamChatEventData](../models/streamchateventdata.md) | :heavy_check_mark: | One stream envelope: `result` carries the next cell, `error` reports a failure that ended the stream. | \ No newline at end of file diff --git a/docs/models/streamchateventdata.md b/docs/models/streamchateventdata.md new file mode 100644 index 0000000..e2c977d --- /dev/null +++ b/docs/models/streamchateventdata.md @@ -0,0 +1,11 @@ +# StreamChatEventData + +One stream envelope: `result` carries the next cell, `error` reports a failure that ended the stream. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| `result` | [Optional[models.TextqlRPCPublicChatCell]](../models/textqlrpcpublicchatcell.md) | :heavy_minus_sign: | N/A | +| `error` | [Optional[models.GoogleRPCStatus]](../models/googlerpcstatus.md) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/textqlrpcpublicchatchatservicestreamchatbody.md b/docs/models/textqlrpcpublicchatchatservicestreamchatbody.md new file mode 100644 index 0000000..bad20a9 --- /dev/null +++ b/docs/models/textqlrpcpublicchatchatservicestreamchatbody.md @@ -0,0 +1,12 @@ +# TextqlRPCPublicChatChatServiceStreamChatBody + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| `latest_complete_cell_id` | *Optional[str]* | :heavy_minus_sign: | N/A | +| `research` | *Optional[bool]* | :heavy_minus_sign: | N/A | +| `model` | [Optional[models.TextqlRPCPublicChatLlmModel]](../models/textqlrpcpublicchatllmmodel.md) | :heavy_minus_sign: | N/A | +| `fast_mode` | *Optional[bool]* | :heavy_minus_sign: | N/A | +| `max_thinking` | *Optional[bool]* | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/sdks/chats/README.md b/docs/sdks/chats/README.md index 5c923e7..1fd7f38 100644 --- a/docs/sdks/chats/README.md +++ b/docs/sdks/chats/README.md @@ -42,6 +42,7 @@ * [submit_questions](#submit_questions) - Resolve a halted questions cell. Submit hands the answers to the agent and resumes it; Dismiss hands over only the answered count and does NOT resume (the user's next message becomes the dismissal reason). * [unbookmark](#unbookmark) - UnbookmarkChat * [update](#update) - UpdateChat +* [stream_chat](#stream_chat) ## approve_context_prompt_change @@ -1674,6 +1675,51 @@ with Textql( ### Errors +| Error Type | Status Code | Content Type | +| ------------------------- | ------------------------- | ------------------------- | +| errors.TextqlDefaultError | 4XX, 5XX | \*/\* | + +## stream_chat + +### Example Usage + + +```python +import os +from textql_sdk import Textql + + +with Textql( + api_key=os.getenv("TEXTQL_API_KEY", ""), +) as textql: + + res = textql.chats.stream_chat(chat_id="") + + with res as event_stream: + for event in event_stream: + # handle event + print(event, flush=True) + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | +| `chat_id` | *str* | :heavy_check_mark: | N/A | +| `latest_complete_cell_id` | *Optional[str]* | :heavy_minus_sign: | N/A | +| `research` | *Optional[bool]* | :heavy_minus_sign: | N/A | +| `model` | [Optional[models.TextqlRPCPublicChatLlmModel]](../../models/textqlrpcpublicchatllmmodel.md) | :heavy_minus_sign: | N/A | +| `fast_mode` | *Optional[bool]* | :heavy_minus_sign: | N/A | +| `max_thinking` | *Optional[bool]* | :heavy_minus_sign: | N/A | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + +### Response + +**[models.ChatServiceStreamChatResponse](../../models/chatservicestreamchatresponse.md)** + +### Errors + | Error Type | Status Code | Content Type | | ------------------------- | ------------------------- | ------------------------- | | errors.TextqlDefaultError | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index d14db9d..889b7bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "textql-sdk" -version = "1.0.4" +version = "1.1.0" description = "Python Client SDK Generated by Speakeasy." authors = [{ name = "Speakeasy" },] readme = "README-PYPI.md" diff --git a/src/textql_sdk/_version.py b/src/textql_sdk/_version.py index 4f3a413..a53939b 100644 --- a/src/textql_sdk/_version.py +++ b/src/textql_sdk/_version.py @@ -3,10 +3,10 @@ import importlib.metadata __title__: str = "textql-sdk" -__version__: str = "1.0.4" +__version__: str = "1.1.0" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.918.4" -__user_agent__: str = "speakeasy-sdk/python 1.0.4 2.918.4 1.0.0 textql-sdk" +__user_agent__: str = "speakeasy-sdk/python 1.1.0 2.918.4 1.0.0 textql-sdk" try: if __package__ is not None: diff --git a/src/textql_sdk/chats.py b/src/textql_sdk/chats.py index 3457bc2..946030a 100644 --- a/src/textql_sdk/chats.py +++ b/src/textql_sdk/chats.py @@ -2,14 +2,20 @@ from .basesdk import BaseSDK from datetime import datetime +from enum import Enum from textql_sdk import errors, models, utils from textql_sdk._hooks import HookContext from textql_sdk.types import OptionalNullable, UNSET -from textql_sdk.utils import get_security_from_env +from textql_sdk.utils import eventstreaming, get_security_from_env from textql_sdk.utils.unmarshal_json_response import unmarshal_json_response from typing import Iterable, List, Mapping, Optional, Union +class StreamChatAcceptEnum(str, Enum): + APPLICATION_JSON = "application/json" + TEXT_EVENT_STREAM = "text/event-stream" + + class Chats(BaseSDK): def approve_context_prompt_change( self, @@ -8798,3 +8804,263 @@ async def update_async( return unmarshal_json_response(models.ConnectError, http_res) raise errors.TextqlDefaultError("Unexpected response received", http_res) + + def stream_chat( + self, + *, + chat_id: str, + latest_complete_cell_id: Optional[str] = None, + research: Optional[bool] = None, + model: Optional[models.TextqlRPCPublicChatLlmModel] = None, + fast_mode: Optional[bool] = None, + max_thinking: Optional[bool] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + accept_header_override: Optional[StreamChatAcceptEnum] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> models.ChatServiceStreamChatResponse: + r""" + :param chat_id: + :param latest_complete_cell_id: + :param research: + :param model: + :param fast_mode: + :param max_thinking: + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param accept_header_override: Override the default accept header for this method + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = models.ChatServiceStreamChatRequest( + chat_id=chat_id, + body=models.TextqlRPCPublicChatChatServiceStreamChatBody( + latest_complete_cell_id=latest_complete_cell_id, + research=research, + model=model, + fast_mode=fast_mode, + max_thinking=max_thinking, + ), + ) + + req = self._build_request( + method="POST", + path="/v2/chats/{chat_id}/cells/stream", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value=accept_header_override.value + if accept_header_override is not None + else "application/json;q=1, text/event-stream;q=0", + http_headers=http_headers, + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body( + request.body, + False, + False, + "json", + models.TextqlRPCPublicChatChatServiceStreamChatBody, + ), + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = self.do_request( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="ChatService_StreamChat", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, models.Security + ), + tags=["ChatService"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + stream=True, + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "text/event-stream"): + return eventstreaming.EventStream( + http_res, + lambda raw: unmarshal_json_response( + models.StreamChatEvent, http_res, raw + ), + client_ref=self, + ) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.TextqlDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.TextqlDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "default", "application/json"): + http_res_text = utils.stream_to_text(http_res) + return unmarshal_json_response( + models.GoogleRPCStatus, http_res, http_res_text + ) + + http_res_text = utils.stream_to_text(http_res) + raise errors.TextqlDefaultError( + "Unexpected response received", http_res, http_res_text + ) + + async def stream_chat_async( + self, + *, + chat_id: str, + latest_complete_cell_id: Optional[str] = None, + research: Optional[bool] = None, + model: Optional[models.TextqlRPCPublicChatLlmModel] = None, + fast_mode: Optional[bool] = None, + max_thinking: Optional[bool] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + accept_header_override: Optional[StreamChatAcceptEnum] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> models.ChatServiceStreamChatResponse: + r""" + :param chat_id: + :param latest_complete_cell_id: + :param research: + :param model: + :param fast_mode: + :param max_thinking: + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param accept_header_override: Override the default accept header for this method + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = models.ChatServiceStreamChatRequest( + chat_id=chat_id, + body=models.TextqlRPCPublicChatChatServiceStreamChatBody( + latest_complete_cell_id=latest_complete_cell_id, + research=research, + model=model, + fast_mode=fast_mode, + max_thinking=max_thinking, + ), + ) + + req = self._build_request_async( + method="POST", + path="/v2/chats/{chat_id}/cells/stream", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value=accept_header_override.value + if accept_header_override is not None + else "application/json;q=1, text/event-stream;q=0", + http_headers=http_headers, + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body( + request.body, + False, + False, + "json", + models.TextqlRPCPublicChatChatServiceStreamChatBody, + ), + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="ChatService_StreamChat", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, models.Security + ), + tags=["ChatService"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + stream=True, + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "text/event-stream"): + return eventstreaming.EventStreamAsync( + http_res, + lambda raw: unmarshal_json_response( + models.StreamChatEvent, http_res, raw + ), + client_ref=self, + ) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.TextqlDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.TextqlDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "default", "application/json"): + http_res_text = await utils.stream_to_text_async(http_res) + return unmarshal_json_response( + models.GoogleRPCStatus, http_res, http_res_text + ) + + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.TextqlDefaultError( + "Unexpected response received", http_res, http_res_text + ) diff --git a/src/textql_sdk/models/__init__.py b/src/textql_sdk/models/__init__.py index 30e6284..7f4a27f 100644 --- a/src/textql_sdk/models/__init__.py +++ b/src/textql_sdk/models/__init__.py @@ -497,6 +497,16 @@ ChatServiceSendMessageResponse, ChatServiceSendMessageResponseTypedDict, ) + from .chatservice_streamchatop import ( + ChatServiceStreamChatRequest, + ChatServiceStreamChatRequestTypedDict, + ChatServiceStreamChatResponse, + ChatServiceStreamChatResponseTypedDict, + StreamChatEvent, + StreamChatEventData, + StreamChatEventDataTypedDict, + StreamChatEventTypedDict, + ) from .chatservice_submitcontextpromptchangeop import ( ChatServiceSubmitContextPromptChangeRequest, ChatServiceSubmitContextPromptChangeRequestTypedDict, @@ -858,8 +868,10 @@ DatasetServiceUpdateDatasetResponse, DatasetServiceUpdateDatasetResponseTypedDict, ) + from .google_protobuf_any import GoogleProtobufAny, GoogleProtobufAnyTypedDict from .google_protobuf_empty import GoogleProtobufEmpty, GoogleProtobufEmptyTypedDict from .google_protobuf_value import GoogleProtobufValue, GoogleProtobufValueTypedDict + from .google_rpc_status import GoogleRPCStatus, GoogleRPCStatusTypedDict from .mcpservice_clearoauthtokenop import ( MCPServiceClearOAuthTokenRequest, MCPServiceClearOAuthTokenRequestTypedDict, @@ -3662,6 +3674,10 @@ TextqlRPCPublicChatChatMessage, TextqlRPCPublicChatChatMessageTypedDict, ) + from .textql_rpc_public_chat_chatservice_streamchatbody import ( + TextqlRPCPublicChatChatServiceStreamChatBody, + TextqlRPCPublicChatChatServiceStreamChatBodyTypedDict, + ) from .textql_rpc_public_chat_chatsortdirection import ( TextqlRPCPublicChatChatSortDirection, ) @@ -8200,6 +8216,10 @@ "ChatServiceSendMessageRequestTypedDict", "ChatServiceSendMessageResponse", "ChatServiceSendMessageResponseTypedDict", + "ChatServiceStreamChatRequest", + "ChatServiceStreamChatRequestTypedDict", + "ChatServiceStreamChatResponse", + "ChatServiceStreamChatResponseTypedDict", "ChatServiceSubmitContextPromptChangeRequest", "ChatServiceSubmitContextPromptChangeRequestTypedDict", "ChatServiceSubmitContextPromptChangeResponse", @@ -8550,10 +8570,14 @@ "GoogleDriveTypedDict", "GoogleMetadata", "GoogleMetadataTypedDict", + "GoogleProtobufAny", + "GoogleProtobufAnyTypedDict", "GoogleProtobufEmpty", "GoogleProtobufEmptyTypedDict", "GoogleProtobufValue", "GoogleProtobufValueTypedDict", + "GoogleRPCStatus", + "GoogleRPCStatusTypedDict", "GoogleTypedDict", "HTTPConfig", "HTTPConfigTypedDict", @@ -9707,6 +9731,10 @@ "StartedAtMsTypedDict", "StatusCell", "StatusCellTypedDict", + "StreamChatEvent", + "StreamChatEventData", + "StreamChatEventDataTypedDict", + "StreamChatEventTypedDict", "Streamlit", "StreamlitCell", "StreamlitCellTypedDict", @@ -10439,6 +10467,8 @@ "TextqlRPCPublicChatChatExecutionTimingWarehouseMsTypedDict", "TextqlRPCPublicChatChatMessage", "TextqlRPCPublicChatChatMessageTypedDict", + "TextqlRPCPublicChatChatServiceStreamChatBody", + "TextqlRPCPublicChatChatServiceStreamChatBodyTypedDict", "TextqlRPCPublicChatChatSortDirection", "TextqlRPCPublicChatChatSortField", "TextqlRPCPublicChatChatSource", @@ -12790,6 +12820,14 @@ "ChatServiceSendMessageRequestTypedDict": ".chatservice_sendmessageop", "ChatServiceSendMessageResponse": ".chatservice_sendmessageop", "ChatServiceSendMessageResponseTypedDict": ".chatservice_sendmessageop", + "ChatServiceStreamChatRequest": ".chatservice_streamchatop", + "ChatServiceStreamChatRequestTypedDict": ".chatservice_streamchatop", + "ChatServiceStreamChatResponse": ".chatservice_streamchatop", + "ChatServiceStreamChatResponseTypedDict": ".chatservice_streamchatop", + "StreamChatEvent": ".chatservice_streamchatop", + "StreamChatEventData": ".chatservice_streamchatop", + "StreamChatEventDataTypedDict": ".chatservice_streamchatop", + "StreamChatEventTypedDict": ".chatservice_streamchatop", "ChatServiceSubmitContextPromptChangeRequest": ".chatservice_submitcontextpromptchangeop", "ChatServiceSubmitContextPromptChangeRequestTypedDict": ".chatservice_submitcontextpromptchangeop", "ChatServiceSubmitContextPromptChangeResponse": ".chatservice_submitcontextpromptchangeop", @@ -13033,10 +13071,14 @@ "DatasetServiceUpdateDatasetRequestTypedDict": ".datasetservice_updatedatasetop", "DatasetServiceUpdateDatasetResponse": ".datasetservice_updatedatasetop", "DatasetServiceUpdateDatasetResponseTypedDict": ".datasetservice_updatedatasetop", + "GoogleProtobufAny": ".google_protobuf_any", + "GoogleProtobufAnyTypedDict": ".google_protobuf_any", "GoogleProtobufEmpty": ".google_protobuf_empty", "GoogleProtobufEmptyTypedDict": ".google_protobuf_empty", "GoogleProtobufValue": ".google_protobuf_value", "GoogleProtobufValueTypedDict": ".google_protobuf_value", + "GoogleRPCStatus": ".google_rpc_status", + "GoogleRPCStatusTypedDict": ".google_rpc_status", "MCPServiceClearOAuthTokenRequest": ".mcpservice_clearoauthtokenop", "MCPServiceClearOAuthTokenRequestTypedDict": ".mcpservice_clearoauthtokenop", "MCPServiceClearOAuthTokenResponse": ".mcpservice_clearoauthtokenop", @@ -14836,6 +14878,8 @@ "TextqlRPCPublicChatChatExecutionTimingWarehouseMsTypedDict": ".textql_rpc_public_chat_chatexecutiontiming", "TextqlRPCPublicChatChatMessage": ".textql_rpc_public_chat_chatmessage", "TextqlRPCPublicChatChatMessageTypedDict": ".textql_rpc_public_chat_chatmessage", + "TextqlRPCPublicChatChatServiceStreamChatBody": ".textql_rpc_public_chat_chatservice_streamchatbody", + "TextqlRPCPublicChatChatServiceStreamChatBodyTypedDict": ".textql_rpc_public_chat_chatservice_streamchatbody", "TextqlRPCPublicChatChatSortDirection": ".textql_rpc_public_chat_chatsortdirection", "TextqlRPCPublicChatChatSortField": ".textql_rpc_public_chat_chatsortfield", "TextqlRPCPublicChatChatSource": ".textql_rpc_public_chat_chatsource", diff --git a/src/textql_sdk/models/chatservice_streamchatop.py b/src/textql_sdk/models/chatservice_streamchatop.py new file mode 100644 index 0000000..148177c --- /dev/null +++ b/src/textql_sdk/models/chatservice_streamchatop.py @@ -0,0 +1,107 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .google_rpc_status import GoogleRPCStatus, GoogleRPCStatusTypedDict +from .textql_rpc_public_chat_cell import ( + TextqlRPCPublicChatCell, + TextqlRPCPublicChatCellTypedDict, +) +from .textql_rpc_public_chat_chatservice_streamchatbody import ( + TextqlRPCPublicChatChatServiceStreamChatBody, + TextqlRPCPublicChatChatServiceStreamChatBodyTypedDict, +) +from pydantic import model_serializer +from textql_sdk.types import BaseModel, UNSET_SENTINEL +from textql_sdk.utils import ( + FieldMetadata, + PathParamMetadata, + RequestMetadata, + eventstreaming, +) +from typing import Optional, Union +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict + + +class ChatServiceStreamChatRequestTypedDict(TypedDict): + chat_id: str + body: TextqlRPCPublicChatChatServiceStreamChatBodyTypedDict + + +class ChatServiceStreamChatRequest(BaseModel): + chat_id: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + + body: Annotated[ + TextqlRPCPublicChatChatServiceStreamChatBody, + FieldMetadata(request=RequestMetadata(media_type="application/json")), + ] + + +class StreamChatEventDataTypedDict(TypedDict): + r"""One stream envelope: `result` carries the next cell, `error` reports a failure that ended the stream.""" + + result: NotRequired[TextqlRPCPublicChatCellTypedDict] + error: NotRequired[GoogleRPCStatusTypedDict] + + +class StreamChatEventData(BaseModel): + r"""One stream envelope: `result` carries the next cell, `error` reports a failure that ended the stream.""" + + result: Optional[TextqlRPCPublicChatCell] = None + + error: Optional[GoogleRPCStatus] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["result", "error"]) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class StreamChatEventTypedDict(TypedDict): + r"""A successful response.(streaming responses)""" + + data: StreamChatEventDataTypedDict + r"""One stream envelope: `result` carries the next cell, `error` reports a failure that ended the stream.""" + + +class StreamChatEvent(BaseModel): + r"""A successful response.(streaming responses)""" + + data: StreamChatEventData + r"""One stream envelope: `result` carries the next cell, `error` reports a failure that ended the stream.""" + + +ChatServiceStreamChatResponseTypedDict = TypeAliasType( + "ChatServiceStreamChatResponseTypedDict", + Union[ + GoogleRPCStatusTypedDict, + Union[ + eventstreaming.EventStream[StreamChatEventTypedDict], + eventstreaming.EventStreamAsync[StreamChatEventTypedDict], + ], + ], +) + + +ChatServiceStreamChatResponse = TypeAliasType( + "ChatServiceStreamChatResponse", + Union[ + GoogleRPCStatus, + Union[ + eventstreaming.EventStream[StreamChatEvent], + eventstreaming.EventStreamAsync[StreamChatEvent], + ], + ], +) diff --git a/src/textql_sdk/models/google_protobuf_any.py b/src/textql_sdk/models/google_protobuf_any.py new file mode 100644 index 0000000..93eee50 --- /dev/null +++ b/src/textql_sdk/models/google_protobuf_any.py @@ -0,0 +1,54 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +import pydantic +from pydantic import ConfigDict, model_serializer +from textql_sdk.types import BaseModel, UNSET_SENTINEL +from typing import Any, Dict, Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class GoogleProtobufAnyTypedDict(TypedDict): + at_type: NotRequired[str] + + +class GoogleProtobufAny(BaseModel): + model_config = ConfigDict( + populate_by_name=True, arbitrary_types_allowed=True, extra="allow" + ) + __pydantic_extra__: Dict[str, Any] = pydantic.Field(init=False) + + at_type: Annotated[Optional[str], pydantic.Field(alias="@type")] = None + + @property + def additional_properties(self): + return self.__pydantic_extra__ + + @additional_properties.setter + def additional_properties(self, value): + self.__pydantic_extra__ = value # pyright: ignore[reportIncompatibleVariableOverride] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["@type"]) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + serialized.pop(k, serialized.pop(n, None)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + for k, v in serialized.items(): + m[k] = v + + return m + + +try: + GoogleProtobufAny.model_rebuild() +except NameError: + pass diff --git a/src/textql_sdk/models/google_rpc_status.py b/src/textql_sdk/models/google_rpc_status.py new file mode 100644 index 0000000..43708b1 --- /dev/null +++ b/src/textql_sdk/models/google_rpc_status.py @@ -0,0 +1,38 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .google_protobuf_any import GoogleProtobufAny, GoogleProtobufAnyTypedDict +from pydantic import model_serializer +from textql_sdk.types import BaseModel, UNSET_SENTINEL +from typing import List, Optional +from typing_extensions import NotRequired, TypedDict + + +class GoogleRPCStatusTypedDict(TypedDict): + code: NotRequired[int] + message: NotRequired[str] + details: NotRequired[List[GoogleProtobufAnyTypedDict]] + + +class GoogleRPCStatus(BaseModel): + code: Optional[int] = None + + message: Optional[str] = None + + details: Optional[List[GoogleProtobufAny]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["code", "message", "details"]) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/src/textql_sdk/models/textql_rpc_public_chat_chatservice_streamchatbody.py b/src/textql_sdk/models/textql_rpc_public_chat_chatservice_streamchatbody.py new file mode 100644 index 0000000..87b6cbb --- /dev/null +++ b/src/textql_sdk/models/textql_rpc_public_chat_chatservice_streamchatbody.py @@ -0,0 +1,55 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .textql_rpc_public_chat_llmmodel import TextqlRPCPublicChatLlmModel +import pydantic +from pydantic import model_serializer +from textql_sdk.types import BaseModel, UNSET_SENTINEL +from typing import Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class TextqlRPCPublicChatChatServiceStreamChatBodyTypedDict(TypedDict): + latest_complete_cell_id: NotRequired[str] + research: NotRequired[bool] + model: NotRequired[TextqlRPCPublicChatLlmModel] + fast_mode: NotRequired[bool] + max_thinking: NotRequired[bool] + + +class TextqlRPCPublicChatChatServiceStreamChatBody(BaseModel): + latest_complete_cell_id: Annotated[ + Optional[str], pydantic.Field(alias="latestCompleteCellId") + ] = None + + research: Optional[bool] = None + + model: Optional[TextqlRPCPublicChatLlmModel] = None + + fast_mode: Annotated[Optional[bool], pydantic.Field(alias="fastMode")] = None + + max_thinking: Annotated[Optional[bool], pydantic.Field(alias="maxThinking")] = None + + @model_serializer(mode="wrap") + def _serialize_model(self, handler): + optional_fields = set( + ["latestCompleteCellId", "research", "model", "fastMode", "maxThinking"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +try: + TextqlRPCPublicChatChatServiceStreamChatBody.model_rebuild() +except NameError: + pass