Compare commits

...

59 commits

Author SHA1 Message Date
stainless-app[bot]
817f1a0816 release: 0.1.0-alpha.36 2025-08-27 02:38:36 +00:00
stainless-app[bot]
7a6b7d16c4 chore(internal): update pyright exclude list 2025-08-27 02:38:36 +00:00
stainless-app[bot]
6eae86427a fix: avoid newer type syntax 2025-08-27 02:38:36 +00:00
stainless-app[bot]
c11a24e28e chore(internal): change ci workflow machines 2025-08-27 02:38:36 +00:00
stainless-app[bot]
a1b54afef1 chore: update github action 2025-08-27 02:38:36 +00:00
stainless-app[bot]
5f8681cf63 chore(internal): codegen related update 2025-08-27 02:38:36 +00:00
stainless-app[bot]
ec855544b2 chore(internal): update comment in script 2025-08-27 02:38:36 +00:00
stainless-app[bot]
bdbeff638a chore: update @stainless-api/prism-cli to v5.15.0 2025-08-27 02:38:36 +00:00
stainless-app[bot]
63af9064ec chore(internal): fix ruff target version 2025-08-27 02:38:36 +00:00
stainless-app[bot]
34ccc7f7d7 feat(client): support file upload requests 2025-08-27 02:38:36 +00:00
stainless-app[bot]
a4212485db release: 0.1.0-alpha.35 2025-07-29 02:59:34 +00:00
stainless-app[bot]
1c6a3700f1 feat(api): api update 2025-07-29 02:59:34 +00:00
stainless-app[bot]
17f9c65321 release: 0.1.0-alpha.34 2025-07-28 17:08:39 +00:00
stainless-app[bot]
206f54ea71 feat(api): api update 2025-07-28 17:08:39 +00:00
stainless-app[bot]
1de4987d50 feat(api): api update 2025-07-28 17:08:39 +00:00
stainless-app[bot]
4e7027e1d9 release: 0.1.0-alpha.33 2025-07-25 02:26:21 +00:00
stainless-app[bot]
4d13992ad1 chore(project): add settings file for vscode 2025-07-25 02:26:21 +00:00
stainless-app[bot]
145229a92b feat(api): api update 2025-07-25 02:26:21 +00:00
stainless-app[bot]
45b4e60154 release: 0.1.0-alpha.32 2025-07-24 04:08:59 +00:00
stainless-app[bot]
c75867efe7 feat(api): api update 2025-07-24 04:08:59 +00:00
stainless-app[bot]
10a8dac1d7 release: 0.1.0-alpha.31 2025-07-24 01:49:43 +00:00
stainless-app[bot]
4c0117a6c5 feat(api): api update 2025-07-24 01:49:43 +00:00
stainless-app[bot]
8b4a7b17fc release: 0.1.0-alpha.30 2025-07-23 03:06:36 +00:00
stainless-app[bot]
0a269c0379 fix(parsing): parse extra field types 2025-07-23 03:06:36 +00:00
stainless-app[bot]
646b99cd24 release: 0.1.0-alpha.29 2025-07-22 21:55:44 +00:00
stainless-app[bot]
5f9e3cd004 feat(api): api update 2025-07-22 21:55:44 +00:00
stainless-app[bot]
f2d28d2990 release: 0.1.0-alpha.28 2025-07-22 16:09:30 +00:00
stainless-app[bot]
1bddb4b6c3 codegen metadata 2025-07-22 16:09:30 +00:00
stainless-app[bot]
6e577d0bde feat(api): api update 2025-07-22 16:09:30 +00:00
stainless-app[bot]
60df30faf5 release: 0.1.0-alpha.27 2025-07-22 02:03:53 +00:00
stainless-app[bot]
d0c8c5bb87 fix(parsing): ignore empty metadata 2025-07-22 02:03:53 +00:00
stainless-app[bot]
ff6b72a6da feat(api): api update 2025-07-22 02:03:53 +00:00
stainless-app[bot]
c75c9633c9 release: 0.1.0-alpha.26 2025-07-21 23:24:56 +00:00
stainless-app[bot]
be1f9d88f0 feat(api): api update 2025-07-21 23:24:56 +00:00
stainless-app[bot]
e27c59a26c codegen metadata 2025-07-21 23:24:56 +00:00
stainless-app[bot]
8ea99fb27b release: 0.1.0-alpha.25 2025-07-21 23:01:10 +00:00
stainless-app[bot]
98315648f7 feat(api): api update 2025-07-21 23:01:10 +00:00
stainless-app[bot]
c9d0f6daa1 codegen metadata 2025-07-21 23:01:10 +00:00
stainless-app[bot]
4c406aa027 codegen metadata 2025-07-21 23:01:10 +00:00
stainless-app[bot]
05859cbd01 release: 0.1.0-alpha.24 2025-07-21 22:40:17 +00:00
stainless-app[bot]
e2e1f1d384 feat(api): api update 2025-07-21 22:40:17 +00:00
stainless-app[bot]
06577e9685 release: 0.1.0-alpha.23 2025-07-18 17:47:39 +00:00
stainless-app[bot]
5f542aa68e feat(api): api update 2025-07-18 17:47:39 +00:00
stainless-app[bot]
002bf2d57f release: 0.1.0-alpha.22 2025-07-17 19:40:32 +00:00
stainless-app[bot]
d19014d391 feat(api): api update 2025-07-17 19:40:32 +00:00
stainless-app[bot]
5ae45651bd release: 0.1.0-alpha.21 2025-07-17 19:29:58 +00:00
stainless-app[bot]
5e3dae765d feat(api): api update 2025-07-17 19:29:58 +00:00
stainless-app[bot]
a617d3359f codegen metadata 2025-07-17 19:29:58 +00:00
stainless-app[bot]
23ee4bb279 release: 0.1.0-alpha.20 2025-07-17 19:22:15 +00:00
stainless-app[bot]
e9bdc09f73 feat(api): api update 2025-07-17 19:22:15 +00:00
stainless-app[bot]
6fc2509c19 release: 0.1.0-alpha.19 2025-07-17 03:06:30 +00:00
stainless-app[bot]
731f553f04 feat(api): api update 2025-07-17 03:06:30 +00:00
stainless-app[bot]
3214ae78d3 release: 0.1.0-alpha.18 2025-07-16 15:08:05 +00:00
stainless-app[bot]
d899ee8369 feat(api): api update 2025-07-16 15:08:05 +00:00
stainless-app[bot]
36382a289b codegen metadata 2025-07-16 15:08:05 +00:00
stainless-app[bot]
fad149a84b release: 0.1.0-alpha.17 2025-07-16 14:54:11 +00:00
stainless-app[bot]
f1d9d8f9ec feat(api): api update 2025-07-16 14:54:11 +00:00
stainless-app[bot]
94575f6882 release: 0.1.0-alpha.16 2025-07-15 15:01:24 +00:00
stainless-app[bot]
7a9790fae8 feat(api): api update 2025-07-15 15:01:24 +00:00
63 changed files with 2000 additions and 793 deletions

View file

