diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index d1c9c66c..acb7a47d 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,19 +1,19 @@ lockVersion: 2.0.0 id: c48cf606-fb42-4a45-9c23-8f0555307828 management: - docChecksum: 31a453ec8245c65098405a9010d2ff54 + docChecksum: 22dd2a8c52c82b2e6d45813b3a136d8e docVersion: 1.0.0 speakeasyVersion: 1.787.0 generationVersion: 2.914.0 - releaseVersion: 0.11.1 - configChecksum: 85e803126e799123b660fa86fbd0594f + releaseVersion: 0.11.2 + configChecksum: d99c6e3ad8d65139a1705b2482f5b0f6 repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: 2fd172e4-2ed7-47d2-959b-76faccc0db40 - pristine_commit_hash: 770c36dfd9d9611977f1d4f1b874b911010e7f2b - pristine_tree_hash: 752195cbe1fa7f997c727815c9f9ea4da62ac759 + generation_id: 17428005-f3ed-41ee-832f-a08e2ee4b2c9 + pristine_commit_hash: c52584d3b29fe1ab0cd11c36fc0519e7988910d6 + pristine_tree_hash: 35802e82c88cd41747250883f8acad806745fe0e features: python: acceptHeaders: 3.0.0 @@ -2508,6 +2508,10 @@ trackedFiles: id: be60b3aa222d last_write_checksum: sha1:5e5e015f7957686bce403d8f176e4f7f9eba9b47 pristine_git_object: 27bb746a556432a1d423634c0d2f55e384de7859 + docs/components/listworkspacemembersresponse.mdx: + id: 1b8dff85b565 + last_write_checksum: sha1:3577f9efc0094f785f0413e6eacc729267e204fc + pristine_git_object: 90edcaf6b5451904212adc4202422f5808d2194f docs/components/listworkspacesresponse.mdx: id: cddf2b6dd8bf last_write_checksum: sha1:e5f4cc01853d9fa8feb77140d976d64ebe5b1d45 @@ -6016,6 +6020,18 @@ trackedFiles: id: fbaf80b58271 last_write_checksum: sha1:b9166455ca5f9dfbb1d692547ef54158685ece80 pristine_git_object: f6101881f6a54e2b999a60c6c607b2e7bcf103dc + docs/operations/listworkspacemembersglobals.mdx: + id: 0b0ec6b14941 + last_write_checksum: sha1:ed137f5daaa24ffda73b29d91830b62782c75f46 + pristine_git_object: c8f845c5520b7d515548724e90034eec4e2989f5 + docs/operations/listworkspacemembersrequest.mdx: + id: 094a5435a3a6 + last_write_checksum: sha1:655363c94d19fee214f5ca0283f5f8e4c2c10ddd + pristine_git_object: fe553b32e8a2e665d7f60820017710b9d1d1e759 + docs/operations/listworkspacemembersresponse.mdx: + id: 1ea6e450f1db + last_write_checksum: sha1:69a0763e6d3816274d51b825514ec38b637a0312 + pristine_git_object: 94558019b67d816d9deb6acc7508d3f9ab4419aa docs/operations/listworkspacesglobals.mdx: id: 796f26dced99 last_write_checksum: sha1:900a20b914fa6bf043585f1e0de3692510bab04e @@ -6346,16 +6362,16 @@ trackedFiles: pristine_git_object: 429ca7dad6a66516aec6bb1e674af1e09dc42dd5 docs/sdks/workspaces/README.mdx: id: 0c75d023ef6b - last_write_checksum: sha1:b3552fadeab957d102333c3ba7d69f7c6bae267e - pristine_git_object: cf4cc041104ab0bffd6a0c8276068616e104819c + last_write_checksum: sha1:29a4f4699004ed16b9c980463a649576b30fe035 + pristine_git_object: 37f2346cb81f6c7712df90b676b5084808b609b5 py.typed: id: 258c3ed47ae4 last_write_checksum: sha1:8efc425ffe830805ffcc0f3055871bdcdc542c60 pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:315748f12aad769a99d497d7f7b72b1bfd6d79ab - pristine_git_object: 60601548fd081896f4b477f701e887facde0de63 + last_write_checksum: sha1:e2bc1b3fccb2ccdf85aa79e5886a52f91340150a + pristine_git_object: e0deb3eae39559a8ab667ff46b01c4a505abd7db scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -6382,8 +6398,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:c775f28ffba30ec6110b067674d42628dfe28b1e - pristine_git_object: 30f0645017b376be4851dddedda35fdbcd70fb48 + last_write_checksum: sha1:0d2f123171a2b90c45806c351b029f722c836270 + pristine_git_object: 065e7c6105281025b6c465f401c6bf6c03966342 src/openrouter/analytics.py: id: cb406b5aaabb last_write_checksum: sha1:9e709b71dd0611056dc0cec6150b578defe32841 @@ -6422,8 +6438,8 @@ trackedFiles: pristine_git_object: ad3d247954547814054c01989a2dff3d12b3e4e1 src/openrouter/components/__init__.py: id: 81754e97b3f4 - last_write_checksum: sha1:f1a79345c2156a1e659b55a506babccbdd392463 - pristine_git_object: c0bbbca94f36baba1ca34b27a0827a97cf47ed00 + last_write_checksum: sha1:3d56cadcea54efec319a1d282eeae4c5b387d1e5 + pristine_git_object: 19c69fe69c979eccea5ec82ed501dda6fc391d3a src/openrouter/components/aabenchmarkentry.py: id: e2e0f0b48c82 last_write_checksum: sha1:fab4d9a24d2cea937bb749d46c5f83941e99d65c @@ -7524,6 +7540,10 @@ trackedFiles: id: 64fa8723acb0 last_write_checksum: sha1:2546a0136f06ab451e7df5d1af7d32029e5f4719 pristine_git_object: df7bc125a2e1135e8e83f6032810d879d06934f7 + src/openrouter/components/listworkspacemembersresponse.py: + id: cfe46d91c277 + last_write_checksum: sha1:f5d86b2ad810be375324b6cd281c4f41f6864419 + pristine_git_object: 911823770e39cfeb2d632eaa0796a4de58c26147 src/openrouter/components/listworkspacesresponse.py: id: 0c5f98eddbf5 last_write_checksum: sha1:53b10630a44ccc43fa86a34e9a3f5a64f08488c4 @@ -8694,8 +8714,8 @@ trackedFiles: pristine_git_object: a1dea9b45650cc42a6f60447c032fa46b102839a src/openrouter/operations/__init__.py: id: 9afcea1e7161 - last_write_checksum: sha1:a652e6a05b4685dff3a016965467f2b90b862c05 - pristine_git_object: a79839770301dc301204149ff14f7f8945122b0c + last_write_checksum: sha1:58c06e81675a137ec84b13517f78cf1020874f2d + pristine_git_object: fc51690a99a6041a78762af05e43da30f15875da src/openrouter/operations/bulkaddworkspacemembers.py: id: e0ed56117619 last_write_checksum: sha1:5c44eb0d40fdece3ac084615f6c6082be4cf1d5a @@ -8996,6 +9016,10 @@ trackedFiles: id: 1310fb7e01a9 last_write_checksum: sha1:83b3e498943e3c5a239e2c50e9d417b1f5d227fb pristine_git_object: a65454da5ec6727d99312d56c64324edd8615685 + src/openrouter/operations/listworkspacemembers.py: + id: 9886d508d283 + last_write_checksum: sha1:c83463410e0899b9f5b686e2155f69340c7acff7 + pristine_git_object: 9a8706fcb1a1761c4e636dba74866e239e8d51a3 src/openrouter/operations/listworkspaces.py: id: fe94c6f61835 last_write_checksum: sha1:2458a0c8d4834fa046496a68620b66c5ba55d927 @@ -9170,8 +9194,8 @@ trackedFiles: pristine_git_object: 4a82cde858211c0f5a01b08980cee0e9e3d0f52c src/openrouter/workspaces.py: id: cd6c533b1802 - last_write_checksum: sha1:545a54d7d445ecb42e24c9b137362747e9d90651 - pristine_git_object: d22a8e667cb3f29570234bc057261a9082d69ee5 + last_write_checksum: sha1:cde38a8140d790751ffd6bb013a4c702c112aa6f + pristine_git_object: f3cf390c8f027710aaf32e794fa5229f0447b991 examples: createResponses: speakeasy-default-create-responses: @@ -10599,5 +10623,23 @@ examples: application/json: {"error": {"code": 404, "message": "Resource not found"}} "500": application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + listWorkspaceMembers: + speakeasy-default-list-workspace-members: + parameters: + path: + id: "production" + responses: + "200": + application/json: {"data": [{"created_at": "2025-08-24T10:30:00Z", "id": "660e8400-e29b-41d4-a716-446655440000", "role": "member", "user_id": "user_abc123", "workspace_id": "550e8400-e29b-41d4-a716-446655440000"}], "total_count": 1} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "403": + application/json: {"error": {"code": 403, "message": "Only management keys can perform this operation"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} examplesVersion: 1.0.2 -releaseNotes: "## Python SDK Changes:\n* `open_router.beta.responses.send()`: \n * `request.tools[].union(openrouter:files)` **Added**\n* `open_router.chat.send()`: \n * `request.tools[].union(FilesServerTool)` **Added**\n* `open_router.presets.create_presets_chat_completions()`: \n * `request.tools[].union(FilesServerTool)` **Added**\n* `open_router.presets.create_presets_responses()`: \n * `request.tools[].union(openrouter:files)` **Added**\n" +releaseNotes: | + ## Python SDK Changes: + * `open_router.workspaces.list_members()`: **Added** diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index c14d6f5e..fcd35491 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -36,7 +36,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 0.11.1 + version: 0.11.2 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index 3ff05edf..39c2451f 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -10872,6 +10872,29 @@ components: required: - data type: object + ListWorkspaceMembersResponse: + example: + data: + - created_at: '2025-08-24T10:30:00Z' + id: 660e8400-e29b-41d4-a716-446655440000 + role: member + user_id: user_abc123 + workspace_id: 550e8400-e29b-41d4-a716-446655440000 + total_count: 1 + properties: + data: + description: List of workspace members + items: + $ref: '#/components/schemas/WorkspaceMember' + type: array + total_count: + description: Total number of members in the workspace + example: 5 + type: integer + required: + - data + - total_count + type: object ListWorkspacesResponse: example: data: @@ -33907,6 +33930,115 @@ paths: - $ref: "#/components/parameters/AppIdentifier" - $ref: "#/components/parameters/AppDisplayName" - $ref: "#/components/parameters/AppCategories" + /workspaces/{id}/members: + get: + description: >- + List all members of a workspace. Returns paginated results. For the default workspace, returns all organization members (implicit membership). [Management key](/docs/guides/overview/auth/management-api-keys) required. + operationId: listWorkspaceMembers + parameters: + - description: The workspace ID (UUID) or slug + in: path + name: id + required: true + schema: + description: The workspace ID (UUID) or slug + example: production + minLength: 1 + type: string + - description: Number of records to skip for pagination + in: query + name: offset + required: false + schema: + description: Number of records to skip for pagination + example: 0 + minimum: 0 + nullable: false + type: integer + - description: Maximum number of records to return (max 100) + in: query + name: limit + required: false + schema: + description: Maximum number of records to return (max 100) + example: 50 + maximum: 100 + minimum: 1 + type: integer + responses: + '200': + content: + application/json: + example: + data: + - created_at: '2025-08-24T10:30:00Z' + id: 660e8400-e29b-41d4-a716-446655440000 + role: member + user_id: user_abc123 + workspace_id: 550e8400-e29b-41d4-a716-446655440000 + total_count: 1 + schema: + $ref: '#/components/schemas/ListWorkspaceMembersResponse' + description: List of workspace members + '401': + content: + application/json: + example: + error: + code: 401 + message: Missing Authentication header + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: Unauthorized - Authentication required or invalid credentials + '403': + content: + application/json: + example: + error: + code: 403 + message: Only management keys can perform this operation + schema: + $ref: '#/components/schemas/ForbiddenResponse' + description: Forbidden - Authentication successful but insufficient permissions + '404': + content: + application/json: + example: + error: + code: 404 + message: Resource not found + schema: + $ref: '#/components/schemas/NotFoundResponse' + description: Not Found - Resource does not exist + '500': + content: + application/json: + example: + error: + code: 500 + message: Internal Server Error + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: Internal Server Error - Unexpected server error + summary: List workspace members + tags: + - Workspaces + x-speakeasy-name-override: listMembers + x-speakeasy-pagination: + inputs: + - in: parameters + name: offset + type: offset + - in: parameters + name: limit + type: limit + outputs: + results: $.data + type: offsetLimit + parameters: + - $ref: "#/components/parameters/AppIdentifier" + - $ref: "#/components/parameters/AppDisplayName" + - $ref: "#/components/parameters/AppCategories" /workspaces/{id}/members/add: post: description: >- diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index d7018bfe..9e6f0884 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -2,8 +2,8 @@ speakeasyVersion: 1.787.0 sources: OpenRouter API: sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:f55ad0f499156d20c6b57efb38c3ae9ed94c860e434405e7d52338e61eb6f79c - sourceBlobDigest: sha256:90e75fce2c45d81d02e9eaeb0a1be6e2d4a214ac796334b5680996b911d4e9c5 + sourceRevisionDigest: sha256:5f1370b2087005edf5335d559553a8e78a7f68548feeb5007ffd159eb331d4b8 + sourceBlobDigest: sha256:ccab13156b379a7393d475a3dffeede1ab1e849f77860609a73af1ce7a3839e4 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:f55ad0f499156d20c6b57efb38c3ae9ed94c860e434405e7d52338e61eb6f79c - sourceBlobDigest: sha256:90e75fce2c45d81d02e9eaeb0a1be6e2d4a214ac796334b5680996b911d4e9c5 + sourceRevisionDigest: sha256:5f1370b2087005edf5335d559553a8e78a7f68548feeb5007ffd159eb331d4b8 + sourceBlobDigest: sha256:ccab13156b379a7393d475a3dffeede1ab1e849f77860609a73af1ce7a3839e4 codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:32b3050b10d3e0f8cbe39300fb98b5c0e1ee9b07ff7c1c4bcef85045d844b33c + codeSamplesRevisionDigest: sha256:68f0535d2a29eafd4da54cc0f2ebb260b678afae6f4a752f76cad957fb319df2 workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.787.0 diff --git a/RELEASES.md b/RELEASES.md index 06b3d82b..251818a2 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -118,4 +118,14 @@ Based on: ### Generated - [python v0.11.1] . ### Releases -- [PyPI v0.11.1] https://pypi.org/project/openrouter/0.11.1 - . \ No newline at end of file +- [PyPI v0.11.1] https://pypi.org/project/openrouter/0.11.1 - . + +## 2026-07-03 15:05:16 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v0.11.2] . +### Releases +- [PyPI v0.11.2] https://pypi.org/project/openrouter/0.11.2 - . \ No newline at end of file diff --git a/docs/components/listworkspacemembersresponse.mdx b/docs/components/listworkspacemembersresponse.mdx new file mode 100644 index 00000000..90edcaf6 --- /dev/null +++ b/docs/components/listworkspacemembersresponse.mdx @@ -0,0 +1,10 @@ +--- +title: "ListWorkspaceMembersResponse" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | +| `data` | List[[components.WorkspaceMember](../components/workspacemember.mdx)] | :heavy_check_mark: | List of workspace members | | +| `total_count` | *int* | :heavy_check_mark: | Total number of members in the workspace | 5 | \ No newline at end of file diff --git a/docs/operations/listworkspacemembersglobals.mdx b/docs/operations/listworkspacemembersglobals.mdx new file mode 100644 index 00000000..c8f845c5 --- /dev/null +++ b/docs/operations/listworkspacemembersglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "ListWorkspaceMembersGlobals" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| \ No newline at end of file diff --git a/docs/operations/listworkspacemembersrequest.mdx b/docs/operations/listworkspacemembersrequest.mdx new file mode 100644 index 00000000..fe553b32 --- /dev/null +++ b/docs/operations/listworkspacemembersrequest.mdx @@ -0,0 +1,14 @@ +--- +title: "ListWorkspaceMembersRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `id` | *str* | :heavy_check_mark: | The workspace ID (UUID) or slug | production | +| `offset` | *Optional[int]* | :heavy_minus_sign: | Number of records to skip for pagination | 0 | +| `limit` | *Optional[int]* | :heavy_minus_sign: | Maximum number of records to return (max 100) | 50 | \ No newline at end of file diff --git a/docs/operations/listworkspacemembersresponse.mdx b/docs/operations/listworkspacemembersresponse.mdx new file mode 100644 index 00000000..94558019 --- /dev/null +++ b/docs/operations/listworkspacemembersresponse.mdx @@ -0,0 +1,9 @@ +--- +title: "ListWorkspaceMembersResponse" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `result` | [components.ListWorkspaceMembersResponse](../components/listworkspacemembersresponse.mdx) | :heavy_check_mark: | N/A | \{
"data": [
\{
"created_at": "2025-08-24T10:30:00Z",
"id": "660e8400-e29b-41d4-a716-446655440000",
"role": "member",
"user_id": "user_abc123",
"workspace_id": "550e8400-e29b-41d4-a716-446655440000"
}
],
"total_count": 1
} | \ No newline at end of file diff --git a/docs/sdks/workspaces/README.mdx b/docs/sdks/workspaces/README.mdx index cf4cc041..37f2346c 100644 --- a/docs/sdks/workspaces/README.mdx +++ b/docs/sdks/workspaces/README.mdx @@ -17,6 +17,7 @@ Workspaces endpoints * [list_budgets](#list_budgets) - List workspace budgets * [delete_budget](#delete_budget) - Delete a workspace budget * [set_budget](#set_budget) - Create or update a workspace budget +* [list_members](#list_members) - List workspace members * [bulk_add_members](#bulk_add_members) - Bulk add members to a workspace * [bulk_remove_members](#bulk_remove_members) - Bulk remove members from a workspace @@ -436,6 +437,59 @@ with OpenRouter( | errors.InternalServerResponseError | 500 | application/json | | errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | +## list_members + +List all members of a workspace. Returns paginated results. For the default workspace, returns all organization members (implicit membership). [Management key](/docs/guides/overview/auth/management-api-keys) required. + +### Example Usage + +```python +from openrouter import OpenRouter +import os + + +with OpenRouter( + http_referer="", + x_open_router_title="", + x_open_router_categories="", + api_key=os.getenv("OPENROUTER_API_KEY", ""), +) as open_router: + + res = open_router.workspaces.list_members(id="production") + + while res is not None: + # Handle items + + res = res.next() + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | *str* | :heavy_check_mark: | The workspace ID (UUID) or slug | production | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `offset` | *Optional[int]* | :heavy_minus_sign: | Number of records to skip for pagination | 0 | +| `limit` | *Optional[int]* | :heavy_minus_sign: | Maximum number of records to return (max 100) | 50 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[operations.ListWorkspaceMembersResponse](../../operations/listworkspacemembersresponse.mdx)** + +### Errors + +| Error Type | Status Code | Content Type | +| ---------------------------------- | ---------------------------------- | ---------------------------------- | +| errors.UnauthorizedResponseError | 401 | application/json | +| errors.ForbiddenResponseError | 403 | application/json | +| errors.NotFoundResponseError | 404 | application/json | +| errors.InternalServerResponseError | 500 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | + ## bulk_add_members Add multiple organization members to a workspace. Members are assigned the same role they hold in the organization. [Management key](/docs/guides/overview/auth/management-api-keys) required. diff --git a/pyproject.toml b/pyproject.toml index 60601548..e0deb3ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "0.11.1" +version = "0.11.2" description = "Official Python Client SDK for OpenRouter." authors = [{ name = "OpenRouter" },] readme = "README-PYPI.md" diff --git a/src/openrouter/_version.py b/src/openrouter/_version.py index 30f06450..065e7c61 100644 --- a/src/openrouter/_version.py +++ b/src/openrouter/_version.py @@ -3,10 +3,10 @@ import importlib.metadata __title__: str = "openrouter" -__version__: str = "0.11.1" +__version__: str = "0.11.2" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.914.0" -__user_agent__: str = "speakeasy-sdk/python 0.11.1 2.914.0 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 0.11.2 2.914.0 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/components/__init__.py b/src/openrouter/components/__init__.py index c0bbbca9..19c69fe6 100644 --- a/src/openrouter/components/__init__.py +++ b/src/openrouter/components/__init__.py @@ -1330,6 +1330,10 @@ ListWorkspaceBudgetsResponse, ListWorkspaceBudgetsResponseTypedDict, ) + from .listworkspacemembersresponse import ( + ListWorkspaceMembersResponse, + ListWorkspaceMembersResponseTypedDict, + ) from .listworkspacesresponse import ( ListWorkspacesResponse, ListWorkspacesResponseTypedDict, @@ -3686,6 +3690,8 @@ "ListPresetsResponseTypedDict", "ListWorkspaceBudgetsResponse", "ListWorkspaceBudgetsResponseTypedDict", + "ListWorkspaceMembersResponse", + "ListWorkspaceMembersResponseTypedDict", "ListWorkspacesResponse", "ListWorkspacesResponseTypedDict", "LocalShellCallItem", @@ -5651,6 +5657,8 @@ "ListPresetVersionsResponseTypedDict": ".listpresetversionsresponse", "ListWorkspaceBudgetsResponse": ".listworkspacebudgetsresponse", "ListWorkspaceBudgetsResponseTypedDict": ".listworkspacebudgetsresponse", + "ListWorkspaceMembersResponse": ".listworkspacemembersresponse", + "ListWorkspaceMembersResponseTypedDict": ".listworkspacemembersresponse", "ListWorkspacesResponse": ".listworkspacesresponse", "ListWorkspacesResponseTypedDict": ".listworkspacesresponse", "LocalShellCallItem": ".localshellcallitem", diff --git a/src/openrouter/components/listworkspacemembersresponse.py b/src/openrouter/components/listworkspacemembersresponse.py new file mode 100644 index 00000000..91182377 --- /dev/null +++ b/src/openrouter/components/listworkspacemembersresponse.py @@ -0,0 +1,22 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .workspacemember import WorkspaceMember, WorkspaceMemberTypedDict +from openrouter.types import BaseModel +from typing import List +from typing_extensions import TypedDict + + +class ListWorkspaceMembersResponseTypedDict(TypedDict): + data: List[WorkspaceMemberTypedDict] + r"""List of workspace members""" + total_count: int + r"""Total number of members in the workspace""" + + +class ListWorkspaceMembersResponse(BaseModel): + data: List[WorkspaceMember] + r"""List of workspace members""" + + total_count: int + r"""Total number of members in the workspace""" diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py index a7983977..fc51690a 100644 --- a/src/openrouter/operations/__init__.py +++ b/src/openrouter/operations/__init__.py @@ -618,6 +618,14 @@ ListWorkspaceBudgetsRequest, ListWorkspaceBudgetsRequestTypedDict, ) + from .listworkspacemembers import ( + ListWorkspaceMembersGlobals, + ListWorkspaceMembersGlobalsTypedDict, + ListWorkspaceMembersRequest, + ListWorkspaceMembersRequestTypedDict, + ListWorkspaceMembersResponse, + ListWorkspaceMembersResponseTypedDict, + ) from .listworkspaces import ( ListWorkspacesGlobals, ListWorkspacesGlobalsTypedDict, @@ -1159,6 +1167,12 @@ "ListWorkspaceBudgetsGlobalsTypedDict", "ListWorkspaceBudgetsRequest", "ListWorkspaceBudgetsRequestTypedDict", + "ListWorkspaceMembersGlobals", + "ListWorkspaceMembersGlobalsTypedDict", + "ListWorkspaceMembersRequest", + "ListWorkspaceMembersRequestTypedDict", + "ListWorkspaceMembersResponse", + "ListWorkspaceMembersResponseTypedDict", "ListWorkspacesGlobals", "ListWorkspacesGlobalsTypedDict", "ListWorkspacesRequest", @@ -1721,6 +1735,12 @@ "ListWorkspaceBudgetsGlobalsTypedDict": ".listworkspacebudgets", "ListWorkspaceBudgetsRequest": ".listworkspacebudgets", "ListWorkspaceBudgetsRequestTypedDict": ".listworkspacebudgets", + "ListWorkspaceMembersGlobals": ".listworkspacemembers", + "ListWorkspaceMembersGlobalsTypedDict": ".listworkspacemembers", + "ListWorkspaceMembersRequest": ".listworkspacemembers", + "ListWorkspaceMembersRequestTypedDict": ".listworkspacemembers", + "ListWorkspaceMembersResponse": ".listworkspacemembers", + "ListWorkspaceMembersResponseTypedDict": ".listworkspacemembers", "ListWorkspacesGlobals": ".listworkspaces", "ListWorkspacesGlobalsTypedDict": ".listworkspaces", "ListWorkspacesRequest": ".listworkspaces", diff --git a/src/openrouter/operations/listworkspacemembers.py b/src/openrouter/operations/listworkspacemembers.py new file mode 100644 index 00000000..9a8706fc --- /dev/null +++ b/src/openrouter/operations/listworkspacemembers.py @@ -0,0 +1,189 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.components import ( + listworkspacemembersresponse as components_listworkspacemembersresponse, +) +from openrouter.types import BaseModel, UNSET_SENTINEL +from openrouter.utils import ( + FieldMetadata, + HeaderMetadata, + PathParamMetadata, + QueryParamMetadata, +) +import pydantic +from pydantic import model_serializer +from typing import Awaitable, Callable, Optional, Union +from typing_extensions import Annotated, NotRequired, TypedDict + + +class ListWorkspaceMembersGlobalsTypedDict(TypedDict): + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class ListWorkspaceMembersGlobals(BaseModel): + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + 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 ListWorkspaceMembersRequestTypedDict(TypedDict): + id: str + r"""The workspace ID (UUID) or slug""" + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + offset: NotRequired[int] + r"""Number of records to skip for pagination""" + limit: NotRequired[int] + r"""Maximum number of records to return (max 100)""" + + +class ListWorkspaceMembersRequest(BaseModel): + id: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + r"""The workspace ID (UUID) or slug""" + + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + offset: Annotated[ + Optional[int], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = None + r"""Number of records to skip for pagination""" + + limit: Annotated[ + Optional[int], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = None + r"""Maximum number of records to return (max 100)""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + [ + "HTTP-Referer", + "X-OpenRouter-Title", + "X-OpenRouter-Categories", + "offset", + "limit", + ] + ) + 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 ListWorkspaceMembersResponseTypedDict(TypedDict): + result: ( + components_listworkspacemembersresponse.ListWorkspaceMembersResponseTypedDict + ) + + +class ListWorkspaceMembersResponse(BaseModel): + next: Union[ + Callable[[], Optional[ListWorkspaceMembersResponse]], + Callable[[], Awaitable[Optional[ListWorkspaceMembersResponse]]], + ] + + result: components_listworkspacemembersresponse.ListWorkspaceMembersResponse diff --git a/src/openrouter/workspaces.py b/src/openrouter/workspaces.py index d22a8e66..f3cf390c 100644 --- a/src/openrouter/workspaces.py +++ b/src/openrouter/workspaces.py @@ -2402,6 +2402,353 @@ async def set_budget_async( raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + def list_members( + self, + *, + id: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + offset: Optional[int] = None, + limit: Optional[int] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> Optional[operations.ListWorkspaceMembersResponse]: + r"""List workspace members + + List all members of a workspace. Returns paginated results. For the default workspace, returns all organization members (implicit membership). [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param id: The workspace ID (UUID) or slug + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param offset: Number of records to skip for pagination + :param limit: Maximum number of records to return (max 100) + :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 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 = operations.ListWorkspaceMembersRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + id=id, + offset=offset, + limit=limit, + ) + + req = self._build_request( + method="GET", + path="/workspaces/{id}/members", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.ListWorkspaceMembersGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + 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 + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = self.do_request( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="listWorkspaceMembers", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["Workspaces"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + def next_func() -> Optional[operations.ListWorkspaceMembersResponse]: + body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]]) + + offset = request.offset if isinstance(request.offset, int) else 0 + + if not http_res.text: + return None + results = JSONPath("$.data").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit_ = request.limit if isinstance(request.limit, int) else 0 + if len(results[0]) < limit_: + return None + next_offset = offset + len(results[0]) + + return self.list_members( + id=id, + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + offset=next_offset, + limit=limit, + retries=retries, + server_url=server_url, + timeout_ms=timeout_ms, + http_headers=http_headers, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return operations.ListWorkspaceMembersResponse( + result=unmarshal_json_response( + components.ListWorkspaceMembersResponse, http_res + ), + next=next_func, + ) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "403", "application/json"): + response_data = unmarshal_json_response( + errors.ForbiddenResponseErrorData, http_res + ) + raise errors.ForbiddenResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "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.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + async def list_members_async( + self, + *, + id: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + offset: Optional[int] = None, + limit: Optional[int] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> Optional[operations.ListWorkspaceMembersResponse]: + r"""List workspace members + + List all members of a workspace. Returns paginated results. For the default workspace, returns all organization members (implicit membership). [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param id: The workspace ID (UUID) or slug + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param offset: Number of records to skip for pagination + :param limit: Maximum number of records to return (max 100) + :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 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 = operations.ListWorkspaceMembersRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + id=id, + offset=offset, + limit=limit, + ) + + req = self._build_request_async( + method="GET", + path="/workspaces/{id}/members", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.ListWorkspaceMembersGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + 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 + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="listWorkspaceMembers", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["Workspaces"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + def next_func() -> Awaitable[Optional[operations.ListWorkspaceMembersResponse]]: + body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]]) + + async def empty_result(): + return None + + offset = request.offset if isinstance(request.offset, int) else 0 + + if not http_res.text: + return empty_result() + results = JSONPath("$.data").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return empty_result() + limit_ = request.limit if isinstance(request.limit, int) else 0 + if len(results[0]) < limit_: + return empty_result() + next_offset = offset + len(results[0]) + + return self.list_members_async( + id=id, + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + offset=next_offset, + limit=limit, + retries=retries, + server_url=server_url, + timeout_ms=timeout_ms, + http_headers=http_headers, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return operations.ListWorkspaceMembersResponse( + result=unmarshal_json_response( + components.ListWorkspaceMembersResponse, http_res + ), + next=next_func, + ) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "403", "application/json"): + response_data = unmarshal_json_response( + errors.ForbiddenResponseErrorData, http_res + ) + raise errors.ForbiddenResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "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.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + def bulk_add_members( self, *, diff --git a/uv.lock b/uv.lock index 68cc8206..b1a15246 100644 --- a/uv.lock +++ b/uv.lock @@ -213,7 +213,7 @@ wheels = [ [[package]] name = "openrouter" -version = "0.11.1" +version = "0.11.2" source = { editable = "." } dependencies = [ { name = "httpcore" },