@ -36,13 +36,13 @@ jobs:
run: ./scripts/lint run: ./scripts/lint
build: build:
if: github.repository == 'stainless-sdks/opencode-python' && (github.event_name == 'push' || github.event.pull_request.head.repo.fork) if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
timeout-minutes: 10 timeout-minutes: 10
name: build name: build
permissions: permissions:
contents: read contents: read
id-token: write id-token: write
runs-on: depot-ubuntu-24.04 runs-on: ${{ github.repository == 'stainless-sdks/opencode-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -61,12 +61,14 @@ jobs:
run: rye build run: rye build
- name: Get GitHub OIDC Token - name: Get GitHub OIDC Token
if: github.repository == 'stainless-sdks/opencode-python'
id: github-oidc id: github-oidc
uses: actions/github-script@v6 uses: actions/github-script@v6
with: with:
script: core.setOutput('github_token', await core.getIDToken()); script: core.setOutput('github_token', await core.getIDToken());
- name: Upload tarball - name: Upload tarball
if: github.repository == 'stainless-sdks/opencode-python'
env: env:
URL: https://pkg.stainless.com/s URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }} AUTH: ${{ steps.github-oidc.outputs.github_token }}

1
.gitignore vendored
View file

@ -1,5 +1,4 @@
.prism.log .prism.log
.vscode
_dev _dev
__pycache__ __pycache__

View file

@ -1,3 +1,3 @@
{ {
".": "0.1.0-alpha.15" ".": "0.1.0-alpha.36"
} }

View file

@ -1,4 +1,4 @@
configured_endpoints: 22 configured_endpoints: 26
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-7270b9e4859010d6680bcc92afcd6f7c679d80a2645f65d7097d19ce2e8cdc5a.yml openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-62d8fccba4eb8dc3a80434e0849eab3352e49fb96a718bb7b6d17ed8e582b716.yml
openapi_spec_hash: 5fcbfaedebfea62c17c74437a9728b04 openapi_spec_hash: 4ff9376cf9634e91731e63fe482ea532
config_hash: 38a50dff50297c2f735b5e1c83fa0188 config_hash: 1ae82c93499b9f0b9ba828b8919f9cb3

3
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"python.analysis.importFormat": "relative",
}

View file

@ -1,5 +1,200 @@
# Changelog # Changelog
## 0.1.0-alpha.36 (2025-08-27)
Full Changelog: [v0.1.0-alpha.35...v0.1.0-alpha.36](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.35...v0.1.0-alpha.36)
### Features
* **client:** support file upload requests ([c2e1522](https://github.com/sst/opencode-sdk-python/commit/c2e1522ffba596910098e1e58eef7b4d00548e18))
### Bug Fixes
* avoid newer type syntax ([42779eb](https://github.com/sst/opencode-sdk-python/commit/42779eb3d7035b677ef213d6508658dbd56b50bf))
### Chores
* **internal:** change ci workflow machines ([14c918e](https://github.com/sst/opencode-sdk-python/commit/14c918ee18edc797d2d8dd1f1d462ffb004a7e89))
* **internal:** codegen related update ([477ff58](https://github.com/sst/opencode-sdk-python/commit/477ff58aa920fd0c02378ff33c041d061923dee4))
* **internal:** fix ruff target version ([359b956](https://github.com/sst/opencode-sdk-python/commit/359b95615445c2f675aa3520cb233c19b50dfe31))
* **internal:** update comment in script ([9ac7cbb](https://github.com/sst/opencode-sdk-python/commit/9ac7cbb6dba85d18d18bd37f95dffc0eea3d2605))
* **internal:** update pyright exclude list ([5d96f63](https://github.com/sst/opencode-sdk-python/commit/5d96f63f7a9aaebb2e85fcd11b380bbeca3b7310))
* update @stainless-api/prism-cli to v5.15.0 ([88487ee](https://github.com/sst/opencode-sdk-python/commit/88487ee6dbc8ac60e9d26573c8f08ae3f1389e83))
* update github action ([fe98742](https://github.com/sst/opencode-sdk-python/commit/fe98742cd53b1e8783f600879164dd16fea610d3))
## 0.1.0-alpha.35 (2025-07-29)
Full Changelog: [v0.1.0-alpha.34...v0.1.0-alpha.35](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.34...v0.1.0-alpha.35)
### Features
* **api:** api update ([06ebf15](https://github.com/sst/opencode-sdk-python/commit/06ebf15e7ed0f782dbf51352a71fc5edb948a93c))
## 0.1.0-alpha.34 (2025-07-28)
Full Changelog: [v0.1.0-alpha.33...v0.1.0-alpha.34](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.33...v0.1.0-alpha.34)
### Features
* **api:** api update ([0bc9251](https://github.com/sst/opencode-sdk-python/commit/0bc92517109d280c22e22639ee4ffa58d63d837b))
* **api:** api update ([14ada9d](https://github.com/sst/opencode-sdk-python/commit/14ada9d7d1e93d85f357f417633b691b116c8ad5))
## 0.1.0-alpha.33 (2025-07-25)
Full Changelog: [v0.1.0-alpha.32...v0.1.0-alpha.33](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.32...v0.1.0-alpha.33)
### Features
* **api:** api update ([9002768](https://github.com/sst/opencode-sdk-python/commit/9002768edd617a44d4d686dd9e88f41fe6a56f2f))
### Chores
* **project:** add settings file for vscode ([7fff9af](https://github.com/sst/opencode-sdk-python/commit/7fff9af8fd66865dc933dce74f0385250377af87))
## 0.1.0-alpha.32 (2025-07-24)
Full Changelog: [v0.1.0-alpha.31...v0.1.0-alpha.32](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.31...v0.1.0-alpha.32)
### Features
* **api:** api update ([988b38c](https://github.com/sst/opencode-sdk-python/commit/988b38ce1d4b7694083abe26f2198463d4555012))
## 0.1.0-alpha.31 (2025-07-24)
Full Changelog: [v0.1.0-alpha.30...v0.1.0-alpha.31](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.30...v0.1.0-alpha.31)
### Features
* **api:** api update ([35553a6](https://github.com/sst/opencode-sdk-python/commit/35553a6e3b3472562cdc38f0399fcd37af1b52e9))
## 0.1.0-alpha.30 (2025-07-23)
Full Changelog: [v0.1.0-alpha.29...v0.1.0-alpha.30](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.29...v0.1.0-alpha.30)
### Bug Fixes
* **parsing:** parse extra field types ([6817656](https://github.com/sst/opencode-sdk-python/commit/6817656ba347e8074960af1526763c134d75cf7d))
## 0.1.0-alpha.29 (2025-07-22)
Full Changelog: [v0.1.0-alpha.28...v0.1.0-alpha.29](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.28...v0.1.0-alpha.29)
### Features
* **api:** api update ([08130f0](https://github.com/sst/opencode-sdk-python/commit/08130f0c068f4008ffda297c68a68a44dec34d95))
## 0.1.0-alpha.28 (2025-07-22)
Full Changelog: [v0.1.0-alpha.27...v0.1.0-alpha.28](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.27...v0.1.0-alpha.28)
### Features
* **api:** api update ([e8022cd](https://github.com/sst/opencode-sdk-python/commit/e8022cd6d313c1c710dc2721f7e962285d48b02e))
## 0.1.0-alpha.27 (2025-07-22)
Full Changelog: [v0.1.0-alpha.26...v0.1.0-alpha.27](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.26...v0.1.0-alpha.27)
### Features
* **api:** api update ([50c887c](https://github.com/sst/opencode-sdk-python/commit/50c887c4202f587317afecb8998181c6de78b7b4))
### Bug Fixes
* **parsing:** ignore empty metadata ([8ee35ae](https://github.com/sst/opencode-sdk-python/commit/8ee35ae762cb0ade81b08cc41a9f496afe9fd484))
## 0.1.0-alpha.26 (2025-07-21)
Full Changelog: [v0.1.0-alpha.25...v0.1.0-alpha.26](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.25...v0.1.0-alpha.26)
### Features
* **api:** api update ([827dc0c](https://github.com/sst/opencode-sdk-python/commit/827dc0c780afd217f981cdd31d371fe96327aeec))
## 0.1.0-alpha.25 (2025-07-21)
Full Changelog: [v0.1.0-alpha.24...v0.1.0-alpha.25](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.24...v0.1.0-alpha.25)
### Features
* **api:** api update ([a85f832](https://github.com/sst/opencode-sdk-python/commit/a85f832a942075091b9ca3f7e6399ba00239f354))
## 0.1.0-alpha.24 (2025-07-21)
Full Changelog: [v0.1.0-alpha.23...v0.1.0-alpha.24](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.23...v0.1.0-alpha.24)
### Features
* **api:** api update ([bd6dd48](https://github.com/sst/opencode-sdk-python/commit/bd6dd48f11b23c77802e0a36af94c1a92c0326c7))
## 0.1.0-alpha.23 (2025-07-18)
Full Changelog: [v0.1.0-alpha.22...v0.1.0-alpha.23](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.22...v0.1.0-alpha.23)
### Features
* **api:** api update ([d8c9fc9](https://github.com/sst/opencode-sdk-python/commit/d8c9fc984c48b7dadce8840c5c1e010a508d58b4))
## 0.1.0-alpha.22 (2025-07-17)
Full Changelog: [v0.1.0-alpha.21...v0.1.0-alpha.22](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.21...v0.1.0-alpha.22)
### Features
* **api:** api update ([582070a](https://github.com/sst/opencode-sdk-python/commit/582070ae69b0ae1088271038b0fcb818c30c74cf))
## 0.1.0-alpha.21 (2025-07-17)
Full Changelog: [v0.1.0-alpha.20...v0.1.0-alpha.21](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.20...v0.1.0-alpha.21)
### Features
* **api:** api update ([71211e8](https://github.com/sst/opencode-sdk-python/commit/71211e888ecd5e848ac4de5ed058e4756025f694))
## 0.1.0-alpha.20 (2025-07-17)
Full Changelog: [v0.1.0-alpha.19...v0.1.0-alpha.20](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.19...v0.1.0-alpha.20)
### Features
* **api:** api update ([f48c0d6](https://github.com/sst/opencode-sdk-python/commit/f48c0d6bb1943df3e3758d19b83c70fd1c15e2c2))
## 0.1.0-alpha.19 (2025-07-16)
Full Changelog: [v0.1.0-alpha.18...v0.1.0-alpha.19](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.18...v0.1.0-alpha.19)
### Features
* **api:** api update ([07b8550](https://github.com/sst/opencode-sdk-python/commit/07b8550e658373298ac5d64eed102f21d03a29fa))
## 0.1.0-alpha.18 (2025-07-16)
Full Changelog: [v0.1.0-alpha.17...v0.1.0-alpha.18](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.17...v0.1.0-alpha.18)
### Features
* **api:** api update ([02c3399](https://github.com/sst/opencode-sdk-python/commit/02c3399fb52fa96d50e6dd9c74f3106d1107308e))
## 0.1.0-alpha.17 (2025-07-16)
Full Changelog: [v0.1.0-alpha.16...v0.1.0-alpha.17](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.16...v0.1.0-alpha.17)
### Features
* **api:** api update ([e76b574](https://github.com/sst/opencode-sdk-python/commit/e76b57439c37c0d3514e1497a4d1a78279844bdc))
## 0.1.0-alpha.16 (2025-07-15)
Full Changelog: [v0.1.0-alpha.15...v0.1.0-alpha.16](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.15...v0.1.0-alpha.16)
### Features
* **api:** api update ([670fa88](https://github.com/sst/opencode-sdk-python/commit/670fa889512f9000e6fee8c9f5c2b49434224592))
## 0.1.0-alpha.15 (2025-07-15) ## 0.1.0-alpha.15 (2025-07-15)
Full Changelog: [v0.1.0-alpha.14...v0.1.0-alpha.15](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.14...v0.1.0-alpha.15) Full Changelog: [v0.1.0-alpha.14...v0.1.0-alpha.15](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.14...v0.1.0-alpha.15)

202
LICENSE
View file

@ -1,201 +1,7 @@
Apache License Copyright 2025 opencode
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
1. Definitions. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
"License" shall mean the terms and conditions for use, reproduction, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2025 Opencode
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -81,6 +81,32 @@ async def main() -> None:
asyncio.run(main()) asyncio.run(main())
``` ```
## Streaming responses
We provide support for streaming responses using Server Side Events (SSE).
```python
from opencode_ai import Opencode
client = Opencode()
stream = client.event.list()
for events in stream:
print(events)
```
The async client uses the exact same interface.
```python
from opencode_ai import AsyncOpencode
client = AsyncOpencode()
stream = await client.event.list()
async for events in stream:
print(events)
```
## Using types ## Using types
Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like: Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:

52
api.md
View file

@ -21,7 +21,16 @@ Methods:
Types: Types:
```python ```python
from opencode_ai.types import App, LogLevel, Mode, AppInitResponse, AppLogResponse, AppModesResponse from opencode_ai.types import (
App,
Mode,
Model,
Provider,
AppInitResponse,
AppLogResponse,
AppModesResponse,
AppProvidersResponse,
)
``` ```
Methods: Methods:
@ -30,19 +39,14 @@ Methods:
- <code title="post /app/init">client.app.<a href="./src/opencode_ai/resources/app.py">init</a>() -> <a href="./src/opencode_ai/types/app_init_response.py">AppInitResponse</a></code> - <code title="post /app/init">client.app.<a href="./src/opencode_ai/resources/app.py">init</a>() -> <a href="./src/opencode_ai/types/app_init_response.py">AppInitResponse</a></code>
- <code title="post /log">client.app.<a href="./src/opencode_ai/resources/app.py">log</a>(\*\*<a href="src/opencode_ai/types/app_log_params.py">params</a>) -> <a href="./src/opencode_ai/types/app_log_response.py">AppLogResponse</a></code> - <code title="post /log">client.app.<a href="./src/opencode_ai/resources/app.py">log</a>(\*\*<a href="src/opencode_ai/types/app_log_params.py">params</a>) -> <a href="./src/opencode_ai/types/app_log_response.py">AppLogResponse</a></code>
- <code title="get /mode">client.app.<a href="./src/opencode_ai/resources/app.py">modes</a>() -> <a href="./src/opencode_ai/types/app_modes_response.py">AppModesResponse</a></code> - <code title="get /mode">client.app.<a href="./src/opencode_ai/resources/app.py">modes</a>() -> <a href="./src/opencode_ai/types/app_modes_response.py">AppModesResponse</a></code>
- <code title="get /config/providers">client.app.<a href="./src/opencode_ai/resources/app.py">providers</a>() -> <a href="./src/opencode_ai/types/app_providers_response.py">AppProvidersResponse</a></code>
# Find # Find
Types: Types:
```python ```python
from opencode_ai.types import ( from opencode_ai.types import Symbol, FindFilesResponse, FindSymbolsResponse, FindTextResponse
Match,
Symbol,
FindFilesResponse,
FindSymbolsResponse,
FindTextResponse,
)
``` ```
Methods: Methods:
@ -69,21 +73,12 @@ Methods:
Types: Types:
```python ```python
from opencode_ai.types import ( from opencode_ai.types import Config, KeybindsConfig, McpLocalConfig, McpRemoteConfig, ModeConfig
Config,
Keybinds,
McpLocal,
McpRemote,
Model,
Provider,
ConfigProvidersResponse,
)
``` ```
Methods: Methods:
- <code title="get /config">client.config.<a href="./src/opencode_ai/resources/config.py">get</a>() -> <a href="./src/opencode_ai/types/config.py">Config</a></code> - <code title="get /config">client.config.<a href="./src/opencode_ai/resources/config.py">get</a>() -> <a href="./src/opencode_ai/types/config.py">Config</a></code>
- <code title="get /config/providers">client.config.<a href="./src/opencode_ai/resources/config.py">providers</a>() -> <a href="./src/opencode_ai/types/config_providers_response.py">ConfigProvidersResponse</a></code>
# Session # Session
@ -93,13 +88,19 @@ Types:
from opencode_ai.types import ( from opencode_ai.types import (
AssistantMessage, AssistantMessage,
FilePart, FilePart,
FilePartInput,
FilePartSource,
FilePartSourceText,
FileSource,
Message, Message,
Part, Part,
Session, Session,
SnapshotPart, SnapshotPart,
StepFinishPart, StepFinishPart,
StepStartPart, StepStartPart,
SymbolSource,
TextPart, TextPart,
TextPartInput,
ToolPart, ToolPart,
ToolStateCompleted, ToolStateCompleted,
ToolStateError, ToolStateError,
@ -124,6 +125,21 @@ Methods:
- <code title="post /session/{id}/message">client.session.<a href="./src/opencode_ai/resources/session.py">chat</a>(id, \*\*<a href="src/opencode_ai/types/session_chat_params.py">params</a>) -> <a href="./src/opencode_ai/types/assistant_message.py">AssistantMessage</a></code> - <code title="post /session/{id}/message">client.session.<a href="./src/opencode_ai/resources/session.py">chat</a>(id, \*\*<a href="src/opencode_ai/types/session_chat_params.py">params</a>) -> <a href="./src/opencode_ai/types/assistant_message.py">AssistantMessage</a></code>
- <code title="post /session/{id}/init">client.session.<a href="./src/opencode_ai/resources/session.py">init</a>(id, \*\*<a href="src/opencode_ai/types/session_init_params.py">params</a>) -> <a href="./src/opencode_ai/types/session_init_response.py">SessionInitResponse</a></code> - <code title="post /session/{id}/init">client.session.<a href="./src/opencode_ai/resources/session.py">init</a>(id, \*\*<a href="src/opencode_ai/types/session_init_params.py">params</a>) -> <a href="./src/opencode_ai/types/session_init_response.py">SessionInitResponse</a></code>
- <code title="get /session/{id}/message">client.session.<a href="./src/opencode_ai/resources/session.py">messages</a>(id) -> <a href="./src/opencode_ai/types/session_messages_response.py">SessionMessagesResponse</a></code> - <code title="get /session/{id}/message">client.session.<a href="./src/opencode_ai/resources/session.py">messages</a>(id) -> <a href="./src/opencode_ai/types/session_messages_response.py">SessionMessagesResponse</a></code>
- <code title="post /session/{id}/revert">client.session.<a href="./src/opencode_ai/resources/session.py">revert</a>(id, \*\*<a href="src/opencode_ai/types/session_revert_params.py">params</a>) -> <a href="./src/opencode_ai/types/session.py">Session</a></code>
- <code title="post /session/{id}/share">client.session.<a href="./src/opencode_ai/resources/session.py">share</a>(id) -> <a href="./src/opencode_ai/types/session.py">Session</a></code> - <code title="post /session/{id}/share">client.session.<a href="./src/opencode_ai/resources/session.py">share</a>(id) -> <a href="./src/opencode_ai/types/session.py">Session</a></code>
- <code title="post /session/{id}/summarize">client.session.<a href="./src/opencode_ai/resources/session.py">summarize</a>(id, \*\*<a href="src/opencode_ai/types/session_summarize_params.py">params</a>) -> <a href="./src/opencode_ai/types/session_summarize_response.py">SessionSummarizeResponse</a></code> - <code title="post /session/{id}/summarize">client.session.<a href="./src/opencode_ai/resources/session.py">summarize</a>(id, \*\*<a href="src/opencode_ai/types/session_summarize_params.py">params</a>) -> <a href="./src/opencode_ai/types/session_summarize_response.py">SessionSummarizeResponse</a></code>
- <code title="post /session/{id}/unrevert">client.session.<a href="./src/opencode_ai/resources/session.py">unrevert</a>(id) -> <a href="./src/opencode_ai/types/session.py">Session</a></code>
- <code title="delete /session/{id}/share">client.session.<a href="./src/opencode_ai/resources/session.py">unshare</a>(id) -> <a href="./src/opencode_ai/types/session.py">Session</a></code> - <code title="delete /session/{id}/share">client.session.<a href="./src/opencode_ai/resources/session.py">unshare</a>(id) -> <a href="./src/opencode_ai/types/session.py">Session</a></code>
# Tui
Types:
```python
from opencode_ai.types import TuiAppendPromptResponse, TuiOpenHelpResponse
```
Methods:
- <code title="post /tui/append-prompt">client.tui.<a href="./src/opencode_ai/resources/tui.py">append_prompt</a>(\*\*<a href="src/opencode_ai/types/tui_append_prompt_params.py">params</a>) -> <a href="./src/opencode_ai/types/tui_append_prompt_response.py">TuiAppendPromptResponse</a></code>
- <code title="post /tui/open-help">client.tui.<a href="./src/opencode_ai/resources/tui.py">open_help</a>() -> <a href="./src/opencode_ai/types/tui_open_help_response.py">TuiOpenHelpResponse</a></code>

View file

@ -1,9 +1,9 @@
[project] [project]
name = "opencode-ai" name = "opencode-ai"
version = "0.1.0-alpha.15" version = "0.1.0-alpha.36"
description = "The official Python library for the opencode API" description = "The official Python library for the opencode API"
dynamic = ["readme"] dynamic = ["readme"]
license = "Apache-2.0" license = "MIT"
authors = [ authors = [
{ name = "Opencode", email = "support@sst.dev" }, { name = "Opencode", email = "support@sst.dev" },
] ]
@ -31,7 +31,7 @@ classifiers = [
"Operating System :: POSIX :: Linux", "Operating System :: POSIX :: Linux",
"Operating System :: Microsoft :: Windows", "Operating System :: Microsoft :: Windows",
"Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Libraries :: Python Modules",
"License :: OSI Approved :: Apache Software License" "License :: OSI Approved :: MIT License"
] ]
[project.urls] [project.urls]
@ -148,6 +148,7 @@ exclude = [
"_dev", "_dev",
".venv", ".venv",
".nox", ".nox",
".git",
] ]
reportImplicitOverride = true reportImplicitOverride = true
@ -159,7 +160,7 @@ reportPrivateUsage = false
[tool.ruff] [tool.ruff]
line-length = 120 line-length = 120
output-format = "grouped" output-format = "grouped"
target-version = "py37" target-version = "py38"
[tool.ruff.format] [tool.ruff.format]
docstring-code-format = true docstring-code-format = true

View file

@ -21,7 +21,7 @@ echo "==> Starting mock server with URL ${URL}"
# Run prism mock on the given spec # Run prism mock on the given spec
if [ "$1" == "--daemon" ]; then if [ "$1" == "--daemon" ]; then
npm exec --package=@stainless-api/prism-cli@5.8.5 -- prism mock "$URL" &> .prism.log & npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
# Wait for server to come online # Wait for server to come online
echo -n "Waiting for server" echo -n "Waiting for server"
@ -37,5 +37,5 @@ if [ "$1" == "--daemon" ]; then
echo echo
else else
npm exec --package=@stainless-api/prism-cli@5.8.5 -- prism mock "$URL" npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL"
fi fi

View file

@ -43,7 +43,7 @@ elif ! prism_is_running ; then
echo -e "To run the server, pass in the path or url of your OpenAPI" echo -e "To run the server, pass in the path or url of your OpenAPI"
echo -e "spec to the prism command:" echo -e "spec to the prism command:"
echo echo
echo -e " \$ ${YELLOW}npm exec --package=@stoplight/prism-cli@~5.3.2 -- prism mock path/to/your.openapi.yml${NC}" echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}"
echo echo
exit 1 exit 1

View file

@ -532,7 +532,10 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
is_body_allowed = options.method.lower() != "get" is_body_allowed = options.method.lower() != "get"
if is_body_allowed: if is_body_allowed:
kwargs["json"] = json_data if is_given(json_data) else None if isinstance(json_data, bytes):
kwargs["content"] = json_data
else:
kwargs["json"] = json_data if is_given(json_data) else None
kwargs["files"] = files kwargs["files"] = files
else: else:
headers.pop("Content-Type", None) headers.pop("Content-Type", None)

View file

@ -21,7 +21,7 @@ from ._types import (
) )
from ._utils import is_given, get_async_library from ._utils import is_given, get_async_library
from ._version import __version__ from ._version import __version__
from .resources import app, file, find, event, config, session from .resources import app, tui, file, find, event, config, session
from ._streaming import Stream as Stream, AsyncStream as AsyncStream from ._streaming import Stream as Stream, AsyncStream as AsyncStream
from ._exceptions import APIStatusError from ._exceptions import APIStatusError
from ._base_client import ( from ._base_client import (
@ -49,6 +49,7 @@ class Opencode(SyncAPIClient):
file: file.FileResource file: file.FileResource
config: config.ConfigResource config: config.ConfigResource
session: session.SessionResource session: session.SessionResource
tui: tui.TuiResource
with_raw_response: OpencodeWithRawResponse with_raw_response: OpencodeWithRawResponse
with_streaming_response: OpencodeWithStreamedResponse with_streaming_response: OpencodeWithStreamedResponse
@ -101,6 +102,7 @@ class Opencode(SyncAPIClient):
self.file = file.FileResource(self) self.file = file.FileResource(self)
self.config = config.ConfigResource(self) self.config = config.ConfigResource(self)
self.session = session.SessionResource(self) self.session = session.SessionResource(self)
self.tui = tui.TuiResource(self)
self.with_raw_response = OpencodeWithRawResponse(self) self.with_raw_response = OpencodeWithRawResponse(self)
self.with_streaming_response = OpencodeWithStreamedResponse(self) self.with_streaming_response = OpencodeWithStreamedResponse(self)
@ -208,6 +210,7 @@ class AsyncOpencode(AsyncAPIClient):
file: file.AsyncFileResource file: file.AsyncFileResource
config: config.AsyncConfigResource config: config.AsyncConfigResource
session: session.AsyncSessionResource session: session.AsyncSessionResource
tui: tui.AsyncTuiResource
with_raw_response: AsyncOpencodeWithRawResponse with_raw_response: AsyncOpencodeWithRawResponse
with_streaming_response: AsyncOpencodeWithStreamedResponse with_streaming_response: AsyncOpencodeWithStreamedResponse
@ -260,6 +263,7 @@ class AsyncOpencode(AsyncAPIClient):
self.file = file.AsyncFileResource(self) self.file = file.AsyncFileResource(self)
self.config = config.AsyncConfigResource(self) self.config = config.AsyncConfigResource(self)
self.session = session.AsyncSessionResource(self) self.session = session.AsyncSessionResource(self)
self.tui = tui.AsyncTuiResource(self)
self.with_raw_response = AsyncOpencodeWithRawResponse(self) self.with_raw_response = AsyncOpencodeWithRawResponse(self)
self.with_streaming_response = AsyncOpencodeWithStreamedResponse(self) self.with_streaming_response = AsyncOpencodeWithStreamedResponse(self)
@ -368,6 +372,7 @@ class OpencodeWithRawResponse:
self.file = file.FileResourceWithRawResponse(client.file) self.file = file.FileResourceWithRawResponse(client.file)
self.config = config.ConfigResourceWithRawResponse(client.config) self.config = config.ConfigResourceWithRawResponse(client.config)
self.session = session.SessionResourceWithRawResponse(client.session) self.session = session.SessionResourceWithRawResponse(client.session)
self.tui = tui.TuiResourceWithRawResponse(client.tui)
class AsyncOpencodeWithRawResponse: class AsyncOpencodeWithRawResponse:
@ -378,6 +383,7 @@ class AsyncOpencodeWithRawResponse:
self.file = file.AsyncFileResourceWithRawResponse(client.file) self.file = file.AsyncFileResourceWithRawResponse(client.file)
self.config = config.AsyncConfigResourceWithRawResponse(client.config) self.config = config.AsyncConfigResourceWithRawResponse(client.config)
self.session = session.AsyncSessionResourceWithRawResponse(client.session) self.session = session.AsyncSessionResourceWithRawResponse(client.session)
self.tui = tui.AsyncTuiResourceWithRawResponse(client.tui)
class OpencodeWithStreamedResponse: class OpencodeWithStreamedResponse:
@ -388,6 +394,7 @@ class OpencodeWithStreamedResponse:
self.file = file.FileResourceWithStreamingResponse(client.file) self.file = file.FileResourceWithStreamingResponse(client.file)
self.config = config.ConfigResourceWithStreamingResponse(client.config) self.config = config.ConfigResourceWithStreamingResponse(client.config)
self.session = session.SessionResourceWithStreamingResponse(client.session) self.session = session.SessionResourceWithStreamingResponse(client.session)
self.tui = tui.TuiResourceWithStreamingResponse(client.tui)
class AsyncOpencodeWithStreamedResponse: class AsyncOpencodeWithStreamedResponse:
@ -398,6 +405,7 @@ class AsyncOpencodeWithStreamedResponse:
self.file = file.AsyncFileResourceWithStreamingResponse(client.file) self.file = file.AsyncFileResourceWithStreamingResponse(client.file)
self.config = config.AsyncConfigResourceWithStreamingResponse(client.config) self.config = config.AsyncConfigResourceWithStreamingResponse(client.config)
self.session = session.AsyncSessionResourceWithStreamingResponse(client.session) self.session = session.AsyncSessionResourceWithStreamingResponse(client.session)
self.tui = tui.AsyncTuiResourceWithStreamingResponse(client.tui)
Client = Opencode Client = Opencode

View file

@ -69,12 +69,12 @@ def _transform_file(file: FileTypes) -> HttpxFileTypes:
return file return file
if is_tuple_t(file): if is_tuple_t(file):
return (file[0], _read_file_content(file[1]), *file[2:]) return (file[0], read_file_content(file[1]), *file[2:])
raise TypeError(f"Expected file types input to be a FileContent type or to be a tuple") raise TypeError(f"Expected file types input to be a FileContent type or to be a tuple")
def _read_file_content(file: FileContent) -> HttpxFileContent: def read_file_content(file: FileContent) -> HttpxFileContent:
if isinstance(file, os.PathLike): if isinstance(file, os.PathLike):
return pathlib.Path(file).read_bytes() return pathlib.Path(file).read_bytes()
return file return file
@ -111,12 +111,12 @@ async def _async_transform_file(file: FileTypes) -> HttpxFileTypes:
return file return file
if is_tuple_t(file): if is_tuple_t(file):
return (file[0], await _async_read_file_content(file[1]), *file[2:]) return (file[0], await async_read_file_content(file[1]), *file[2:])
raise TypeError(f"Expected file types input to be a FileContent type or to be a tuple") raise TypeError(f"Expected file types input to be a FileContent type or to be a tuple")
async def _async_read_file_content(file: FileContent) -> HttpxFileContent: async def async_read_file_content(file: FileContent) -> HttpxFileContent:
if isinstance(file, os.PathLike): if isinstance(file, os.PathLike):
return await anyio.Path(file).read_bytes() return await anyio.Path(file).read_bytes()

View file

@ -208,14 +208,18 @@ class BaseModel(pydantic.BaseModel):
else: else:
fields_values[name] = field_get_default(field) fields_values[name] = field_get_default(field)
extra_field_type = _get_extra_fields_type(__cls)
_extra = {} _extra = {}
for key, value in values.items(): for key, value in values.items():
if key not in model_fields: if key not in model_fields:
parsed = construct_type(value=value, type_=extra_field_type) if extra_field_type is not None else value
if PYDANTIC_V2: if PYDANTIC_V2:
_extra[key] = value _extra[key] = parsed
else: else:
_fields_set.add(key) _fields_set.add(key)
fields_values[key] = value fields_values[key] = parsed
object.__setattr__(m, "__dict__", fields_values) object.__setattr__(m, "__dict__", fields_values)
@ -300,7 +304,7 @@ class BaseModel(pydantic.BaseModel):
exclude_none=exclude_none, exclude_none=exclude_none,
) )
return cast(dict[str, Any], json_safe(dumped)) if mode == "json" else dumped return cast("dict[str, Any]", json_safe(dumped)) if mode == "json" else dumped
@override @override
def model_dump_json( def model_dump_json(
@ -370,6 +374,23 @@ def _construct_field(value: object, field: FieldInfo, key: str) -> object:
return construct_type(value=value, type_=type_, metadata=getattr(field, "metadata", None)) return construct_type(value=value, type_=type_, metadata=getattr(field, "metadata", None))
def _get_extra_fields_type(cls: type[pydantic.BaseModel]) -> type | None:
if not PYDANTIC_V2:
# TODO
return None
schema = cls.__pydantic_core_schema__
if schema["type"] == "model":
fields = schema["schema"]
if fields["type"] == "model-fields":
extras = fields.get("extras_schema")
if extras and "cls" in extras:
# mypy can't narrow the type
return extras["cls"] # type: ignore[no-any-return]
return None
def is_basemodel(type_: type) -> bool: def is_basemodel(type_: type) -> bool:
"""Returns whether or not the given type is either a `BaseModel` or a union of `BaseModel`""" """Returns whether or not the given type is either a `BaseModel` or a union of `BaseModel`"""
if is_union(type_): if is_union(type_):
@ -439,7 +460,7 @@ def construct_type(*, value: object, type_: object, metadata: Optional[List[Any]
type_ = type_.__value__ # type: ignore[unreachable] type_ = type_.__value__ # type: ignore[unreachable]
# unwrap `Annotated[T, ...]` -> `T` # unwrap `Annotated[T, ...]` -> `T`
if metadata is not None: if metadata is not None and len(metadata) > 0:
meta: tuple[Any, ...] = tuple(metadata) meta: tuple[Any, ...] = tuple(metadata)
elif is_annotated_type(type_): elif is_annotated_type(type_):
meta = get_args(type_)[1:] meta = get_args(type_)[1:]

View file

@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "opencode_ai" __title__ = "opencode_ai"
__version__ = "0.1.0-alpha.15" # x-release-please-version __version__ = "0.1.0-alpha.36" # x-release-please-version

View file

@ -8,6 +8,14 @@ from .app import (
AppResourceWithStreamingResponse, AppResourceWithStreamingResponse,
AsyncAppResourceWithStreamingResponse, AsyncAppResourceWithStreamingResponse,
) )
from .tui import (
TuiResource,
AsyncTuiResource,
TuiResourceWithRawResponse,
AsyncTuiResourceWithRawResponse,
TuiResourceWithStreamingResponse,
AsyncTuiResourceWithStreamingResponse,
)
from .file import ( from .file import (
FileResource, FileResource,
AsyncFileResource, AsyncFileResource,
@ -86,4 +94,10 @@ __all__ = [
"AsyncSessionResourceWithRawResponse", "AsyncSessionResourceWithRawResponse",
"SessionResourceWithStreamingResponse", "SessionResourceWithStreamingResponse",
"AsyncSessionResourceWithStreamingResponse", "AsyncSessionResourceWithStreamingResponse",
"TuiResource",
"AsyncTuiResource",
"TuiResourceWithRawResponse",
"AsyncTuiResourceWithRawResponse",
"TuiResourceWithStreamingResponse",
"AsyncTuiResourceWithStreamingResponse",
] ]

View file

@ -23,6 +23,7 @@ from .._base_client import make_request_options
from ..types.app_log_response import AppLogResponse from ..types.app_log_response import AppLogResponse
from ..types.app_init_response import AppInitResponse from ..types.app_init_response import AppInitResponse
from ..types.app_modes_response import AppModesResponse from ..types.app_modes_response import AppModesResponse
from ..types.app_providers_response import AppProvidersResponse
__all__ = ["AppResource", "AsyncAppResource"] __all__ = ["AppResource", "AsyncAppResource"]
@ -155,6 +156,25 @@ class AppResource(SyncAPIResource):
cast_to=AppModesResponse, cast_to=AppModesResponse,
) )
def providers(
self,
*,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AppProvidersResponse:
"""List all providers"""
return self._get(
"/config/providers",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=AppProvidersResponse,
)
class AsyncAppResource(AsyncAPIResource): class AsyncAppResource(AsyncAPIResource):
@cached_property @cached_property
@ -284,6 +304,25 @@ class AsyncAppResource(AsyncAPIResource):
cast_to=AppModesResponse, cast_to=AppModesResponse,
) )
async def providers(
self,
*,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AppProvidersResponse:
"""List all providers"""
return await self._get(
"/config/providers",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=AppProvidersResponse,
)
class AppResourceWithRawResponse: class AppResourceWithRawResponse:
def __init__(self, app: AppResource) -> None: def __init__(self, app: AppResource) -> None:
@ -301,6 +340,9 @@ class AppResourceWithRawResponse:
self.modes = to_raw_response_wrapper( self.modes = to_raw_response_wrapper(
app.modes, app.modes,
) )
self.providers = to_raw_response_wrapper(
app.providers,
)
class AsyncAppResourceWithRawResponse: class AsyncAppResourceWithRawResponse:
@ -319,6 +361,9 @@ class AsyncAppResourceWithRawResponse:
self.modes = async_to_raw_response_wrapper( self.modes = async_to_raw_response_wrapper(
app.modes, app.modes,
) )
self.providers = async_to_raw_response_wrapper(
app.providers,
)
class AppResourceWithStreamingResponse: class AppResourceWithStreamingResponse:
@ -337,6 +382,9 @@ class AppResourceWithStreamingResponse:
self.modes = to_streamed_response_wrapper( self.modes = to_streamed_response_wrapper(
app.modes, app.modes,
) )
self.providers = to_streamed_response_wrapper(
app.providers,
)
class AsyncAppResourceWithStreamingResponse: class AsyncAppResourceWithStreamingResponse:
@ -355,3 +403,6 @@ class AsyncAppResourceWithStreamingResponse:
self.modes = async_to_streamed_response_wrapper( self.modes = async_to_streamed_response_wrapper(
app.modes, app.modes,
) )
self.providers = async_to_streamed_response_wrapper(
app.providers,
)

View file

@ -15,7 +15,6 @@ from .._response import (
) )
from .._base_client import make_request_options from .._base_client import make_request_options
from ..types.config import Config from ..types.config import Config
from ..types.config_providers_response import ConfigProvidersResponse
__all__ = ["ConfigResource", "AsyncConfigResource"] __all__ = ["ConfigResource", "AsyncConfigResource"]
@ -59,25 +58,6 @@ class ConfigResource(SyncAPIResource):
cast_to=Config, cast_to=Config,
) )
def providers(
self,
*,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> ConfigProvidersResponse:
"""List all providers"""
return self._get(
"/config/providers",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ConfigProvidersResponse,
)
class AsyncConfigResource(AsyncAPIResource): class AsyncConfigResource(AsyncAPIResource):
@cached_property @cached_property
@ -118,25 +98,6 @@ class AsyncConfigResource(AsyncAPIResource):
cast_to=Config, cast_to=Config,
) )
async def providers(
self,
*,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> ConfigProvidersResponse:
"""List all providers"""
return await self._get(
"/config/providers",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ConfigProvidersResponse,
)
class ConfigResourceWithRawResponse: class ConfigResourceWithRawResponse:
def __init__(self, config: ConfigResource) -> None: def __init__(self, config: ConfigResource) -> None:
@ -145,9 +106,6 @@ class ConfigResourceWithRawResponse:
self.get = to_raw_response_wrapper( self.get = to_raw_response_wrapper(
config.get, config.get,
) )
self.providers = to_raw_response_wrapper(
config.providers,
)
class AsyncConfigResourceWithRawResponse: class AsyncConfigResourceWithRawResponse:
@ -157,9 +115,6 @@ class AsyncConfigResourceWithRawResponse:
self.get = async_to_raw_response_wrapper( self.get = async_to_raw_response_wrapper(
config.get, config.get,
) )
self.providers = async_to_raw_response_wrapper(
config.providers,
)
class ConfigResourceWithStreamingResponse: class ConfigResourceWithStreamingResponse:
@ -169,9 +124,6 @@ class ConfigResourceWithStreamingResponse:
self.get = to_streamed_response_wrapper( self.get = to_streamed_response_wrapper(
config.get, config.get,
) )
self.providers = to_streamed_response_wrapper(
config.providers,
)
class AsyncConfigResourceWithStreamingResponse: class AsyncConfigResourceWithStreamingResponse:
@ -181,6 +133,3 @@ class AsyncConfigResourceWithStreamingResponse:
self.get = async_to_streamed_response_wrapper( self.get = async_to_streamed_response_wrapper(
config.get, config.get,
) )
self.providers = async_to_streamed_response_wrapper(
config.providers,
)

View file

@ -2,11 +2,11 @@
from __future__ import annotations from __future__ import annotations
from typing import Iterable from typing import Dict, Iterable
import httpx import httpx
from ..types import session_chat_params, session_init_params, session_summarize_params from ..types import session_chat_params, session_init_params, session_revert_params, session_summarize_params
from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
from .._utils import maybe_transform, async_maybe_transform from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property from .._compat import cached_property
@ -158,11 +158,13 @@ class SessionResource(SyncAPIResource):
self, self,
id: str, id: str,
*, *,
message_id: str,
mode: str,
model_id: str, model_id: str,
parts: Iterable[session_chat_params.Part], parts: Iterable[session_chat_params.Part],
provider_id: str, provider_id: str,
message_id: str | NotGiven = NOT_GIVEN,
mode: str | NotGiven = NOT_GIVEN,
system: str | NotGiven = NOT_GIVEN,
tools: Dict[str, bool] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method. # The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None, extra_headers: Headers | None = None,
@ -190,11 +192,13 @@ class SessionResource(SyncAPIResource):
f"/session/{id}/message", f"/session/{id}/message",
body=maybe_transform( body=maybe_transform(
{ {
"message_id": message_id,
"mode": mode,
"model_id": model_id, "model_id": model_id,
"parts": parts, "parts": parts,
"provider_id": provider_id, "provider_id": provider_id,
"message_id": message_id,
"mode": mode,
"system": system,
"tools": tools,
}, },
session_chat_params.SessionChatParams, session_chat_params.SessionChatParams,
), ),
@ -285,6 +289,48 @@ class SessionResource(SyncAPIResource):
cast_to=SessionMessagesResponse, cast_to=SessionMessagesResponse,
) )
def revert(
self,
id: str,
*,
message_id: str,
part_id: str | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> Session:
"""
Revert a message
Args:
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
extra_body: Add additional JSON properties to the request
timeout: Override the client-level default timeout for this request, in seconds
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
f"/session/{id}/revert",
body=maybe_transform(
{
"message_id": message_id,
"part_id": part_id,
},
session_revert_params.SessionRevertParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=Session,
)
def share( def share(
self, self,
id: str, id: str,
@ -362,6 +408,39 @@ class SessionResource(SyncAPIResource):
cast_to=SessionSummarizeResponse, cast_to=SessionSummarizeResponse,
) )
def unrevert(
self,
id: str,
*,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> Session:
"""
Restore all reverted messages
Args:
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
extra_body: Add additional JSON properties to the request
timeout: Override the client-level default timeout for this request, in seconds
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
f"/session/{id}/unrevert",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=Session,
)
def unshare( def unshare(
self, self,
id: str, id: str,
@ -524,11 +603,13 @@ class AsyncSessionResource(AsyncAPIResource):
self, self,
id: str, id: str,
*, *,
message_id: str,
mode: str,
model_id: str, model_id: str,
parts: Iterable[session_chat_params.Part], parts: Iterable[session_chat_params.Part],
provider_id: str, provider_id: str,
message_id: str | NotGiven = NOT_GIVEN,
mode: str | NotGiven = NOT_GIVEN,
system: str | NotGiven = NOT_GIVEN,
tools: Dict[str, bool] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method. # The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None, extra_headers: Headers | None = None,
@ -556,11 +637,13 @@ class AsyncSessionResource(AsyncAPIResource):
f"/session/{id}/message", f"/session/{id}/message",
body=await async_maybe_transform( body=await async_maybe_transform(
{ {
"message_id": message_id,
"mode": mode,
"model_id": model_id, "model_id": model_id,
"parts": parts, "parts": parts,
"provider_id": provider_id, "provider_id": provider_id,
"message_id": message_id,
"mode": mode,
"system": system,
"tools": tools,
}, },
session_chat_params.SessionChatParams, session_chat_params.SessionChatParams,
), ),
@ -651,6 +734,48 @@ class AsyncSessionResource(AsyncAPIResource):
cast_to=SessionMessagesResponse, cast_to=SessionMessagesResponse,
) )
async def revert(
self,
id: str,
*,
message_id: str,
part_id: str | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> Session:
"""
Revert a message
Args:
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
extra_body: Add additional JSON properties to the request
timeout: Override the client-level default timeout for this request, in seconds
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
f"/session/{id}/revert",
body=await async_maybe_transform(
{
"message_id": message_id,
"part_id": part_id,
},
session_revert_params.SessionRevertParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=Session,
)
async def share( async def share(
self, self,
id: str, id: str,
@ -728,6 +853,39 @@ class AsyncSessionResource(AsyncAPIResource):
cast_to=SessionSummarizeResponse, cast_to=SessionSummarizeResponse,
) )
async def unrevert(
self,
id: str,
*,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> Session:
"""
Restore all reverted messages
Args:
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
extra_body: Add additional JSON properties to the request
timeout: Override the client-level default timeout for this request, in seconds
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
f"/session/{id}/unrevert",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=Session,
)
async def unshare( async def unshare(
self, self,
id: str, id: str,
@ -787,12 +945,18 @@ class SessionResourceWithRawResponse:
self.messages = to_raw_response_wrapper( self.messages = to_raw_response_wrapper(
session.messages, session.messages,
) )
self.revert = to_raw_response_wrapper(
session.revert,
)
self.share = to_raw_response_wrapper( self.share = to_raw_response_wrapper(
session.share, session.share,
) )
self.summarize = to_raw_response_wrapper( self.summarize = to_raw_response_wrapper(
session.summarize, session.summarize,
) )
self.unrevert = to_raw_response_wrapper(
session.unrevert,
)
self.unshare = to_raw_response_wrapper( self.unshare = to_raw_response_wrapper(
session.unshare, session.unshare,
) )
@ -823,12 +987,18 @@ class AsyncSessionResourceWithRawResponse:
self.messages = async_to_raw_response_wrapper( self.messages = async_to_raw_response_wrapper(
session.messages, session.messages,
) )
self.revert = async_to_raw_response_wrapper(
session.revert,
)
self.share = async_to_raw_response_wrapper( self.share = async_to_raw_response_wrapper(
session.share, session.share,
) )
self.summarize = async_to_raw_response_wrapper( self.summarize = async_to_raw_response_wrapper(
session.summarize, session.summarize,
) )
self.unrevert = async_to_raw_response_wrapper(
session.unrevert,
)
self.unshare = async_to_raw_response_wrapper( self.unshare = async_to_raw_response_wrapper(
session.unshare, session.unshare,
) )
@ -859,12 +1029,18 @@ class SessionResourceWithStreamingResponse:
self.messages = to_streamed_response_wrapper( self.messages = to_streamed_response_wrapper(
session.messages, session.messages,
) )
self.revert = to_streamed_response_wrapper(
session.revert,
)
self.share = to_streamed_response_wrapper( self.share = to_streamed_response_wrapper(
session.share, session.share,
) )
self.summarize = to_streamed_response_wrapper( self.summarize = to_streamed_response_wrapper(
session.summarize, session.summarize,
) )
self.unrevert = to_streamed_response_wrapper(
session.unrevert,
)
self.unshare = to_streamed_response_wrapper( self.unshare = to_streamed_response_wrapper(
session.unshare, session.unshare,
) )
@ -895,12 +1071,18 @@ class AsyncSessionResourceWithStreamingResponse:
self.messages = async_to_streamed_response_wrapper( self.messages = async_to_streamed_response_wrapper(
session.messages, session.messages,
) )
self.revert = async_to_streamed_response_wrapper(
session.revert,
)
self.share = async_to_streamed_response_wrapper( self.share = async_to_streamed_response_wrapper(
session.share, session.share,
) )
self.summarize = async_to_streamed_response_wrapper( self.summarize = async_to_streamed_response_wrapper(
session.summarize, session.summarize,
) )
self.unrevert = async_to_streamed_response_wrapper(
session.unrevert,
)
self.unshare = async_to_streamed_response_wrapper( self.unshare = async_to_streamed_response_wrapper(
session.unshare, session.unshare,
) )

View file

@ -0,0 +1,214 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
import httpx
from ..types import tui_append_prompt_params
from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
from .._base_client import make_request_options
from ..types.tui_open_help_response import TuiOpenHelpResponse
from ..types.tui_append_prompt_response import TuiAppendPromptResponse
__all__ = ["TuiResource", "AsyncTuiResource"]
class TuiResource(SyncAPIResource):
@cached_property
def with_raw_response(self) -> TuiResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/sst/opencode-sdk-python#accessing-raw-response-data-eg-headers
"""
return TuiResourceWithRawResponse(self)
@cached_property
def with_streaming_response(self) -> TuiResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/sst/opencode-sdk-python#with_streaming_response
"""
return TuiResourceWithStreamingResponse(self)
def append_prompt(
self,
*,
text: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TuiAppendPromptResponse:
"""
Append prompt to the TUI
Args:
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
extra_body: Add additional JSON properties to the request
timeout: Override the client-level default timeout for this request, in seconds
"""
return self._post(
"/tui/append-prompt",
body=maybe_transform({"text": text}, tui_append_prompt_params.TuiAppendPromptParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=TuiAppendPromptResponse,
)
def open_help(
self,
*,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TuiOpenHelpResponse:
"""Open the help dialog"""
return self._post(
"/tui/open-help",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=TuiOpenHelpResponse,
)
class AsyncTuiResource(AsyncAPIResource):
@cached_property
def with_raw_response(self) -> AsyncTuiResourceWithRawResponse:
"""
This property can be used as a prefix for any HTTP method call to return
the raw response object instead of the parsed content.
For more information, see https://www.github.com/sst/opencode-sdk-python#accessing-raw-response-data-eg-headers
"""
return AsyncTuiResourceWithRawResponse(self)
@cached_property
def with_streaming_response(self) -> AsyncTuiResourceWithStreamingResponse:
"""
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
For more information, see https://www.github.com/sst/opencode-sdk-python#with_streaming_response
"""
return AsyncTuiResourceWithStreamingResponse(self)
async def append_prompt(
self,
*,
text: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TuiAppendPromptResponse:
"""
Append prompt to the TUI
Args:
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
extra_body: Add additional JSON properties to the request
timeout: Override the client-level default timeout for this request, in seconds
"""
return await self._post(
"/tui/append-prompt",
body=await async_maybe_transform({"text": text}, tui_append_prompt_params.TuiAppendPromptParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=TuiAppendPromptResponse,
)
async def open_help(
self,
*,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TuiOpenHelpResponse:
"""Open the help dialog"""
return await self._post(
"/tui/open-help",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=TuiOpenHelpResponse,
)
class TuiResourceWithRawResponse:
def __init__(self, tui: TuiResource) -> None:
self._tui = tui
self.append_prompt = to_raw_response_wrapper(
tui.append_prompt,
)
self.open_help = to_raw_response_wrapper(
tui.open_help,
)
class AsyncTuiResourceWithRawResponse:
def __init__(self, tui: AsyncTuiResource) -> None:
self._tui = tui
self.append_prompt = async_to_raw_response_wrapper(
tui.append_prompt,
)
self.open_help = async_to_raw_response_wrapper(
tui.open_help,
)
class TuiResourceWithStreamingResponse:
def __init__(self, tui: TuiResource) -> None:
self._tui = tui
self.append_prompt = to_streamed_response_wrapper(
tui.append_prompt,
)
self.open_help = to_streamed_response_wrapper(
tui.open_help,
)
class AsyncTuiResourceWithStreamingResponse:
def __init__(self, tui: AsyncTuiResource) -> None:
self._tui = tui
self.append_prompt = async_to_streamed_response_wrapper(
tui.append_prompt,
)
self.open_help = async_to_streamed_response_wrapper(
tui.open_help,
)

View file

@ -6,7 +6,6 @@ from .app import App as App
from .file import File as File from .file import File as File
from .mode import Mode as Mode from .mode import Mode as Mode
from .part import Part as Part from .part import Part as Part
from .match import Match as Match
from .model import Model as Model from .model import Model as Model
from .config import Config as Config from .config import Config as Config
from .shared import ( from .shared import (
@ -17,28 +16,30 @@ from .shared import (
from .symbol import Symbol as Symbol from .symbol import Symbol as Symbol
from .message import Message as Message from .message import Message as Message
from .session import Session as Session from .session import Session as Session
from .keybinds import Keybinds as Keybinds
from .provider import Provider as Provider from .provider import Provider as Provider
from .file_part import FilePart as FilePart from .file_part import FilePart as FilePart
from .log_level import LogLevel as LogLevel
from .mcp_local import McpLocal as McpLocal
from .text_part import TextPart as TextPart from .text_part import TextPart as TextPart
from .tool_part import ToolPart as ToolPart from .tool_part import ToolPart as ToolPart
from .mcp_remote import McpRemote as McpRemote from .file_source import FileSource as FileSource
from .mode_config import ModeConfig as ModeConfig
from .user_message import UserMessage as UserMessage from .user_message import UserMessage as UserMessage
from .snapshot_part import SnapshotPart as SnapshotPart from .snapshot_part import SnapshotPart as SnapshotPart
from .symbol_source import SymbolSource as SymbolSource
from .app_log_params import AppLogParams as AppLogParams from .app_log_params import AppLogParams as AppLogParams
from .file_part_param import FilePartParam as FilePartParam from .keybinds_config import KeybindsConfig as KeybindsConfig
from .step_start_part import StepStartPart as StepStartPart from .step_start_part import StepStartPart as StepStartPart
from .text_part_param import TextPartParam as TextPartParam
from .app_log_response import AppLogResponse as AppLogResponse from .app_log_response import AppLogResponse as AppLogResponse
from .file_part_source import FilePartSource as FilePartSource
from .file_read_params import FileReadParams as FileReadParams from .file_read_params import FileReadParams as FileReadParams
from .find_text_params import FindTextParams as FindTextParams from .find_text_params import FindTextParams as FindTextParams
from .mcp_local_config import McpLocalConfig as McpLocalConfig
from .step_finish_part import StepFinishPart as StepFinishPart from .step_finish_part import StepFinishPart as StepFinishPart
from .tool_state_error import ToolStateError as ToolStateError from .tool_state_error import ToolStateError as ToolStateError
from .app_init_response import AppInitResponse as AppInitResponse from .app_init_response import AppInitResponse as AppInitResponse
from .assistant_message import AssistantMessage as AssistantMessage from .assistant_message import AssistantMessage as AssistantMessage
from .file_source_param import FileSourceParam as FileSourceParam
from .find_files_params import FindFilesParams as FindFilesParams from .find_files_params import FindFilesParams as FindFilesParams
from .mcp_remote_config import McpRemoteConfig as McpRemoteConfig
from .app_modes_response import AppModesResponse as AppModesResponse from .app_modes_response import AppModesResponse as AppModesResponse
from .file_read_response import FileReadResponse as FileReadResponse from .file_read_response import FileReadResponse as FileReadResponse
from .find_text_response import FindTextResponse as FindTextResponse from .find_text_response import FindTextResponse as FindTextResponse
@ -49,14 +50,24 @@ from .find_files_response import FindFilesResponse as FindFilesResponse
from .find_symbols_params import FindSymbolsParams as FindSymbolsParams from .find_symbols_params import FindSymbolsParams as FindSymbolsParams
from .session_chat_params import SessionChatParams as SessionChatParams from .session_chat_params import SessionChatParams as SessionChatParams
from .session_init_params import SessionInitParams as SessionInitParams from .session_init_params import SessionInitParams as SessionInitParams
from .symbol_source_param import SymbolSourceParam as SymbolSourceParam
from .file_status_response import FileStatusResponse as FileStatusResponse from .file_status_response import FileStatusResponse as FileStatusResponse
from .tool_state_completed import ToolStateCompleted as ToolStateCompleted from .tool_state_completed import ToolStateCompleted as ToolStateCompleted
from .file_part_input_param import FilePartInputParam as FilePartInputParam
from .file_part_source_text import FilePartSourceText as FilePartSourceText
from .find_symbols_response import FindSymbolsResponse as FindSymbolsResponse from .find_symbols_response import FindSymbolsResponse as FindSymbolsResponse
from .session_init_response import SessionInitResponse as SessionInitResponse from .session_init_response import SessionInitResponse as SessionInitResponse
from .session_list_response import SessionListResponse as SessionListResponse from .session_list_response import SessionListResponse as SessionListResponse
from .session_revert_params import SessionRevertParams as SessionRevertParams
from .text_part_input_param import TextPartInputParam as TextPartInputParam
from .app_providers_response import AppProvidersResponse as AppProvidersResponse
from .file_part_source_param import FilePartSourceParam as FilePartSourceParam
from .session_abort_response import SessionAbortResponse as SessionAbortResponse from .session_abort_response import SessionAbortResponse as SessionAbortResponse
from .tui_open_help_response import TuiOpenHelpResponse as TuiOpenHelpResponse
from .session_delete_response import SessionDeleteResponse as SessionDeleteResponse from .session_delete_response import SessionDeleteResponse as SessionDeleteResponse
from .session_summarize_params import SessionSummarizeParams as SessionSummarizeParams from .session_summarize_params import SessionSummarizeParams as SessionSummarizeParams
from .config_providers_response import ConfigProvidersResponse as ConfigProvidersResponse from .tui_append_prompt_params import TuiAppendPromptParams as TuiAppendPromptParams
from .session_messages_response import SessionMessagesResponse as SessionMessagesResponse from .session_messages_response import SessionMessagesResponse as SessionMessagesResponse
from .session_summarize_response import SessionSummarizeResponse as SessionSummarizeResponse from .session_summarize_response import SessionSummarizeResponse as SessionSummarizeResponse
from .tui_append_prompt_response import TuiAppendPromptResponse as TuiAppendPromptResponse
from .file_part_source_text_param import FilePartSourceTextParam as FilePartSourceTextParam

View file

@ -5,10 +5,10 @@ from typing import Dict, List
from .._models import BaseModel from .._models import BaseModel
from .provider import Provider from .provider import Provider
__all__ = ["ConfigProvidersResponse"] __all__ = ["AppProvidersResponse"]
class ConfigProvidersResponse(BaseModel): class AppProvidersResponse(BaseModel):
default: Dict[str, str] default: Dict[str, str]
providers: List[Provider] providers: List[Provider]

View file

@ -59,6 +59,8 @@ class AssistantMessage(BaseModel):
cost: float cost: float
mode: str
api_model_id: str = FieldInfo(alias="modelID") api_model_id: str = FieldInfo(alias="modelID")
path: Path path: Path

View file

@ -5,31 +5,51 @@ from typing_extensions import Literal, Annotated, TypeAlias
from pydantic import Field as FieldInfo from pydantic import Field as FieldInfo
from .config import ModeUnnamedTypeWithobjectParent0ModeUnnamedTypeWithobjectParent0Item
from .._utils import PropertyInfo from .._utils import PropertyInfo
from .._models import BaseModel from .._models import BaseModel
from .keybinds import Keybinds from .mode_config import ModeConfig
from .log_level import LogLevel from .keybinds_config import KeybindsConfig
from .mcp_local import McpLocal from .mcp_local_config import McpLocalConfig
from .mcp_remote import McpRemote from .mcp_remote_config import McpRemoteConfig
__all__ = [ __all__ = [
"Config", "Config",
"Agent",
"AgentGeneral",
"AgentAgentItem",
"Experimental", "Experimental",
"ExperimentalHook", "ExperimentalHook",
"ExperimentalHookFileEdited", "ExperimentalHookFileEdited",
"ExperimentalHookSessionCompleted", "ExperimentalHookSessionCompleted",
"Mcp", "Mcp",
"Mode", "Mode",
"ModeBuild",
"ModePlan",
"Provider", "Provider",
"ProviderModels", "ProviderModels",
"ProviderModelsCost", "ProviderModelsCost",
"ProviderModelsLimit", "ProviderModelsLimit",
"ProviderOptions",
] ]
class AgentGeneral(ModeConfig):
description: str
class AgentAgentItem(ModeConfig):
description: str
class Agent(BaseModel):
general: Optional[AgentGeneral] = None
__pydantic_extra__: Dict[str, AgentAgentItem] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride]
if TYPE_CHECKING:
# Stub to indicate that arbitrary properties are accepted.
# To access properties that are not valid identifiers you can use `getattr`, e.g.
# `getattr(obj, '$type')`
def __getattr__(self, attr: str) -> AgentAgentItem: ...
class ExperimentalHookFileEdited(BaseModel): class ExperimentalHookFileEdited(BaseModel):
command: List[str] command: List[str]
@ -52,35 +72,20 @@ class Experimental(BaseModel):
hook: Optional[ExperimentalHook] = None hook: Optional[ExperimentalHook] = None
Mcp: TypeAlias = Annotated[Union[McpLocal, McpRemote], PropertyInfo(discriminator="type")] Mcp: TypeAlias = Annotated[Union[McpLocalConfig, McpRemoteConfig], PropertyInfo(discriminator="type")]
class ModeBuild(BaseModel):
model: Optional[str] = None
prompt: Optional[str] = None
tools: Optional[Dict[str, bool]] = None
class ModePlan(BaseModel):
model: Optional[str] = None
prompt: Optional[str] = None
tools: Optional[Dict[str, bool]] = None
class Mode(BaseModel): class Mode(BaseModel):
build: Optional[ModeBuild] = None build: Optional[ModeConfig] = None
plan: Optional[ModePlan] = None plan: Optional[ModeConfig] = None
__pydantic_extra__: Dict[str, ModeConfig] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride]
if TYPE_CHECKING: if TYPE_CHECKING:
# Stub to indicate that arbitrary properties are accepted. # Stub to indicate that arbitrary properties are accepted.
# To access properties that are not valid identifiers you can use `getattr`, e.g. # To access properties that are not valid identifiers you can use `getattr`, e.g.
# `getattr(obj, '$type')` # `getattr(obj, '$type')`
def __getattr__(self, attr: str) -> ModeUnnamedTypeWithobjectParent0ModeUnnamedTypeWithobjectParent0Item: ... def __getattr__(self, attr: str) -> ModeConfig: ...
class ProviderModelsCost(BaseModel): class ProviderModelsCost(BaseModel):
@ -121,6 +126,19 @@ class ProviderModels(BaseModel):
tool_call: Optional[bool] = None tool_call: Optional[bool] = None
class ProviderOptions(BaseModel):
api_key: Optional[str] = FieldInfo(alias="apiKey", default=None)
base_url: Optional[str] = FieldInfo(alias="baseURL", default=None)
__pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride]
if TYPE_CHECKING:
# Stub to indicate that arbitrary properties are accepted.
# To access properties that are not valid identifiers you can use `getattr`, e.g.
# `getattr(obj, '$type')`
def __getattr__(self, attr: str) -> object: ...
class Provider(BaseModel): class Provider(BaseModel):
models: Dict[str, ProviderModels] models: Dict[str, ProviderModels]
@ -134,13 +152,16 @@ class Provider(BaseModel):
npm: Optional[str] = None npm: Optional[str] = None
options: Optional[Dict[str, object]] = None options: Optional[ProviderOptions] = None
class Config(BaseModel): class Config(BaseModel):
schema_: Optional[str] = FieldInfo(alias="$schema", default=None) schema_: Optional[str] = FieldInfo(alias="$schema", default=None)
"""JSON schema reference for configuration validation""" """JSON schema reference for configuration validation"""
agent: Optional[Agent] = None
"""Modes configuration, see https://opencode.ai/docs/modes"""
autoshare: Optional[bool] = None autoshare: Optional[bool] = None
"""@deprecated Use 'share' field instead. """@deprecated Use 'share' field instead.
@ -158,16 +179,17 @@ class Config(BaseModel):
instructions: Optional[List[str]] = None instructions: Optional[List[str]] = None
"""Additional instruction files or patterns to include""" """Additional instruction files or patterns to include"""
keybinds: Optional[Keybinds] = None keybinds: Optional[KeybindsConfig] = None
"""Custom keybind configurations""" """Custom keybind configurations"""
log_level: Optional[LogLevel] = None layout: Optional[Literal["auto", "stretch"]] = None
"""Minimum log level to write to log files""" """@deprecated Always uses stretch layout."""
mcp: Optional[Dict[str, Mcp]] = None mcp: Optional[Dict[str, Mcp]] = None
"""MCP (Model Context Protocol) server configurations""" """MCP (Model Context Protocol) server configurations"""
mode: Optional[Mode] = None mode: Optional[Mode] = None
"""Modes configuration, see https://opencode.ai/docs/modes"""
model: Optional[str] = None model: Optional[str] = None
"""Model to use in the format of provider/model, eg anthropic/claude-2""" """Model to use in the format of provider/model, eg anthropic/claude-2"""
@ -175,10 +197,16 @@ class Config(BaseModel):
provider: Optional[Dict[str, Provider]] = None provider: Optional[Dict[str, Provider]] = None
"""Custom provider configurations and model overrides""" """Custom provider configurations and model overrides"""
share: Optional[Literal["auto", "disabled"]] = None share: Optional[Literal["manual", "auto", "disabled"]] = None
""" """
Control sharing behavior: 'auto' enables automatic sharing, 'disabled' disables Control sharing behavior:'manual' allows manual sharing via commands, 'auto'
all sharing enables automatic sharing, 'disabled' disables all sharing
"""
small_model: Optional[str] = None
"""
Small model to use for tasks like summarization and title generation in the
format of provider/model
""" """
theme: Optional[str] = None theme: Optional[str] = None

View file

@ -16,23 +16,25 @@ from .shared.message_aborted_error import MessageAbortedError
__all__ = [ __all__ = [
"EventListResponse", "EventListResponse",
"EventLspClientDiagnostics",
"EventLspClientDiagnosticsProperties",
"EventPermissionUpdated",
"EventPermissionUpdatedProperties",
"EventPermissionUpdatedPropertiesTime",
"EventFileEdited",
"EventFileEditedProperties",
"EventInstallationUpdated", "EventInstallationUpdated",
"EventInstallationUpdatedProperties", "EventInstallationUpdatedProperties",
"EventLspClientDiagnostics",
"EventLspClientDiagnosticsProperties",
"EventMessageUpdated", "EventMessageUpdated",
"EventMessageUpdatedProperties", "EventMessageUpdatedProperties",
"EventMessageRemoved", "EventMessageRemoved",
"EventMessageRemovedProperties", "EventMessageRemovedProperties",
"EventMessagePartUpdated", "EventMessagePartUpdated",
"EventMessagePartUpdatedProperties", "EventMessagePartUpdatedProperties",
"EventMessagePartRemoved",
"EventMessagePartRemovedProperties",
"EventStorageWrite", "EventStorageWrite",
"EventStorageWriteProperties", "EventStorageWriteProperties",
"EventPermissionUpdated",
"EventPermissionUpdatedProperties",
"EventPermissionUpdatedPropertiesTime",
"EventFileEdited",
"EventFileEditedProperties",
"EventSessionUpdated", "EventSessionUpdated",
"EventSessionUpdatedProperties", "EventSessionUpdatedProperties",
"EventSessionDeleted", "EventSessionDeleted",
@ -43,11 +45,24 @@ __all__ = [
"EventSessionErrorProperties", "EventSessionErrorProperties",
"EventSessionErrorPropertiesError", "EventSessionErrorPropertiesError",
"EventSessionErrorPropertiesErrorMessageOutputLengthError", "EventSessionErrorPropertiesErrorMessageOutputLengthError",
"EventServerConnected",
"EventFileWatcherUpdated", "EventFileWatcherUpdated",
"EventFileWatcherUpdatedProperties", "EventFileWatcherUpdatedProperties",
"EventIdeInstalled",
"EventIdeInstalledProperties",
] ]
class EventInstallationUpdatedProperties(BaseModel):
version: str
class EventInstallationUpdated(BaseModel):
properties: EventInstallationUpdatedProperties
type: Literal["installation.updated"]
class EventLspClientDiagnosticsProperties(BaseModel): class EventLspClientDiagnosticsProperties(BaseModel):
path: str path: str
@ -60,48 +75,6 @@ class EventLspClientDiagnostics(BaseModel):
type: Literal["lsp.client.diagnostics"] type: Literal["lsp.client.diagnostics"]
class EventPermissionUpdatedPropertiesTime(BaseModel):
created: float
class EventPermissionUpdatedProperties(BaseModel):
id: str
metadata: Dict[str, object]
session_id: str = FieldInfo(alias="sessionID")
time: EventPermissionUpdatedPropertiesTime
title: str
class EventPermissionUpdated(BaseModel):
properties: EventPermissionUpdatedProperties
type: Literal["permission.updated"]
class EventFileEditedProperties(BaseModel):
file: str
class EventFileEdited(BaseModel):
properties: EventFileEditedProperties
type: Literal["file.edited"]
class EventInstallationUpdatedProperties(BaseModel):
version: str
class EventInstallationUpdated(BaseModel):
properties: EventInstallationUpdatedProperties
type: Literal["installation.updated"]
class EventMessageUpdatedProperties(BaseModel): class EventMessageUpdatedProperties(BaseModel):
info: Message info: Message
@ -134,6 +107,20 @@ class EventMessagePartUpdated(BaseModel):
type: Literal["message.part.updated"] type: Literal["message.part.updated"]
class EventMessagePartRemovedProperties(BaseModel):
message_id: str = FieldInfo(alias="messageID")
part_id: str = FieldInfo(alias="partID")
session_id: str = FieldInfo(alias="sessionID")
class EventMessagePartRemoved(BaseModel):
properties: EventMessagePartRemovedProperties
type: Literal["message.part.removed"]
class EventStorageWriteProperties(BaseModel): class EventStorageWriteProperties(BaseModel):
key: str key: str
@ -146,6 +133,38 @@ class EventStorageWrite(BaseModel):
type: Literal["storage.write"] type: Literal["storage.write"]
class EventPermissionUpdatedPropertiesTime(BaseModel):
created: float
class EventPermissionUpdatedProperties(BaseModel):
id: str
metadata: Dict[str, object]
session_id: str = FieldInfo(alias="sessionID")
time: EventPermissionUpdatedPropertiesTime
title: str
class EventPermissionUpdated(BaseModel):
properties: EventPermissionUpdatedProperties
type: Literal["permission.updated"]
class EventFileEditedProperties(BaseModel):
file: str
class EventFileEdited(BaseModel):
properties: EventFileEditedProperties
type: Literal["file.edited"]
class EventSessionUpdatedProperties(BaseModel): class EventSessionUpdatedProperties(BaseModel):
info: Session info: Session
@ -202,6 +221,12 @@ class EventSessionError(BaseModel):
type: Literal["session.error"] type: Literal["session.error"]
class EventServerConnected(BaseModel):
properties: object
type: Literal["server.connected"]
class EventFileWatcherUpdatedProperties(BaseModel): class EventFileWatcherUpdatedProperties(BaseModel):
event: Literal["rename", "change"] event: Literal["rename", "change"]
@ -214,21 +239,34 @@ class EventFileWatcherUpdated(BaseModel):
type: Literal["file.watcher.updated"] type: Literal["file.watcher.updated"]
class EventIdeInstalledProperties(BaseModel):
ide: str
class EventIdeInstalled(BaseModel):
properties: EventIdeInstalledProperties
type: Literal["ide.installed"]
EventListResponse: TypeAlias = Annotated[ EventListResponse: TypeAlias = Annotated[
Union[ Union[
EventLspClientDiagnostics,
EventPermissionUpdated,
EventFileEdited,
EventInstallationUpdated, EventInstallationUpdated,
EventLspClientDiagnostics,
EventMessageUpdated, EventMessageUpdated,
EventMessageRemoved, EventMessageRemoved,
EventMessagePartUpdated, EventMessagePartUpdated,
EventMessagePartRemoved,
EventStorageWrite, EventStorageWrite,
EventPermissionUpdated,
EventFileEdited,
EventSessionUpdated, EventSessionUpdated,
EventSessionDeleted, EventSessionDeleted,
EventSessionIdle, EventSessionIdle,
EventSessionError, EventSessionError,
EventServerConnected,
EventFileWatcherUpdated, EventFileWatcherUpdated,
EventIdeInstalled,
], ],
PropertyInfo(discriminator="type"), PropertyInfo(discriminator="type"),
] ]

View file

@ -6,6 +6,7 @@ from typing_extensions import Literal
from pydantic import Field as FieldInfo from pydantic import Field as FieldInfo
from .._models import BaseModel from .._models import BaseModel
from .file_part_source import FilePartSource
__all__ = ["FilePart"] __all__ = ["FilePart"]
@ -24,3 +25,5 @@ class FilePart(BaseModel):
url: str url: str
filename: Optional[str] = None filename: Optional[str] = None
source: Optional[FilePartSource] = None

View file

@ -0,0 +1,23 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
from typing_extensions import Literal, Required, TypedDict
from .file_part_source_param import FilePartSourceParam
__all__ = ["FilePartInputParam"]
class FilePartInputParam(TypedDict, total=False):
mime: Required[str]
type: Required[Literal["file"]]
url: Required[str]
id: str
filename: str
source: FilePartSourceParam

View file

@ -1,25 +0,0 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
from typing_extensions import Literal, Required, Annotated, TypedDict
from .._utils import PropertyInfo
__all__ = ["FilePartParam"]
class FilePartParam(TypedDict, total=False):
id: Required[str]
message_id: Required[Annotated[str, PropertyInfo(alias="messageID")]]
mime: Required[str]
session_id: Required[Annotated[str, PropertyInfo(alias="sessionID")]]
type: Required[Literal["file"]]
url: Required[str]
filename: str

View file

@ -0,0 +1,12 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Union
from typing_extensions import Annotated, TypeAlias
from .._utils import PropertyInfo
from .file_source import FileSource
from .symbol_source import SymbolSource
__all__ = ["FilePartSource"]
FilePartSource: TypeAlias = Annotated[Union[FileSource, SymbolSource], PropertyInfo(discriminator="type")]

View file

@ -0,0 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
from typing import Union
from typing_extensions import TypeAlias
from .file_source_param import FileSourceParam
from .symbol_source_param import SymbolSourceParam
__all__ = ["FilePartSourceParam"]
FilePartSourceParam: TypeAlias = Union[FileSourceParam, SymbolSourceParam]

View file

@ -0,0 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from .._models import BaseModel
__all__ = ["FilePartSourceText"]
class FilePartSourceText(BaseModel):
end: int
start: int
value: str

View file

@ -0,0 +1,15 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
from typing_extensions import Required, TypedDict
__all__ = ["FilePartSourceTextParam"]
class FilePartSourceTextParam(TypedDict, total=False):
end: Required[int]
start: Required[int]
value: Required[str]

View file

@ -0,0 +1,16 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing_extensions import Literal
from .._models import BaseModel
from .file_part_source_text import FilePartSourceText
__all__ = ["FileSource"]
class FileSource(BaseModel):
path: str
text: FilePartSourceText
type: Literal["file"]

View file

@ -0,0 +1,17 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
from typing_extensions import Literal, Required, TypedDict
from .file_part_source_text_param import FilePartSourceTextParam
__all__ = ["FileSourceParam"]
class FileSourceParam(TypedDict, total=False):
path: Required[str]
text: Required[FilePartSourceTextParam]
type: Required[Literal["file"]]

View file

@ -3,8 +3,48 @@
from typing import List from typing import List
from typing_extensions import TypeAlias from typing_extensions import TypeAlias
from .match import Match from .._models import BaseModel
__all__ = ["FindTextResponse"] __all__ = [
"FindTextResponse",
"FindTextResponseItem",
"FindTextResponseItemLines",
"FindTextResponseItemPath",
"FindTextResponseItemSubmatch",
"FindTextResponseItemSubmatchMatch",
]
FindTextResponse: TypeAlias = List[Match]
class FindTextResponseItemLines(BaseModel):
text: str
class FindTextResponseItemPath(BaseModel):
text: str
class FindTextResponseItemSubmatchMatch(BaseModel):
text: str
class FindTextResponseItemSubmatch(BaseModel):
end: float
match: FindTextResponseItemSubmatchMatch
start: float
class FindTextResponseItem(BaseModel):
absolute_offset: float
line_number: float
lines: FindTextResponseItemLines
path: FindTextResponseItemPath
submatches: List[FindTextResponseItemSubmatch]
FindTextResponse: TypeAlias = List[FindTextResponseItem]

View file

@ -4,10 +4,10 @@ from pydantic import Field as FieldInfo
from .._models import BaseModel from .._models import BaseModel
__all__ = ["Keybinds"] __all__ = ["KeybindsConfig"]
class Keybinds(BaseModel): class KeybindsConfig(BaseModel):
app_exit: str app_exit: str
"""Exit the application""" """Exit the application"""
@ -74,8 +74,14 @@ class Keybinds(BaseModel):
messages_previous: str messages_previous: str
"""Navigate to previous message""" """Navigate to previous message"""
messages_redo: str
"""Redo message"""
messages_revert: str messages_revert: str
"""Revert message""" """@deprecated use messages_undo. Revert message"""
messages_undo: str
"""Undo message"""
api_model_list: str = FieldInfo(alias="model_list") api_model_list: str = FieldInfo(alias="model_list")
"""List available models""" """List available models"""
@ -86,6 +92,9 @@ class Keybinds(BaseModel):
session_compact: str session_compact: str
"""Compact the session""" """Compact the session"""
session_export: str
"""Export session to editor"""
session_interrupt: str session_interrupt: str
"""Interrupt current session""" """Interrupt current session"""
@ -102,7 +111,10 @@ class Keybinds(BaseModel):
"""Unshare current session""" """Unshare current session"""
switch_mode: str switch_mode: str
"""Switch mode""" """Next mode"""
switch_mode_reverse: str
"""Previous Mode"""
theme_list: str theme_list: str
"""List available themes""" """List available themes"""

View file

@ -1,7 +0,0 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing_extensions import Literal, TypeAlias
__all__ = ["LogLevel"]
LogLevel: TypeAlias = Literal["DEBUG", "INFO", "WARN", "ERROR"]

View file

@ -1,39 +0,0 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import List
from .._models import BaseModel
__all__ = ["Match", "Lines", "Path", "Submatch", "SubmatchMatch"]
class Lines(BaseModel):
text: str
class Path(BaseModel):
text: str
class SubmatchMatch(BaseModel):
text: str
class Submatch(BaseModel):
end: float
match: SubmatchMatch
start: float
class Match(BaseModel):
absolute_offset: float
line_number: float
lines: Lines
path: Path
submatches: List[Submatch]

View file

@ -5,10 +5,10 @@ from typing_extensions import Literal
from .._models import BaseModel from .._models import BaseModel
__all__ = ["McpLocal"] __all__ = ["McpLocalConfig"]
class McpLocal(BaseModel): class McpLocalConfig(BaseModel):
command: List[str] command: List[str]
"""Command and arguments to run the MCP server""" """Command and arguments to run the MCP server"""

View file

@ -1,14 +1,14 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional from typing import Dict, Optional
from typing_extensions import Literal from typing_extensions import Literal
from .._models import BaseModel from .._models import BaseModel
__all__ = ["McpRemote"] __all__ = ["McpRemoteConfig"]
class McpRemote(BaseModel): class McpRemoteConfig(BaseModel):
type: Literal["remote"] type: Literal["remote"]
"""Type of MCP server connection""" """Type of MCP server connection"""
@ -17,3 +17,6 @@ class McpRemote(BaseModel):
enabled: Optional[bool] = None enabled: Optional[bool] = None
"""Enable or disable the MCP server on startup""" """Enable or disable the MCP server on startup"""
headers: Optional[Dict[str, str]] = None
"""Headers to send with the request"""

View file

@ -23,3 +23,5 @@ class Mode(BaseModel):
model: Optional[Model] = None model: Optional[Model] = None
prompt: Optional[str] = None prompt: Optional[str] = None
temperature: Optional[float] = None

View file

@ -0,0 +1,19 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Dict, Optional
from .._models import BaseModel
__all__ = ["ModeConfig"]
class ModeConfig(BaseModel):
disable: Optional[bool] = None
model: Optional[str] = None
prompt: Optional[str] = None
temperature: Optional[float] = None
tools: Optional[Dict[str, bool]] = None

View file

@ -1,9 +1,12 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Union from typing import List, Union
from typing_extensions import Annotated, TypeAlias from typing_extensions import Literal, Annotated, TypeAlias
from pydantic import Field as FieldInfo
from .._utils import PropertyInfo from .._utils import PropertyInfo
from .._models import BaseModel
from .file_part import FilePart from .file_part import FilePart
from .text_part import TextPart from .text_part import TextPart
from .tool_part import ToolPart from .tool_part import ToolPart
@ -11,8 +14,24 @@ from .snapshot_part import SnapshotPart
from .step_start_part import StepStartPart from .step_start_part import StepStartPart
from .step_finish_part import StepFinishPart from .step_finish_part import StepFinishPart
__all__ = ["Part"] __all__ = ["Part", "PatchPart"]
class PatchPart(BaseModel):
id: str
files: List[str]
hash: str
message_id: str = FieldInfo(alias="messageID")
session_id: str = FieldInfo(alias="sessionID")
type: Literal["patch"]
Part: TypeAlias = Annotated[ Part: TypeAlias = Annotated[
Union[TextPart, FilePart, ToolPart, StepStartPart, StepFinishPart, SnapshotPart], PropertyInfo(discriminator="type") Union[TextPart, FilePart, ToolPart, StepStartPart, StepFinishPart, SnapshotPart, PatchPart],
PropertyInfo(discriminator="type"),
] ]

View file

@ -18,7 +18,9 @@ class Time(BaseModel):
class Revert(BaseModel): class Revert(BaseModel):
message_id: str = FieldInfo(alias="messageID") message_id: str = FieldInfo(alias="messageID")
part: float diff: Optional[str] = None
part_id: Optional[str] = FieldInfo(alias="partID", default=None)
snapshot: Optional[str] = None snapshot: Optional[str] = None

View file

@ -2,26 +2,30 @@
from __future__ import annotations from __future__ import annotations
from typing import Union, Iterable from typing import Dict, Union, Iterable
from typing_extensions import Required, Annotated, TypeAlias, TypedDict from typing_extensions import Required, Annotated, TypeAlias, TypedDict
from .._utils import PropertyInfo from .._utils import PropertyInfo
from .file_part_param import FilePartParam from .file_part_input_param import FilePartInputParam
from .text_part_param import TextPartParam from .text_part_input_param import TextPartInputParam
__all__ = ["SessionChatParams", "Part"] __all__ = ["SessionChatParams", "Part"]
class SessionChatParams(TypedDict, total=False): class SessionChatParams(TypedDict, total=False):
message_id: Required[Annotated[str, PropertyInfo(alias="messageID")]]
mode: Required[str]
model_id: Required[Annotated[str, PropertyInfo(alias="modelID")]] model_id: Required[Annotated[str, PropertyInfo(alias="modelID")]]
parts: Required[Iterable[Part]] parts: Required[Iterable[Part]]
provider_id: Required[Annotated[str, PropertyInfo(alias="providerID")]] provider_id: Required[Annotated[str, PropertyInfo(alias="providerID")]]
message_id: Annotated[str, PropertyInfo(alias="messageID")]
Part: TypeAlias = Union[FilePartParam, TextPartParam] mode: str
system: str
tools: Dict[str, bool]
Part: TypeAlias = Union[TextPartInputParam, FilePartInputParam]

View file

@ -0,0 +1,15 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
from typing_extensions import Required, Annotated, TypedDict
from .._utils import PropertyInfo
__all__ = ["SessionRevertParams"]
class SessionRevertParams(TypedDict, total=False):
message_id: Required[Annotated[str, PropertyInfo(alias="messageID")]]
part_id: Annotated[str, PropertyInfo(alias="partID")]

View file

@ -0,0 +1,40 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing_extensions import Literal
from .._models import BaseModel
from .file_part_source_text import FilePartSourceText
__all__ = ["SymbolSource", "Range", "RangeEnd", "RangeStart"]
class RangeEnd(BaseModel):
character: float
line: float
class RangeStart(BaseModel):
character: float
line: float
class Range(BaseModel):
end: RangeEnd
start: RangeStart
class SymbolSource(BaseModel):
kind: int
name: str
path: str
range: Range
text: FilePartSourceText
type: Literal["symbol"]

View file

@ -0,0 +1,41 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
from typing_extensions import Literal, Required, TypedDict
from .file_part_source_text_param import FilePartSourceTextParam
__all__ = ["SymbolSourceParam", "Range", "RangeEnd", "RangeStart"]
class RangeEnd(TypedDict, total=False):
character: Required[float]
line: Required[float]
class RangeStart(TypedDict, total=False):
character: Required[float]
line: Required[float]
class Range(TypedDict, total=False):
end: Required[RangeEnd]
start: Required[RangeStart]
class SymbolSourceParam(TypedDict, total=False):
kind: Required[int]
name: Required[str]
path: Required[str]
range: Required[Range]
text: Required[FilePartSourceTextParam]
type: Required[Literal["symbol"]]

View file

@ -0,0 +1,25 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
from typing_extensions import Literal, Required, TypedDict
__all__ = ["TextPartInputParam", "Time"]
class Time(TypedDict, total=False):
start: Required[float]
end: float
class TextPartInputParam(TypedDict, total=False):
text: Required[str]
type: Required[Literal["text"]]
id: str
synthetic: bool
time: Time

View file

@ -1,31 +0,0 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
from typing_extensions import Literal, Required, Annotated, TypedDict
from .._utils import PropertyInfo
__all__ = ["TextPartParam", "Time"]
class Time(TypedDict, total=False):
start: Required[float]
end: float
class TextPartParam(TypedDict, total=False):
id: Required[str]
message_id: Required[Annotated[str, PropertyInfo(alias="messageID")]]
session_id: Required[Annotated[str, PropertyInfo(alias="sessionID")]]
text: Required[str]
type: Required[Literal["text"]]
synthetic: bool
time: Time

View file

@ -0,0 +1,11 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
from typing_extensions import Required, TypedDict
__all__ = ["TuiAppendPromptParams"]
class TuiAppendPromptParams(TypedDict, total=False):
text: Required[str]

View file

@ -0,0 +1,7 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing_extensions import TypeAlias
__all__ = ["TuiAppendPromptResponse"]
TuiAppendPromptResponse: TypeAlias = bool

View file

@ -0,0 +1,7 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing_extensions import TypeAlias
__all__ = ["TuiOpenHelpResponse"]
TuiOpenHelpResponse: TypeAlias = bool

View file

@ -9,7 +9,13 @@ import pytest
from opencode_ai import Opencode, AsyncOpencode from opencode_ai import Opencode, AsyncOpencode
from tests.utils import assert_matches_type from tests.utils import assert_matches_type
from opencode_ai.types import App, AppLogResponse, AppInitResponse, AppModesResponse from opencode_ai.types import (
App,
AppLogResponse,
AppInitResponse,
AppModesResponse,
AppProvidersResponse,
)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@ -17,13 +23,13 @@ base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
class TestApp: class TestApp:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_get(self, client: Opencode) -> None: def test_method_get(self, client: Opencode) -> None:
app = client.app.get() app = client.app.get()
assert_matches_type(App, app, path=["response"]) assert_matches_type(App, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_get(self, client: Opencode) -> None: def test_raw_response_get(self, client: Opencode) -> None:
response = client.app.with_raw_response.get() response = client.app.with_raw_response.get()
@ -33,7 +39,7 @@ class TestApp:
app = response.parse() app = response.parse()
assert_matches_type(App, app, path=["response"]) assert_matches_type(App, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_get(self, client: Opencode) -> None: def test_streaming_response_get(self, client: Opencode) -> None:
with client.app.with_streaming_response.get() as response: with client.app.with_streaming_response.get() as response:
@ -45,13 +51,13 @@ class TestApp:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_init(self, client: Opencode) -> None: def test_method_init(self, client: Opencode) -> None:
app = client.app.init() app = client.app.init()
assert_matches_type(AppInitResponse, app, path=["response"]) assert_matches_type(AppInitResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_init(self, client: Opencode) -> None: def test_raw_response_init(self, client: Opencode) -> None:
response = client.app.with_raw_response.init() response = client.app.with_raw_response.init()
@ -61,7 +67,7 @@ class TestApp:
app = response.parse() app = response.parse()
assert_matches_type(AppInitResponse, app, path=["response"]) assert_matches_type(AppInitResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_init(self, client: Opencode) -> None: def test_streaming_response_init(self, client: Opencode) -> None:
with client.app.with_streaming_response.init() as response: with client.app.with_streaming_response.init() as response:
@ -73,7 +79,7 @@ class TestApp:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_log(self, client: Opencode) -> None: def test_method_log(self, client: Opencode) -> None:
app = client.app.log( app = client.app.log(
@ -83,7 +89,7 @@ class TestApp:
) )
assert_matches_type(AppLogResponse, app, path=["response"]) assert_matches_type(AppLogResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_log_with_all_params(self, client: Opencode) -> None: def test_method_log_with_all_params(self, client: Opencode) -> None:
app = client.app.log( app = client.app.log(
@ -94,7 +100,7 @@ class TestApp:
) )
assert_matches_type(AppLogResponse, app, path=["response"]) assert_matches_type(AppLogResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_log(self, client: Opencode) -> None: def test_raw_response_log(self, client: Opencode) -> None:
response = client.app.with_raw_response.log( response = client.app.with_raw_response.log(
@ -108,7 +114,7 @@ class TestApp:
app = response.parse() app = response.parse()
assert_matches_type(AppLogResponse, app, path=["response"]) assert_matches_type(AppLogResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_log(self, client: Opencode) -> None: def test_streaming_response_log(self, client: Opencode) -> None:
with client.app.with_streaming_response.log( with client.app.with_streaming_response.log(
@ -124,13 +130,13 @@ class TestApp:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_modes(self, client: Opencode) -> None: def test_method_modes(self, client: Opencode) -> None:
app = client.app.modes() app = client.app.modes()
assert_matches_type(AppModesResponse, app, path=["response"]) assert_matches_type(AppModesResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_modes(self, client: Opencode) -> None: def test_raw_response_modes(self, client: Opencode) -> None:
response = client.app.with_raw_response.modes() response = client.app.with_raw_response.modes()
@ -140,7 +146,7 @@ class TestApp:
app = response.parse() app = response.parse()
assert_matches_type(AppModesResponse, app, path=["response"]) assert_matches_type(AppModesResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_modes(self, client: Opencode) -> None: def test_streaming_response_modes(self, client: Opencode) -> None:
with client.app.with_streaming_response.modes() as response: with client.app.with_streaming_response.modes() as response:
@ -152,19 +158,47 @@ class TestApp:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_providers(self, client: Opencode) -> None:
app = client.app.providers()
assert_matches_type(AppProvidersResponse, app, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_providers(self, client: Opencode) -> None:
response = client.app.with_raw_response.providers()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
app = response.parse()
assert_matches_type(AppProvidersResponse, app, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_providers(self, client: Opencode) -> None:
with client.app.with_streaming_response.providers() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
app = response.parse()
assert_matches_type(AppProvidersResponse, app, path=["response"])
assert cast(Any, response.is_closed) is True
class TestAsyncApp: class TestAsyncApp:
parametrize = pytest.mark.parametrize( parametrize = pytest.mark.parametrize(
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_get(self, async_client: AsyncOpencode) -> None: async def test_method_get(self, async_client: AsyncOpencode) -> None:
app = await async_client.app.get() app = await async_client.app.get()
assert_matches_type(App, app, path=["response"]) assert_matches_type(App, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_get(self, async_client: AsyncOpencode) -> None: async def test_raw_response_get(self, async_client: AsyncOpencode) -> None:
response = await async_client.app.with_raw_response.get() response = await async_client.app.with_raw_response.get()
@ -174,7 +208,7 @@ class TestAsyncApp:
app = await response.parse() app = await response.parse()
assert_matches_type(App, app, path=["response"]) assert_matches_type(App, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_get(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_get(self, async_client: AsyncOpencode) -> None:
async with async_client.app.with_streaming_response.get() as response: async with async_client.app.with_streaming_response.get() as response:
@ -186,13 +220,13 @@ class TestAsyncApp:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_init(self, async_client: AsyncOpencode) -> None: async def test_method_init(self, async_client: AsyncOpencode) -> None:
app = await async_client.app.init() app = await async_client.app.init()
assert_matches_type(AppInitResponse, app, path=["response"]) assert_matches_type(AppInitResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_init(self, async_client: AsyncOpencode) -> None: async def test_raw_response_init(self, async_client: AsyncOpencode) -> None:
response = await async_client.app.with_raw_response.init() response = await async_client.app.with_raw_response.init()
@ -202,7 +236,7 @@ class TestAsyncApp:
app = await response.parse() app = await response.parse()
assert_matches_type(AppInitResponse, app, path=["response"]) assert_matches_type(AppInitResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_init(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_init(self, async_client: AsyncOpencode) -> None:
async with async_client.app.with_streaming_response.init() as response: async with async_client.app.with_streaming_response.init() as response:
@ -214,7 +248,7 @@ class TestAsyncApp:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_log(self, async_client: AsyncOpencode) -> None: async def test_method_log(self, async_client: AsyncOpencode) -> None:
app = await async_client.app.log( app = await async_client.app.log(
@ -224,7 +258,7 @@ class TestAsyncApp:
) )
assert_matches_type(AppLogResponse, app, path=["response"]) assert_matches_type(AppLogResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_log_with_all_params(self, async_client: AsyncOpencode) -> None: async def test_method_log_with_all_params(self, async_client: AsyncOpencode) -> None:
app = await async_client.app.log( app = await async_client.app.log(
@ -235,7 +269,7 @@ class TestAsyncApp:
) )
assert_matches_type(AppLogResponse, app, path=["response"]) assert_matches_type(AppLogResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_log(self, async_client: AsyncOpencode) -> None: async def test_raw_response_log(self, async_client: AsyncOpencode) -> None:
response = await async_client.app.with_raw_response.log( response = await async_client.app.with_raw_response.log(
@ -249,7 +283,7 @@ class TestAsyncApp:
app = await response.parse() app = await response.parse()
assert_matches_type(AppLogResponse, app, path=["response"]) assert_matches_type(AppLogResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_log(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_log(self, async_client: AsyncOpencode) -> None:
async with async_client.app.with_streaming_response.log( async with async_client.app.with_streaming_response.log(
@ -265,13 +299,13 @@ class TestAsyncApp:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_modes(self, async_client: AsyncOpencode) -> None: async def test_method_modes(self, async_client: AsyncOpencode) -> None:
app = await async_client.app.modes() app = await async_client.app.modes()
assert_matches_type(AppModesResponse, app, path=["response"]) assert_matches_type(AppModesResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_modes(self, async_client: AsyncOpencode) -> None: async def test_raw_response_modes(self, async_client: AsyncOpencode) -> None:
response = await async_client.app.with_raw_response.modes() response = await async_client.app.with_raw_response.modes()
@ -281,7 +315,7 @@ class TestAsyncApp:
app = await response.parse() app = await response.parse()
assert_matches_type(AppModesResponse, app, path=["response"]) assert_matches_type(AppModesResponse, app, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_modes(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_modes(self, async_client: AsyncOpencode) -> None:
async with async_client.app.with_streaming_response.modes() as response: async with async_client.app.with_streaming_response.modes() as response:
@ -292,3 +326,31 @@ class TestAsyncApp:
assert_matches_type(AppModesResponse, app, path=["response"]) assert_matches_type(AppModesResponse, app, path=["response"])
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_providers(self, async_client: AsyncOpencode) -> None:
app = await async_client.app.providers()
assert_matches_type(AppProvidersResponse, app, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_providers(self, async_client: AsyncOpencode) -> None:
response = await async_client.app.with_raw_response.providers()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
app = await response.parse()
assert_matches_type(AppProvidersResponse, app, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_providers(self, async_client: AsyncOpencode) -> None:
async with async_client.app.with_streaming_response.providers() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
app = await response.parse()
assert_matches_type(AppProvidersResponse, app, path=["response"])
assert cast(Any, response.is_closed) is True

View file

@ -9,7 +9,7 @@ import pytest
from opencode_ai import Opencode, AsyncOpencode from opencode_ai import Opencode, AsyncOpencode
from tests.utils import assert_matches_type from tests.utils import assert_matches_type
from opencode_ai.types import Config, ConfigProvidersResponse from opencode_ai.types import Config
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@ -17,13 +17,13 @@ base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
class TestConfig: class TestConfig:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_get(self, client: Opencode) -> None: def test_method_get(self, client: Opencode) -> None:
config = client.config.get() config = client.config.get()
assert_matches_type(Config, config, path=["response"]) assert_matches_type(Config, config, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_get(self, client: Opencode) -> None: def test_raw_response_get(self, client: Opencode) -> None:
response = client.config.with_raw_response.get() response = client.config.with_raw_response.get()
@ -33,7 +33,7 @@ class TestConfig:
config = response.parse() config = response.parse()
assert_matches_type(Config, config, path=["response"]) assert_matches_type(Config, config, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_get(self, client: Opencode) -> None: def test_streaming_response_get(self, client: Opencode) -> None:
with client.config.with_streaming_response.get() as response: with client.config.with_streaming_response.get() as response:
@ -45,47 +45,19 @@ class TestConfig:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip()
@parametrize
def test_method_providers(self, client: Opencode) -> None:
config = client.config.providers()
assert_matches_type(ConfigProvidersResponse, config, path=["response"])
@pytest.mark.skip()
@parametrize
def test_raw_response_providers(self, client: Opencode) -> None:
response = client.config.with_raw_response.providers()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
config = response.parse()
assert_matches_type(ConfigProvidersResponse, config, path=["response"])
@pytest.mark.skip()
@parametrize
def test_streaming_response_providers(self, client: Opencode) -> None:
with client.config.with_streaming_response.providers() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
config = response.parse()
assert_matches_type(ConfigProvidersResponse, config, path=["response"])
assert cast(Any, response.is_closed) is True
class TestAsyncConfig: class TestAsyncConfig:
parametrize = pytest.mark.parametrize( parametrize = pytest.mark.parametrize(
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_get(self, async_client: AsyncOpencode) -> None: async def test_method_get(self, async_client: AsyncOpencode) -> None:
config = await async_client.config.get() config = await async_client.config.get()
assert_matches_type(Config, config, path=["response"]) assert_matches_type(Config, config, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_get(self, async_client: AsyncOpencode) -> None: async def test_raw_response_get(self, async_client: AsyncOpencode) -> None:
response = await async_client.config.with_raw_response.get() response = await async_client.config.with_raw_response.get()
@ -95,7 +67,7 @@ class TestAsyncConfig:
config = await response.parse() config = await response.parse()
assert_matches_type(Config, config, path=["response"]) assert_matches_type(Config, config, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_get(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_get(self, async_client: AsyncOpencode) -> None:
async with async_client.config.with_streaming_response.get() as response: async with async_client.config.with_streaming_response.get() as response:
@ -106,31 +78,3 @@ class TestAsyncConfig:
assert_matches_type(Config, config, path=["response"]) assert_matches_type(Config, config, path=["response"])
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip()
@parametrize
async def test_method_providers(self, async_client: AsyncOpencode) -> None:
config = await async_client.config.providers()
assert_matches_type(ConfigProvidersResponse, config, path=["response"])
@pytest.mark.skip()
@parametrize
async def test_raw_response_providers(self, async_client: AsyncOpencode) -> None:
response = await async_client.config.with_raw_response.providers()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
config = await response.parse()
assert_matches_type(ConfigProvidersResponse, config, path=["response"])
@pytest.mark.skip()
@parametrize
async def test_streaming_response_providers(self, async_client: AsyncOpencode) -> None:
async with async_client.config.with_streaming_response.providers() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
config = await response.parse()
assert_matches_type(ConfigProvidersResponse, config, path=["response"])
assert cast(Any, response.is_closed) is True

View file

@ -15,13 +15,13 @@ base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
class TestEvent: class TestEvent:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_list(self, client: Opencode) -> None: def test_method_list(self, client: Opencode) -> None:
event_stream = client.event.list() event_stream = client.event.list()
event_stream.response.close() event_stream.response.close()
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_list(self, client: Opencode) -> None: def test_raw_response_list(self, client: Opencode) -> None:
response = client.event.with_raw_response.list() response = client.event.with_raw_response.list()
@ -30,7 +30,7 @@ class TestEvent:
stream = response.parse() stream = response.parse()
stream.close() stream.close()
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_list(self, client: Opencode) -> None: def test_streaming_response_list(self, client: Opencode) -> None:
with client.event.with_streaming_response.list() as response: with client.event.with_streaming_response.list() as response:
@ -48,13 +48,13 @@ class TestAsyncEvent:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_list(self, async_client: AsyncOpencode) -> None: async def test_method_list(self, async_client: AsyncOpencode) -> None:
event_stream = await async_client.event.list() event_stream = await async_client.event.list()
await event_stream.response.aclose() await event_stream.response.aclose()
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_list(self, async_client: AsyncOpencode) -> None: async def test_raw_response_list(self, async_client: AsyncOpencode) -> None:
response = await async_client.event.with_raw_response.list() response = await async_client.event.with_raw_response.list()
@ -63,7 +63,7 @@ class TestAsyncEvent:
stream = await response.parse() stream = await response.parse()
await stream.close() await stream.close()
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_list(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_list(self, async_client: AsyncOpencode) -> None:
async with async_client.event.with_streaming_response.list() as response: async with async_client.event.with_streaming_response.list() as response:

View file

@ -17,7 +17,7 @@ base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
class TestFile: class TestFile:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_read(self, client: Opencode) -> None: def test_method_read(self, client: Opencode) -> None:
file = client.file.read( file = client.file.read(
@ -25,7 +25,7 @@ class TestFile:
) )
assert_matches_type(FileReadResponse, file, path=["response"]) assert_matches_type(FileReadResponse, file, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_read(self, client: Opencode) -> None: def test_raw_response_read(self, client: Opencode) -> None:
response = client.file.with_raw_response.read( response = client.file.with_raw_response.read(
@ -37,7 +37,7 @@ class TestFile:
file = response.parse() file = response.parse()
assert_matches_type(FileReadResponse, file, path=["response"]) assert_matches_type(FileReadResponse, file, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_read(self, client: Opencode) -> None: def test_streaming_response_read(self, client: Opencode) -> None:
with client.file.with_streaming_response.read( with client.file.with_streaming_response.read(
@ -51,13 +51,13 @@ class TestFile:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_status(self, client: Opencode) -> None: def test_method_status(self, client: Opencode) -> None:
file = client.file.status() file = client.file.status()
assert_matches_type(FileStatusResponse, file, path=["response"]) assert_matches_type(FileStatusResponse, file, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_status(self, client: Opencode) -> None: def test_raw_response_status(self, client: Opencode) -> None:
response = client.file.with_raw_response.status() response = client.file.with_raw_response.status()
@ -67,7 +67,7 @@ class TestFile:
file = response.parse() file = response.parse()
assert_matches_type(FileStatusResponse, file, path=["response"]) assert_matches_type(FileStatusResponse, file, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_status(self, client: Opencode) -> None: def test_streaming_response_status(self, client: Opencode) -> None:
with client.file.with_streaming_response.status() as response: with client.file.with_streaming_response.status() as response:
@ -85,7 +85,7 @@ class TestAsyncFile:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_read(self, async_client: AsyncOpencode) -> None: async def test_method_read(self, async_client: AsyncOpencode) -> None:
file = await async_client.file.read( file = await async_client.file.read(
@ -93,7 +93,7 @@ class TestAsyncFile:
) )
assert_matches_type(FileReadResponse, file, path=["response"]) assert_matches_type(FileReadResponse, file, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_read(self, async_client: AsyncOpencode) -> None: async def test_raw_response_read(self, async_client: AsyncOpencode) -> None:
response = await async_client.file.with_raw_response.read( response = await async_client.file.with_raw_response.read(
@ -105,7 +105,7 @@ class TestAsyncFile:
file = await response.parse() file = await response.parse()
assert_matches_type(FileReadResponse, file, path=["response"]) assert_matches_type(FileReadResponse, file, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_read(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_read(self, async_client: AsyncOpencode) -> None:
async with async_client.file.with_streaming_response.read( async with async_client.file.with_streaming_response.read(
@ -119,13 +119,13 @@ class TestAsyncFile:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_status(self, async_client: AsyncOpencode) -> None: async def test_method_status(self, async_client: AsyncOpencode) -> None:
file = await async_client.file.status() file = await async_client.file.status()
assert_matches_type(FileStatusResponse, file, path=["response"]) assert_matches_type(FileStatusResponse, file, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_status(self, async_client: AsyncOpencode) -> None: async def test_raw_response_status(self, async_client: AsyncOpencode) -> None:
response = await async_client.file.with_raw_response.status() response = await async_client.file.with_raw_response.status()
@ -135,7 +135,7 @@ class TestAsyncFile:
file = await response.parse() file = await response.parse()
assert_matches_type(FileStatusResponse, file, path=["response"]) assert_matches_type(FileStatusResponse, file, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_status(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_status(self, async_client: AsyncOpencode) -> None:
async with async_client.file.with_streaming_response.status() as response: async with async_client.file.with_streaming_response.status() as response:

View file

@ -21,7 +21,7 @@ base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
class TestFind: class TestFind:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_files(self, client: Opencode) -> None: def test_method_files(self, client: Opencode) -> None:
find = client.find.files( find = client.find.files(
@ -29,7 +29,7 @@ class TestFind:
) )
assert_matches_type(FindFilesResponse, find, path=["response"]) assert_matches_type(FindFilesResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_files(self, client: Opencode) -> None: def test_raw_response_files(self, client: Opencode) -> None:
response = client.find.with_raw_response.files( response = client.find.with_raw_response.files(
@ -41,7 +41,7 @@ class TestFind:
find = response.parse() find = response.parse()
assert_matches_type(FindFilesResponse, find, path=["response"]) assert_matches_type(FindFilesResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_files(self, client: Opencode) -> None: def test_streaming_response_files(self, client: Opencode) -> None:
with client.find.with_streaming_response.files( with client.find.with_streaming_response.files(
@ -55,7 +55,7 @@ class TestFind:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_symbols(self, client: Opencode) -> None: def test_method_symbols(self, client: Opencode) -> None:
find = client.find.symbols( find = client.find.symbols(
@ -63,7 +63,7 @@ class TestFind:
) )
assert_matches_type(FindSymbolsResponse, find, path=["response"]) assert_matches_type(FindSymbolsResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_symbols(self, client: Opencode) -> None: def test_raw_response_symbols(self, client: Opencode) -> None:
response = client.find.with_raw_response.symbols( response = client.find.with_raw_response.symbols(
@ -75,7 +75,7 @@ class TestFind:
find = response.parse() find = response.parse()
assert_matches_type(FindSymbolsResponse, find, path=["response"]) assert_matches_type(FindSymbolsResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_symbols(self, client: Opencode) -> None: def test_streaming_response_symbols(self, client: Opencode) -> None:
with client.find.with_streaming_response.symbols( with client.find.with_streaming_response.symbols(
@ -89,7 +89,7 @@ class TestFind:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_text(self, client: Opencode) -> None: def test_method_text(self, client: Opencode) -> None:
find = client.find.text( find = client.find.text(
@ -97,7 +97,7 @@ class TestFind:
) )
assert_matches_type(FindTextResponse, find, path=["response"]) assert_matches_type(FindTextResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_text(self, client: Opencode) -> None: def test_raw_response_text(self, client: Opencode) -> None:
response = client.find.with_raw_response.text( response = client.find.with_raw_response.text(
@ -109,7 +109,7 @@ class TestFind:
find = response.parse() find = response.parse()
assert_matches_type(FindTextResponse, find, path=["response"]) assert_matches_type(FindTextResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_text(self, client: Opencode) -> None: def test_streaming_response_text(self, client: Opencode) -> None:
with client.find.with_streaming_response.text( with client.find.with_streaming_response.text(
@ -129,7 +129,7 @@ class TestAsyncFind:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_files(self, async_client: AsyncOpencode) -> None: async def test_method_files(self, async_client: AsyncOpencode) -> None:
find = await async_client.find.files( find = await async_client.find.files(
@ -137,7 +137,7 @@ class TestAsyncFind:
) )
assert_matches_type(FindFilesResponse, find, path=["response"]) assert_matches_type(FindFilesResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_files(self, async_client: AsyncOpencode) -> None: async def test_raw_response_files(self, async_client: AsyncOpencode) -> None:
response = await async_client.find.with_raw_response.files( response = await async_client.find.with_raw_response.files(
@ -149,7 +149,7 @@ class TestAsyncFind:
find = await response.parse() find = await response.parse()
assert_matches_type(FindFilesResponse, find, path=["response"]) assert_matches_type(FindFilesResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_files(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_files(self, async_client: AsyncOpencode) -> None:
async with async_client.find.with_streaming_response.files( async with async_client.find.with_streaming_response.files(
@ -163,7 +163,7 @@ class TestAsyncFind:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_symbols(self, async_client: AsyncOpencode) -> None: async def test_method_symbols(self, async_client: AsyncOpencode) -> None:
find = await async_client.find.symbols( find = await async_client.find.symbols(
@ -171,7 +171,7 @@ class TestAsyncFind:
) )
assert_matches_type(FindSymbolsResponse, find, path=["response"]) assert_matches_type(FindSymbolsResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_symbols(self, async_client: AsyncOpencode) -> None: async def test_raw_response_symbols(self, async_client: AsyncOpencode) -> None:
response = await async_client.find.with_raw_response.symbols( response = await async_client.find.with_raw_response.symbols(
@ -183,7 +183,7 @@ class TestAsyncFind:
find = await response.parse() find = await response.parse()
assert_matches_type(FindSymbolsResponse, find, path=["response"]) assert_matches_type(FindSymbolsResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_symbols(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_symbols(self, async_client: AsyncOpencode) -> None:
async with async_client.find.with_streaming_response.symbols( async with async_client.find.with_streaming_response.symbols(
@ -197,7 +197,7 @@ class TestAsyncFind:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_text(self, async_client: AsyncOpencode) -> None: async def test_method_text(self, async_client: AsyncOpencode) -> None:
find = await async_client.find.text( find = await async_client.find.text(
@ -205,7 +205,7 @@ class TestAsyncFind:
) )
assert_matches_type(FindTextResponse, find, path=["response"]) assert_matches_type(FindTextResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_text(self, async_client: AsyncOpencode) -> None: async def test_raw_response_text(self, async_client: AsyncOpencode) -> None:
response = await async_client.find.with_raw_response.text( response = await async_client.find.with_raw_response.text(
@ -217,7 +217,7 @@ class TestAsyncFind:
find = await response.parse() find = await response.parse()
assert_matches_type(FindTextResponse, find, path=["response"]) assert_matches_type(FindTextResponse, find, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_text(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_text(self, async_client: AsyncOpencode) -> None:
async with async_client.find.with_streaming_response.text( async with async_client.find.with_streaming_response.text(

View file

@ -26,13 +26,13 @@ base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
class TestSession: class TestSession:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_create(self, client: Opencode) -> None: def test_method_create(self, client: Opencode) -> None:
session = client.session.create() session = client.session.create()
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_create(self, client: Opencode) -> None: def test_raw_response_create(self, client: Opencode) -> None:
response = client.session.with_raw_response.create() response = client.session.with_raw_response.create()
@ -42,7 +42,7 @@ class TestSession:
session = response.parse() session = response.parse()
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_create(self, client: Opencode) -> None: def test_streaming_response_create(self, client: Opencode) -> None:
with client.session.with_streaming_response.create() as response: with client.session.with_streaming_response.create() as response:
@ -54,13 +54,13 @@ class TestSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_list(self, client: Opencode) -> None: def test_method_list(self, client: Opencode) -> None:
session = client.session.list() session = client.session.list()
assert_matches_type(SessionListResponse, session, path=["response"]) assert_matches_type(SessionListResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_list(self, client: Opencode) -> None: def test_raw_response_list(self, client: Opencode) -> None:
response = client.session.with_raw_response.list() response = client.session.with_raw_response.list()
@ -70,7 +70,7 @@ class TestSession:
session = response.parse() session = response.parse()
assert_matches_type(SessionListResponse, session, path=["response"]) assert_matches_type(SessionListResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_list(self, client: Opencode) -> None: def test_streaming_response_list(self, client: Opencode) -> None:
with client.session.with_streaming_response.list() as response: with client.session.with_streaming_response.list() as response:
@ -82,7 +82,7 @@ class TestSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_delete(self, client: Opencode) -> None: def test_method_delete(self, client: Opencode) -> None:
session = client.session.delete( session = client.session.delete(
@ -90,7 +90,7 @@ class TestSession:
) )
assert_matches_type(SessionDeleteResponse, session, path=["response"]) assert_matches_type(SessionDeleteResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_delete(self, client: Opencode) -> None: def test_raw_response_delete(self, client: Opencode) -> None:
response = client.session.with_raw_response.delete( response = client.session.with_raw_response.delete(
@ -102,7 +102,7 @@ class TestSession:
session = response.parse() session = response.parse()
assert_matches_type(SessionDeleteResponse, session, path=["response"]) assert_matches_type(SessionDeleteResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_delete(self, client: Opencode) -> None: def test_streaming_response_delete(self, client: Opencode) -> None:
with client.session.with_streaming_response.delete( with client.session.with_streaming_response.delete(
@ -116,7 +116,7 @@ class TestSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_path_params_delete(self, client: Opencode) -> None: def test_path_params_delete(self, client: Opencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -124,7 +124,7 @@ class TestSession:
"", "",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_abort(self, client: Opencode) -> None: def test_method_abort(self, client: Opencode) -> None:
session = client.session.abort( session = client.session.abort(
@ -132,7 +132,7 @@ class TestSession:
) )
assert_matches_type(SessionAbortResponse, session, path=["response"]) assert_matches_type(SessionAbortResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_abort(self, client: Opencode) -> None: def test_raw_response_abort(self, client: Opencode) -> None:
response = client.session.with_raw_response.abort( response = client.session.with_raw_response.abort(
@ -144,7 +144,7 @@ class TestSession:
session = response.parse() session = response.parse()
assert_matches_type(SessionAbortResponse, session, path=["response"]) assert_matches_type(SessionAbortResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_abort(self, client: Opencode) -> None: def test_streaming_response_abort(self, client: Opencode) -> None:
with client.session.with_streaming_response.abort( with client.session.with_streaming_response.abort(
@ -158,7 +158,7 @@ class TestSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_path_params_abort(self, client: Opencode) -> None: def test_path_params_abort(self, client: Opencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -166,44 +166,58 @@ class TestSession:
"", "",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_chat(self, client: Opencode) -> None: def test_method_chat(self, client: Opencode) -> None:
session = client.session.chat( session = client.session.chat(
id="id", id="id",
message_id="messageID",
mode="mode",
model_id="modelID", model_id="modelID",
parts=[ parts=[
{ {
"id": "id", "text": "text",
"message_id": "messageID", "type": "text",
"mime": "mime",
"session_id": "sessionID",
"type": "file",
"url": "url",
} }
], ],
provider_id="providerID", provider_id="providerID",
) )
assert_matches_type(AssistantMessage, session, path=["response"]) assert_matches_type(AssistantMessage, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_chat_with_all_params(self, client: Opencode) -> None:
session = client.session.chat(
id="id",
model_id="modelID",
parts=[
{
"text": "text",
"type": "text",
"id": "id",
"synthetic": True,
"time": {
"start": 0,
"end": 0,
},
}
],
provider_id="providerID",
message_id="msg",
mode="mode",
system="system",
tools={"foo": True},
)
assert_matches_type(AssistantMessage, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_chat(self, client: Opencode) -> None: def test_raw_response_chat(self, client: Opencode) -> None:
response = client.session.with_raw_response.chat( response = client.session.with_raw_response.chat(
id="id", id="id",
message_id="messageID",
mode="mode",
model_id="modelID", model_id="modelID",
parts=[ parts=[
{ {
"id": "id", "text": "text",
"message_id": "messageID", "type": "text",
"mime": "mime",
"session_id": "sessionID",
"type": "file",
"url": "url",
} }
], ],
provider_id="providerID", provider_id="providerID",
@ -214,22 +228,16 @@ class TestSession:
session = response.parse() session = response.parse()
assert_matches_type(AssistantMessage, session, path=["response"]) assert_matches_type(AssistantMessage, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_chat(self, client: Opencode) -> None: def test_streaming_response_chat(self, client: Opencode) -> None:
with client.session.with_streaming_response.chat( with client.session.with_streaming_response.chat(
id="id", id="id",
message_id="messageID",
mode="mode",
model_id="modelID", model_id="modelID",
parts=[ parts=[
{ {
"id": "id", "text": "text",
"message_id": "messageID", "type": "text",
"mime": "mime",
"session_id": "sessionID",
"type": "file",
"url": "url",
} }
], ],
provider_id="providerID", provider_id="providerID",
@ -242,29 +250,23 @@ class TestSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_path_params_chat(self, client: Opencode) -> None: def test_path_params_chat(self, client: Opencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.session.with_raw_response.chat( client.session.with_raw_response.chat(
id="", id="",
message_id="messageID",
mode="mode",
model_id="modelID", model_id="modelID",
parts=[ parts=[
{ {
"id": "id", "text": "text",
"message_id": "messageID", "type": "text",
"mime": "mime",
"session_id": "sessionID",
"type": "file",
"url": "url",
} }
], ],
provider_id="providerID", provider_id="providerID",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_init(self, client: Opencode) -> None: def test_method_init(self, client: Opencode) -> None:
session = client.session.init( session = client.session.init(
@ -275,7 +277,7 @@ class TestSession:
) )
assert_matches_type(SessionInitResponse, session, path=["response"]) assert_matches_type(SessionInitResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_init(self, client: Opencode) -> None: def test_raw_response_init(self, client: Opencode) -> None:
response = client.session.with_raw_response.init( response = client.session.with_raw_response.init(
@ -290,7 +292,7 @@ class TestSession:
session = response.parse() session = response.parse()
assert_matches_type(SessionInitResponse, session, path=["response"]) assert_matches_type(SessionInitResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_init(self, client: Opencode) -> None: def test_streaming_response_init(self, client: Opencode) -> None:
with client.session.with_streaming_response.init( with client.session.with_streaming_response.init(
@ -307,7 +309,7 @@ class TestSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_path_params_init(self, client: Opencode) -> None: def test_path_params_init(self, client: Opencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -318,7 +320,7 @@ class TestSession:
provider_id="providerID", provider_id="providerID",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_messages(self, client: Opencode) -> None: def test_method_messages(self, client: Opencode) -> None:
session = client.session.messages( session = client.session.messages(
@ -326,7 +328,7 @@ class TestSession:
) )
assert_matches_type(SessionMessagesResponse, session, path=["response"]) assert_matches_type(SessionMessagesResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_messages(self, client: Opencode) -> None: def test_raw_response_messages(self, client: Opencode) -> None:
response = client.session.with_raw_response.messages( response = client.session.with_raw_response.messages(
@ -338,7 +340,7 @@ class TestSession:
session = response.parse() session = response.parse()
assert_matches_type(SessionMessagesResponse, session, path=["response"]) assert_matches_type(SessionMessagesResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_messages(self, client: Opencode) -> None: def test_streaming_response_messages(self, client: Opencode) -> None:
with client.session.with_streaming_response.messages( with client.session.with_streaming_response.messages(
@ -352,7 +354,7 @@ class TestSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_path_params_messages(self, client: Opencode) -> None: def test_path_params_messages(self, client: Opencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -360,7 +362,63 @@ class TestSession:
"", "",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_revert(self, client: Opencode) -> None:
session = client.session.revert(
id="id",
message_id="msg",
)
assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_revert_with_all_params(self, client: Opencode) -> None:
session = client.session.revert(
id="id",
message_id="msg",
part_id="prt",
)
assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_revert(self, client: Opencode) -> None:
response = client.session.with_raw_response.revert(
id="id",
message_id="msg",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
session = response.parse()
assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_revert(self, client: Opencode) -> None:
with client.session.with_streaming_response.revert(
id="id",
message_id="msg",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
session = response.parse()
assert_matches_type(Session, session, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_revert(self, client: Opencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.session.with_raw_response.revert(
id="",
message_id="msg",
)
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_share(self, client: Opencode) -> None: def test_method_share(self, client: Opencode) -> None:
session = client.session.share( session = client.session.share(
@ -368,7 +426,7 @@ class TestSession:
) )
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_share(self, client: Opencode) -> None: def test_raw_response_share(self, client: Opencode) -> None:
response = client.session.with_raw_response.share( response = client.session.with_raw_response.share(
@ -380,7 +438,7 @@ class TestSession:
session = response.parse() session = response.parse()
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_share(self, client: Opencode) -> None: def test_streaming_response_share(self, client: Opencode) -> None:
with client.session.with_streaming_response.share( with client.session.with_streaming_response.share(
@ -394,7 +452,7 @@ class TestSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_path_params_share(self, client: Opencode) -> None: def test_path_params_share(self, client: Opencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -402,7 +460,7 @@ class TestSession:
"", "",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_summarize(self, client: Opencode) -> None: def test_method_summarize(self, client: Opencode) -> None:
session = client.session.summarize( session = client.session.summarize(
@ -412,7 +470,7 @@ class TestSession:
) )
assert_matches_type(SessionSummarizeResponse, session, path=["response"]) assert_matches_type(SessionSummarizeResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_summarize(self, client: Opencode) -> None: def test_raw_response_summarize(self, client: Opencode) -> None:
response = client.session.with_raw_response.summarize( response = client.session.with_raw_response.summarize(
@ -426,7 +484,7 @@ class TestSession:
session = response.parse() session = response.parse()
assert_matches_type(SessionSummarizeResponse, session, path=["response"]) assert_matches_type(SessionSummarizeResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_summarize(self, client: Opencode) -> None: def test_streaming_response_summarize(self, client: Opencode) -> None:
with client.session.with_streaming_response.summarize( with client.session.with_streaming_response.summarize(
@ -442,7 +500,7 @@ class TestSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_path_params_summarize(self, client: Opencode) -> None: def test_path_params_summarize(self, client: Opencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -452,7 +510,49 @@ class TestSession:
provider_id="providerID", provider_id="providerID",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_unrevert(self, client: Opencode) -> None:
session = client.session.unrevert(
"id",
)
assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_unrevert(self, client: Opencode) -> None:
response = client.session.with_raw_response.unrevert(
"id",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
session = response.parse()
assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_unrevert(self, client: Opencode) -> None:
with client.session.with_streaming_response.unrevert(
"id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
session = response.parse()
assert_matches_type(Session, session, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_unrevert(self, client: Opencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.session.with_raw_response.unrevert(
"",
)
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_method_unshare(self, client: Opencode) -> None: def test_method_unshare(self, client: Opencode) -> None:
session = client.session.unshare( session = client.session.unshare(
@ -460,7 +560,7 @@ class TestSession:
) )
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_raw_response_unshare(self, client: Opencode) -> None: def test_raw_response_unshare(self, client: Opencode) -> None:
response = client.session.with_raw_response.unshare( response = client.session.with_raw_response.unshare(
@ -472,7 +572,7 @@ class TestSession:
session = response.parse() session = response.parse()
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_streaming_response_unshare(self, client: Opencode) -> None: def test_streaming_response_unshare(self, client: Opencode) -> None:
with client.session.with_streaming_response.unshare( with client.session.with_streaming_response.unshare(
@ -486,7 +586,7 @@ class TestSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
def test_path_params_unshare(self, client: Opencode) -> None: def test_path_params_unshare(self, client: Opencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -500,13 +600,13 @@ class TestAsyncSession:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_create(self, async_client: AsyncOpencode) -> None: async def test_method_create(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.create() session = await async_client.session.create()
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_create(self, async_client: AsyncOpencode) -> None: async def test_raw_response_create(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.create() response = await async_client.session.with_raw_response.create()
@ -516,7 +616,7 @@ class TestAsyncSession:
session = await response.parse() session = await response.parse()
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_create(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_create(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.create() as response: async with async_client.session.with_streaming_response.create() as response:
@ -528,13 +628,13 @@ class TestAsyncSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_list(self, async_client: AsyncOpencode) -> None: async def test_method_list(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.list() session = await async_client.session.list()
assert_matches_type(SessionListResponse, session, path=["response"]) assert_matches_type(SessionListResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_list(self, async_client: AsyncOpencode) -> None: async def test_raw_response_list(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.list() response = await async_client.session.with_raw_response.list()
@ -544,7 +644,7 @@ class TestAsyncSession:
session = await response.parse() session = await response.parse()
assert_matches_type(SessionListResponse, session, path=["response"]) assert_matches_type(SessionListResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_list(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_list(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.list() as response: async with async_client.session.with_streaming_response.list() as response:
@ -556,7 +656,7 @@ class TestAsyncSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_delete(self, async_client: AsyncOpencode) -> None: async def test_method_delete(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.delete( session = await async_client.session.delete(
@ -564,7 +664,7 @@ class TestAsyncSession:
) )
assert_matches_type(SessionDeleteResponse, session, path=["response"]) assert_matches_type(SessionDeleteResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_delete(self, async_client: AsyncOpencode) -> None: async def test_raw_response_delete(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.delete( response = await async_client.session.with_raw_response.delete(
@ -576,7 +676,7 @@ class TestAsyncSession:
session = await response.parse() session = await response.parse()
assert_matches_type(SessionDeleteResponse, session, path=["response"]) assert_matches_type(SessionDeleteResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_delete(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_delete(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.delete( async with async_client.session.with_streaming_response.delete(
@ -590,7 +690,7 @@ class TestAsyncSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_path_params_delete(self, async_client: AsyncOpencode) -> None: async def test_path_params_delete(self, async_client: AsyncOpencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -598,7 +698,7 @@ class TestAsyncSession:
"", "",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_abort(self, async_client: AsyncOpencode) -> None: async def test_method_abort(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.abort( session = await async_client.session.abort(
@ -606,7 +706,7 @@ class TestAsyncSession:
) )
assert_matches_type(SessionAbortResponse, session, path=["response"]) assert_matches_type(SessionAbortResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_abort(self, async_client: AsyncOpencode) -> None: async def test_raw_response_abort(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.abort( response = await async_client.session.with_raw_response.abort(
@ -618,7 +718,7 @@ class TestAsyncSession:
session = await response.parse() session = await response.parse()
assert_matches_type(SessionAbortResponse, session, path=["response"]) assert_matches_type(SessionAbortResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_abort(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_abort(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.abort( async with async_client.session.with_streaming_response.abort(
@ -632,7 +732,7 @@ class TestAsyncSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_path_params_abort(self, async_client: AsyncOpencode) -> None: async def test_path_params_abort(self, async_client: AsyncOpencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -640,44 +740,58 @@ class TestAsyncSession:
"", "",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_chat(self, async_client: AsyncOpencode) -> None: async def test_method_chat(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.chat( session = await async_client.session.chat(
id="id", id="id",
message_id="messageID",
mode="mode",
model_id="modelID", model_id="modelID",
parts=[ parts=[
{ {
"id": "id", "text": "text",
"message_id": "messageID", "type": "text",
"mime": "mime",
"session_id": "sessionID",
"type": "file",
"url": "url",
} }
], ],
provider_id="providerID", provider_id="providerID",
) )
assert_matches_type(AssistantMessage, session, path=["response"]) assert_matches_type(AssistantMessage, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_chat_with_all_params(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.chat(
id="id",
model_id="modelID",
parts=[
{
"text": "text",
"type": "text",
"id": "id",
"synthetic": True,
"time": {
"start": 0,
"end": 0,
},
}
],
provider_id="providerID",
message_id="msg",
mode="mode",
system="system",
tools={"foo": True},
)
assert_matches_type(AssistantMessage, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_chat(self, async_client: AsyncOpencode) -> None: async def test_raw_response_chat(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.chat( response = await async_client.session.with_raw_response.chat(
id="id", id="id",
message_id="messageID",
mode="mode",
model_id="modelID", model_id="modelID",
parts=[ parts=[
{ {
"id": "id", "text": "text",
"message_id": "messageID", "type": "text",
"mime": "mime",
"session_id": "sessionID",
"type": "file",
"url": "url",
} }
], ],
provider_id="providerID", provider_id="providerID",
@ -688,22 +802,16 @@ class TestAsyncSession:
session = await response.parse() session = await response.parse()
assert_matches_type(AssistantMessage, session, path=["response"]) assert_matches_type(AssistantMessage, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_chat(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_chat(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.chat( async with async_client.session.with_streaming_response.chat(
id="id", id="id",
message_id="messageID",
mode="mode",
model_id="modelID", model_id="modelID",
parts=[ parts=[
{ {
"id": "id", "text": "text",
"message_id": "messageID", "type": "text",
"mime": "mime",
"session_id": "sessionID",
"type": "file",
"url": "url",
} }
], ],
provider_id="providerID", provider_id="providerID",
@ -716,29 +824,23 @@ class TestAsyncSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_path_params_chat(self, async_client: AsyncOpencode) -> None: async def test_path_params_chat(self, async_client: AsyncOpencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.session.with_raw_response.chat( await async_client.session.with_raw_response.chat(
id="", id="",
message_id="messageID",
mode="mode",
model_id="modelID", model_id="modelID",
parts=[ parts=[
{ {
"id": "id", "text": "text",
"message_id": "messageID", "type": "text",
"mime": "mime",
"session_id": "sessionID",
"type": "file",
"url": "url",
} }
], ],
provider_id="providerID", provider_id="providerID",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_init(self, async_client: AsyncOpencode) -> None: async def test_method_init(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.init( session = await async_client.session.init(
@ -749,7 +851,7 @@ class TestAsyncSession:
) )
assert_matches_type(SessionInitResponse, session, path=["response"]) assert_matches_type(SessionInitResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_init(self, async_client: AsyncOpencode) -> None: async def test_raw_response_init(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.init( response = await async_client.session.with_raw_response.init(
@ -764,7 +866,7 @@ class TestAsyncSession:
session = await response.parse() session = await response.parse()
assert_matches_type(SessionInitResponse, session, path=["response"]) assert_matches_type(SessionInitResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_init(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_init(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.init( async with async_client.session.with_streaming_response.init(
@ -781,7 +883,7 @@ class TestAsyncSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_path_params_init(self, async_client: AsyncOpencode) -> None: async def test_path_params_init(self, async_client: AsyncOpencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -792,7 +894,7 @@ class TestAsyncSession:
provider_id="providerID", provider_id="providerID",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_messages(self, async_client: AsyncOpencode) -> None: async def test_method_messages(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.messages( session = await async_client.session.messages(
@ -800,7 +902,7 @@ class TestAsyncSession:
) )
assert_matches_type(SessionMessagesResponse, session, path=["response"]) assert_matches_type(SessionMessagesResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_messages(self, async_client: AsyncOpencode) -> None: async def test_raw_response_messages(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.messages( response = await async_client.session.with_raw_response.messages(
@ -812,7 +914,7 @@ class TestAsyncSession:
session = await response.parse() session = await response.parse()
assert_matches_type(SessionMessagesResponse, session, path=["response"]) assert_matches_type(SessionMessagesResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_messages(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_messages(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.messages( async with async_client.session.with_streaming_response.messages(
@ -826,7 +928,7 @@ class TestAsyncSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_path_params_messages(self, async_client: AsyncOpencode) -> None: async def test_path_params_messages(self, async_client: AsyncOpencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -834,7 +936,63 @@ class TestAsyncSession:
"", "",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_revert(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.revert(
id="id",
message_id="msg",
)
assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_revert_with_all_params(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.revert(
id="id",
message_id="msg",
part_id="prt",
)
assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_revert(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.revert(
id="id",
message_id="msg",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
session = await response.parse()
assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_revert(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.revert(
id="id",
message_id="msg",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
session = await response.parse()
assert_matches_type(Session, session, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_revert(self, async_client: AsyncOpencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.session.with_raw_response.revert(
id="",
message_id="msg",
)
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_share(self, async_client: AsyncOpencode) -> None: async def test_method_share(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.share( session = await async_client.session.share(
@ -842,7 +1000,7 @@ class TestAsyncSession:
) )
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_share(self, async_client: AsyncOpencode) -> None: async def test_raw_response_share(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.share( response = await async_client.session.with_raw_response.share(
@ -854,7 +1012,7 @@ class TestAsyncSession:
session = await response.parse() session = await response.parse()
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_share(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_share(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.share( async with async_client.session.with_streaming_response.share(
@ -868,7 +1026,7 @@ class TestAsyncSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_path_params_share(self, async_client: AsyncOpencode) -> None: async def test_path_params_share(self, async_client: AsyncOpencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -876,7 +1034,7 @@ class TestAsyncSession:
"", "",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_summarize(self, async_client: AsyncOpencode) -> None: async def test_method_summarize(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.summarize( session = await async_client.session.summarize(
@ -886,7 +1044,7 @@ class TestAsyncSession:
) )
assert_matches_type(SessionSummarizeResponse, session, path=["response"]) assert_matches_type(SessionSummarizeResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_summarize(self, async_client: AsyncOpencode) -> None: async def test_raw_response_summarize(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.summarize( response = await async_client.session.with_raw_response.summarize(
@ -900,7 +1058,7 @@ class TestAsyncSession:
session = await response.parse() session = await response.parse()
assert_matches_type(SessionSummarizeResponse, session, path=["response"]) assert_matches_type(SessionSummarizeResponse, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_summarize(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_summarize(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.summarize( async with async_client.session.with_streaming_response.summarize(
@ -916,7 +1074,7 @@ class TestAsyncSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_path_params_summarize(self, async_client: AsyncOpencode) -> None: async def test_path_params_summarize(self, async_client: AsyncOpencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
@ -926,7 +1084,49 @@ class TestAsyncSession:
provider_id="providerID", provider_id="providerID",
) )
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_unrevert(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.unrevert(
"id",
)
assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_unrevert(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.unrevert(
"id",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
session = await response.parse()
assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_unrevert(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.unrevert(
"id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
session = await response.parse()
assert_matches_type(Session, session, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_unrevert(self, async_client: AsyncOpencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.session.with_raw_response.unrevert(
"",
)
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_method_unshare(self, async_client: AsyncOpencode) -> None: async def test_method_unshare(self, async_client: AsyncOpencode) -> None:
session = await async_client.session.unshare( session = await async_client.session.unshare(
@ -934,7 +1134,7 @@ class TestAsyncSession:
) )
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_raw_response_unshare(self, async_client: AsyncOpencode) -> None: async def test_raw_response_unshare(self, async_client: AsyncOpencode) -> None:
response = await async_client.session.with_raw_response.unshare( response = await async_client.session.with_raw_response.unshare(
@ -946,7 +1146,7 @@ class TestAsyncSession:
session = await response.parse() session = await response.parse()
assert_matches_type(Session, session, path=["response"]) assert_matches_type(Session, session, path=["response"])
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_streaming_response_unshare(self, async_client: AsyncOpencode) -> None: async def test_streaming_response_unshare(self, async_client: AsyncOpencode) -> None:
async with async_client.session.with_streaming_response.unshare( async with async_client.session.with_streaming_response.unshare(
@ -960,7 +1160,7 @@ class TestAsyncSession:
assert cast(Any, response.is_closed) is True assert cast(Any, response.is_closed) is True
@pytest.mark.skip() @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize @parametrize
async def test_path_params_unshare(self, async_client: AsyncOpencode) -> None: async def test_path_params_unshare(self, async_client: AsyncOpencode) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):

View file

@ -0,0 +1,148 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
import os
from typing import Any, cast
import pytest
from opencode_ai import Opencode, AsyncOpencode
from tests.utils import assert_matches_type
from opencode_ai.types import TuiOpenHelpResponse, TuiAppendPromptResponse
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
class TestTui:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_append_prompt(self, client: Opencode) -> None:
tui = client.tui.append_prompt(
text="text",
)
assert_matches_type(TuiAppendPromptResponse, tui, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_append_prompt(self, client: Opencode) -> None:
response = client.tui.with_raw_response.append_prompt(
text="text",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tui = response.parse()
assert_matches_type(TuiAppendPromptResponse, tui, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_append_prompt(self, client: Opencode) -> None:
with client.tui.with_streaming_response.append_prompt(
text="text",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tui = response.parse()
assert_matches_type(TuiAppendPromptResponse, tui, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_open_help(self, client: Opencode) -> None:
tui = client.tui.open_help()
assert_matches_type(TuiOpenHelpResponse, tui, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_open_help(self, client: Opencode) -> None:
response = client.tui.with_raw_response.open_help()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tui = response.parse()
assert_matches_type(TuiOpenHelpResponse, tui, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_open_help(self, client: Opencode) -> None:
with client.tui.with_streaming_response.open_help() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tui = response.parse()
assert_matches_type(TuiOpenHelpResponse, tui, path=["response"])
assert cast(Any, response.is_closed) is True
class TestAsyncTui:
parametrize = pytest.mark.parametrize(
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_append_prompt(self, async_client: AsyncOpencode) -> None:
tui = await async_client.tui.append_prompt(
text="text",
)
assert_matches_type(TuiAppendPromptResponse, tui, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_append_prompt(self, async_client: AsyncOpencode) -> None:
response = await async_client.tui.with_raw_response.append_prompt(
text="text",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tui = await response.parse()
assert_matches_type(TuiAppendPromptResponse, tui, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_append_prompt(self, async_client: AsyncOpencode) -> None:
async with async_client.tui.with_streaming_response.append_prompt(
text="text",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tui = await response.parse()
assert_matches_type(TuiAppendPromptResponse, tui, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_open_help(self, async_client: AsyncOpencode) -> None:
tui = await async_client.tui.open_help()
assert_matches_type(TuiOpenHelpResponse, tui, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_open_help(self, async_client: AsyncOpencode) -> None:
response = await async_client.tui.with_raw_response.open_help()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tui = await response.parse()
assert_matches_type(TuiOpenHelpResponse, tui, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_open_help(self, async_client: AsyncOpencode) -> None:
async with async_client.tui.with_streaming_response.open_help() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tui = await response.parse()
assert_matches_type(TuiOpenHelpResponse, tui, path=["response"])
assert cast(Any, response.is_closed) is True

View file

@ -1,5 +1,5 @@
import json import json
from typing import Any, Dict, List, Union, Optional, cast from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional, cast
from datetime import datetime, timezone from datetime import datetime, timezone
from typing_extensions import Literal, Annotated, TypeAliasType from typing_extensions import Literal, Annotated, TypeAliasType
@ -934,3 +934,30 @@ def test_nested_discriminated_union() -> None:
) )
assert isinstance(model, Type1) assert isinstance(model, Type1)
assert isinstance(model.value, InnerType2) assert isinstance(model.value, InnerType2)
@pytest.mark.skipif(not PYDANTIC_V2, reason="this is only supported in pydantic v2 for now")
def test_extra_properties() -> None:
class Item(BaseModel):
prop: int
class Model(BaseModel):
__pydantic_extra__: Dict[str, Item] = Field(init=False) # pyright: ignore[reportIncompatibleVariableOverride]
other: str
if TYPE_CHECKING:
def __getattr__(self, attr: str) -> Item: ...
model = construct_type(
type_=Model,
value={
"a": {"prop": 1},
"other": "foo",
},
)
assert isinstance(model, Model)
assert model.a.prop == 1
assert isinstance(model.a, Item)
assert model.other == "foo"