mirror of
https://github.com/anomalyco/opencode-sdk-python.git
synced 2026-05-01 22:10:28 +00:00
Merge pull request #2 from sst/release-please--branches--main--changes--next
release: 0.1.0-alpha.2
This commit is contained in:
commit
ff1e22fcec
111 changed files with 170 additions and 156 deletions
|
|
@ -1,3 +1,3 @@
|
||||||
{
|
{
|
||||||
".": "0.1.0-alpha.1"
|
".": "0.1.0-alpha.2"
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
configured_endpoints: 16
|
configured_endpoints: 16
|
||||||
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-3c79948402e96d2aae6e46095db2cf80759750d1b042d6f91281a72c415b14de.yml
|
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-3c79948402e96d2aae6e46095db2cf80759750d1b042d6f91281a72c415b14de.yml
|
||||||
openapi_spec_hash: f9c2fc5988f0a30397929995c2be2c85
|
openapi_spec_hash: f9c2fc5988f0a30397929995c2be2c85
|
||||||
config_hash: fddca9bc092956a3e82f3f3bdba448d1
|
config_hash: d4c4c71d9a092267df2d4ab61fd89e63
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.1.0-alpha.2 (2025-06-27)
|
||||||
|
|
||||||
|
Full Changelog: [v0.1.0-alpha.1...v0.1.0-alpha.2](https://github.com/sst/opencode-sdk-python/compare/v0.1.0-alpha.1...v0.1.0-alpha.2)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **api:** update via SDK Studio ([a6cf7c5](https://github.com/sst/opencode-sdk-python/commit/a6cf7c5b2a411503294088428ca7918226eca161))
|
||||||
|
|
||||||
## 0.1.0-alpha.1 (2025-06-27)
|
## 0.1.0-alpha.1 (2025-06-27)
|
||||||
|
|
||||||
Full Changelog: [v0.0.1-alpha.0...v0.1.0-alpha.1](https://github.com/sst/opencode-sdk-python/compare/v0.0.1-alpha.0...v0.1.0-alpha.1)
|
Full Changelog: [v0.0.1-alpha.0...v0.1.0-alpha.1](https://github.com/sst/opencode-sdk-python/compare/v0.0.1-alpha.0...v0.1.0-alpha.1)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ $ pip install -r requirements-dev.lock
|
||||||
|
|
||||||
Most of the SDK is generated code. Modifications to code will be persisted between generations, but may
|
Most of the SDK is generated code. Modifications to code will be persisted between generations, but may
|
||||||
result in merge conflicts between manual patches and changes from the generator. The generator will never
|
result in merge conflicts between manual patches and changes from the generator. The generator will never
|
||||||
modify the contents of the `src/opencode/lib/` and `examples/` directories.
|
modify the contents of the `src/opencode_ai/lib/` and `examples/` directories.
|
||||||
|
|
||||||
## Adding and running examples
|
## Adding and running examples
|
||||||
|
|
||||||
|
|
|
||||||
48
README.md
48
README.md
|
|
@ -1,6 +1,6 @@
|
||||||
# Opencode Python API library
|
# Opencode Python API library
|
||||||
|
|
||||||
[>)](https://pypi.org/project/opencode/)
|
[>)](https://pypi.org/project/opencode-ai/)
|
||||||
|
|
||||||
The Opencode Python library provides convenient access to the Opencode REST API from any Python 3.8+
|
The Opencode Python library provides convenient access to the Opencode REST API from any Python 3.8+
|
||||||
application. The library includes type definitions for all request params and response fields,
|
application. The library includes type definitions for all request params and response fields,
|
||||||
|
|
@ -16,7 +16,7 @@ The REST API documentation can be found on [opencode.ai](https://opencode.ai/doc
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# install from PyPI
|
# install from PyPI
|
||||||
pip install --pre opencode
|
pip install --pre opencode-ai
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
@ -24,7 +24,7 @@ pip install --pre opencode
|
||||||
The full API of this library can be found in [api.md](api.md).
|
The full API of this library can be found in [api.md](api.md).
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from opencode import Opencode
|
from opencode_ai import Opencode
|
||||||
|
|
||||||
client = Opencode()
|
client = Opencode()
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ Simply import `AsyncOpencode` instead of `Opencode` and use `await` with each AP
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
from opencode import AsyncOpencode
|
from opencode_ai import AsyncOpencode
|
||||||
|
|
||||||
client = AsyncOpencode()
|
client = AsyncOpencode()
|
||||||
|
|
||||||
|
|
@ -59,15 +59,15 @@ You can enable this by installing `aiohttp`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# install from PyPI
|
# install from PyPI
|
||||||
pip install --pre opencode[aiohttp]
|
pip install --pre opencode-ai[aiohttp]
|
||||||
```
|
```
|
||||||
|
|
||||||
Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:
|
Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
from opencode import DefaultAioHttpClient
|
from opencode_ai import DefaultAioHttpClient
|
||||||
from opencode import AsyncOpencode
|
from opencode_ai import AsyncOpencode
|
||||||
|
|
||||||
|
|
||||||
async def main() -> None:
|
async def main() -> None:
|
||||||
|
|
@ -91,27 +91,27 @@ Typed requests and responses provide autocomplete and documentation within your
|
||||||
|
|
||||||
## Handling errors
|
## Handling errors
|
||||||
|
|
||||||
When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `opencode.APIConnectionError` is raised.
|
When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `opencode_ai.APIConnectionError` is raised.
|
||||||
|
|
||||||
When the API returns a non-success status code (that is, 4xx or 5xx
|
When the API returns a non-success status code (that is, 4xx or 5xx
|
||||||
response), a subclass of `opencode.APIStatusError` is raised, containing `status_code` and `response` properties.
|
response), a subclass of `opencode_ai.APIStatusError` is raised, containing `status_code` and `response` properties.
|
||||||
|
|
||||||
All errors inherit from `opencode.APIError`.
|
All errors inherit from `opencode_ai.APIError`.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import opencode
|
import opencode_ai
|
||||||
from opencode import Opencode
|
from opencode_ai import Opencode
|
||||||
|
|
||||||
client = Opencode()
|
client = Opencode()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client.event.list()
|
client.event.list()
|
||||||
except opencode.APIConnectionError as e:
|
except opencode_ai.APIConnectionError as e:
|
||||||
print("The server could not be reached")
|
print("The server could not be reached")
|
||||||
print(e.__cause__) # an underlying Exception, likely raised within httpx.
|
print(e.__cause__) # an underlying Exception, likely raised within httpx.
|
||||||
except opencode.RateLimitError as e:
|
except opencode_ai.RateLimitError as e:
|
||||||
print("A 429 status code was received; we should back off a bit.")
|
print("A 429 status code was received; we should back off a bit.")
|
||||||
except opencode.APIStatusError as e:
|
except opencode_ai.APIStatusError as e:
|
||||||
print("Another non-200-range status code was received")
|
print("Another non-200-range status code was received")
|
||||||
print(e.status_code)
|
print(e.status_code)
|
||||||
print(e.response)
|
print(e.response)
|
||||||
|
|
@ -139,7 +139,7 @@ Connection errors (for example, due to a network connectivity problem), 408 Requ
|
||||||
You can use the `max_retries` option to configure or disable retry settings:
|
You can use the `max_retries` option to configure or disable retry settings:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from opencode import Opencode
|
from opencode_ai import Opencode
|
||||||
|
|
||||||
# Configure the default for all requests:
|
# Configure the default for all requests:
|
||||||
client = Opencode(
|
client = Opencode(
|
||||||
|
|
@ -157,7 +157,7 @@ By default requests time out after 1 minute. You can configure this with a `time
|
||||||
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:
|
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from opencode import Opencode
|
from opencode_ai import Opencode
|
||||||
|
|
||||||
# Configure the default for all requests:
|
# Configure the default for all requests:
|
||||||
client = Opencode(
|
client = Opencode(
|
||||||
|
|
@ -209,7 +209,7 @@ if response.my_field is None:
|
||||||
The "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g.,
|
The "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g.,
|
||||||
|
|
||||||
```py
|
```py
|
||||||
from opencode import Opencode
|
from opencode_ai import Opencode
|
||||||
|
|
||||||
client = Opencode()
|
client = Opencode()
|
||||||
response = client.event.with_raw_response.list()
|
response = client.event.with_raw_response.list()
|
||||||
|
|
@ -219,9 +219,9 @@ event = response.parse() # get the object that `event.list()` would have return
|
||||||
print(event)
|
print(event)
|
||||||
```
|
```
|
||||||
|
|
||||||
These methods return an [`APIResponse`](https://github.com/sst/opencode-sdk-python/tree/main/src/opencode/_response.py) object.
|
These methods return an [`APIResponse`](https://github.com/sst/opencode-sdk-python/tree/main/src/opencode_ai/_response.py) object.
|
||||||
|
|
||||||
The async client returns an [`AsyncAPIResponse`](https://github.com/sst/opencode-sdk-python/tree/main/src/opencode/_response.py) with the same structure, the only difference being `await`able methods for reading the response content.
|
The async client returns an [`AsyncAPIResponse`](https://github.com/sst/opencode-sdk-python/tree/main/src/opencode_ai/_response.py) with the same structure, the only difference being `await`able methods for reading the response content.
|
||||||
|
|
||||||
#### `.with_streaming_response`
|
#### `.with_streaming_response`
|
||||||
|
|
||||||
|
|
@ -283,7 +283,7 @@ You can directly override the [httpx client](https://www.python-httpx.org/api/#c
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import httpx
|
import httpx
|
||||||
from opencode import Opencode, DefaultHttpxClient
|
from opencode_ai import Opencode, DefaultHttpxClient
|
||||||
|
|
||||||
client = Opencode(
|
client = Opencode(
|
||||||
# Or use the `OPENCODE_BASE_URL` env var
|
# Or use the `OPENCODE_BASE_URL` env var
|
||||||
|
|
@ -306,7 +306,7 @@ client.with_options(http_client=DefaultHttpxClient(...))
|
||||||
By default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting.
|
By default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting.
|
||||||
|
|
||||||
```py
|
```py
|
||||||
from opencode import Opencode
|
from opencode_ai import Opencode
|
||||||
|
|
||||||
with Opencode() as client:
|
with Opencode() as client:
|
||||||
# make requests here
|
# make requests here
|
||||||
|
|
@ -334,8 +334,8 @@ If you've upgraded to the latest version but aren't seeing any new features you
|
||||||
You can determine the version that is being used at runtime with:
|
You can determine the version that is being used at runtime with:
|
||||||
|
|
||||||
```py
|
```py
|
||||||
import opencode
|
import opencode_ai
|
||||||
print(opencode.__version__)
|
print(opencode_ai.__version__)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ or products provided by Opencode, please follow the respective company's securit
|
||||||
|
|
||||||
### Opencode Terms and Policies
|
### Opencode Terms and Policies
|
||||||
|
|
||||||
Please contact support@sst.dev for any questions or concerns regarding the security of our services.
|
Please contact hello@sst.dev for any questions or concerns regarding the security of our services.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
44
api.md
44
api.md
|
|
@ -1,7 +1,7 @@
|
||||||
# Shared Types
|
# Shared Types
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from opencode.types import ProviderAuthError, UnknownError
|
from opencode_ai.types import ProviderAuthError, UnknownError
|
||||||
```
|
```
|
||||||
|
|
||||||
# Event
|
# Event
|
||||||
|
|
@ -9,44 +9,44 @@ from opencode.types import ProviderAuthError, UnknownError
|
||||||
Types:
|
Types:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from opencode.types import EventListResponse
|
from opencode_ai.types import EventListResponse
|
||||||
```
|
```
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
|
|
||||||
- <code title="get /event">client.event.<a href="./src/opencode/resources/event.py">list</a>() -> <a href="./src/opencode/types/event_list_response.py">EventListResponse</a></code>
|
- <code title="get /event">client.event.<a href="./src/opencode_ai/resources/event.py">list</a>() -> <a href="./src/opencode_ai/types/event_list_response.py">EventListResponse</a></code>
|
||||||
|
|
||||||
# App
|
# App
|
||||||
|
|
||||||
Types:
|
Types:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from opencode.types import App, AppInitResponse
|
from opencode_ai.types import App, AppInitResponse
|
||||||
```
|
```
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
|
|
||||||
- <code title="get /app">client.app.<a href="./src/opencode/resources/app.py">get</a>() -> <a href="./src/opencode/types/app.py">App</a></code>
|
- <code title="get /app">client.app.<a href="./src/opencode_ai/resources/app.py">get</a>() -> <a href="./src/opencode_ai/types/app.py">App</a></code>
|
||||||
- <code title="post /app/init">client.app.<a href="./src/opencode/resources/app.py">init</a>() -> <a href="./src/opencode/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>
|
||||||
|
|
||||||
# File
|
# File
|
||||||
|
|
||||||
Types:
|
Types:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from opencode.types import FileSearchResponse
|
from opencode_ai.types import FileSearchResponse
|
||||||
```
|
```
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
|
|
||||||
- <code title="get /file">client.file.<a href="./src/opencode/resources/file.py">search</a>(\*\*<a href="src/opencode/types/file_search_params.py">params</a>) -> <a href="./src/opencode/types/file_search_response.py">FileSearchResponse</a></code>
|
- <code title="get /file">client.file.<a href="./src/opencode_ai/resources/file.py">search</a>(\*\*<a href="src/opencode_ai/types/file_search_params.py">params</a>) -> <a href="./src/opencode_ai/types/file_search_response.py">FileSearchResponse</a></code>
|
||||||
|
|
||||||
# Config
|
# Config
|
||||||
|
|
||||||
Types:
|
Types:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from opencode.types import (
|
from opencode_ai.types import (
|
||||||
Config,
|
Config,
|
||||||
Keybinds,
|
Keybinds,
|
||||||
McpLocal,
|
McpLocal,
|
||||||
|
|
@ -59,15 +59,15 @@ from opencode.types import (
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
|
|
||||||
- <code title="get /config">client.config.<a href="./src/opencode/resources/config.py">get</a>() -> <a href="./src/opencode/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/resources/config.py">providers</a>() -> <a href="./src/opencode/types/config_providers_response.py">ConfigProvidersResponse</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
|
||||||
|
|
||||||
Types:
|
Types:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from opencode.types import (
|
from opencode_ai.types import (
|
||||||
FilePart,
|
FilePart,
|
||||||
Message,
|
Message,
|
||||||
MessagePart,
|
MessagePart,
|
||||||
|
|
@ -91,13 +91,13 @@ from opencode.types import (
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
|
|
||||||
- <code title="post /session">client.session.<a href="./src/opencode/resources/session.py">create</a>() -> <a href="./src/opencode/types/session.py">Session</a></code>
|
- <code title="post /session">client.session.<a href="./src/opencode_ai/resources/session.py">create</a>() -> <a href="./src/opencode_ai/types/session.py">Session</a></code>
|
||||||
- <code title="get /session">client.session.<a href="./src/opencode/resources/session.py">list</a>() -> <a href="./src/opencode/types/session_list_response.py">SessionListResponse</a></code>
|
- <code title="get /session">client.session.<a href="./src/opencode_ai/resources/session.py">list</a>() -> <a href="./src/opencode_ai/types/session_list_response.py">SessionListResponse</a></code>
|
||||||
- <code title="delete /session/{id}">client.session.<a href="./src/opencode/resources/session.py">delete</a>(id) -> <a href="./src/opencode/types/session_delete_response.py">SessionDeleteResponse</a></code>
|
- <code title="delete /session/{id}">client.session.<a href="./src/opencode_ai/resources/session.py">delete</a>(id) -> <a href="./src/opencode_ai/types/session_delete_response.py">SessionDeleteResponse</a></code>
|
||||||
- <code title="post /session/{id}/abort">client.session.<a href="./src/opencode/resources/session.py">abort</a>(id) -> <a href="./src/opencode/types/session_abort_response.py">SessionAbortResponse</a></code>
|
- <code title="post /session/{id}/abort">client.session.<a href="./src/opencode_ai/resources/session.py">abort</a>(id) -> <a href="./src/opencode_ai/types/session_abort_response.py">SessionAbortResponse</a></code>
|
||||||
- <code title="post /session/{id}/message">client.session.<a href="./src/opencode/resources/session.py">chat</a>(id, \*\*<a href="src/opencode/types/session_chat_params.py">params</a>) -> <a href="./src/opencode/types/message.py">Message</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/message.py">Message</a></code>
|
||||||
- <code title="post /session/{id}/init">client.session.<a href="./src/opencode/resources/session.py">init</a>(id, \*\*<a href="src/opencode/types/session_init_params.py">params</a>) -> <a href="./src/opencode/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/resources/session.py">messages</a>(id) -> <a href="./src/opencode/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}/share">client.session.<a href="./src/opencode/resources/session.py">share</a>(id) -> <a href="./src/opencode/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/resources/session.py">summarize</a>(id, \*\*<a href="src/opencode/types/session_summarize_params.py">params</a>) -> <a href="./src/opencode/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="delete /session/{id}/share">client.session.<a href="./src/opencode/resources/session.py">unshare</a>(id) -> <a href="./src/opencode/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>
|
||||||
|
|
|
||||||
2
mypy.ini
2
mypy.ini
|
|
@ -8,7 +8,7 @@ show_error_codes = True
|
||||||
#
|
#
|
||||||
# We also exclude our `tests` as mypy doesn't always infer
|
# We also exclude our `tests` as mypy doesn't always infer
|
||||||
# types correctly and Pyright will still catch any type errors.
|
# types correctly and Pyright will still catch any type errors.
|
||||||
exclude = ^(src/opencode/_files\.py|_dev/.*\.py|tests/.*)$
|
exclude = ^(src/opencode_ai/_files\.py|_dev/.*\.py|tests/.*)$
|
||||||
|
|
||||||
strict_equality = True
|
strict_equality = True
|
||||||
implicit_reexport = True
|
implicit_reexport = True
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
[project]
|
[project]
|
||||||
name = "opencode"
|
name = "opencode-ai"
|
||||||
version = "0.1.0-alpha.1"
|
version = "0.1.0-alpha.2"
|
||||||
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 = "Apache-2.0"
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "Opencode", email = "support@sst.dev" },
|
{ name = "Opencode", email = "hello@sst.dev" },
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"httpx>=0.23.0, <1",
|
"httpx>=0.23.0, <1",
|
||||||
|
|
@ -78,14 +78,14 @@ format = { chain = [
|
||||||
"check:ruff" = "ruff check ."
|
"check:ruff" = "ruff check ."
|
||||||
"fix:ruff" = "ruff check --fix ."
|
"fix:ruff" = "ruff check --fix ."
|
||||||
|
|
||||||
"check:importable" = "python -c 'import opencode'"
|
"check:importable" = "python -c 'import opencode_ai'"
|
||||||
|
|
||||||
typecheck = { chain = [
|
typecheck = { chain = [
|
||||||
"typecheck:pyright",
|
"typecheck:pyright",
|
||||||
"typecheck:mypy"
|
"typecheck:mypy"
|
||||||
]}
|
]}
|
||||||
"typecheck:pyright" = "pyright"
|
"typecheck:pyright" = "pyright"
|
||||||
"typecheck:verify-types" = "pyright --verifytypes opencode --ignoreexternal"
|
"typecheck:verify-types" = "pyright --verifytypes opencode_ai --ignoreexternal"
|
||||||
"typecheck:mypy" = "mypy ."
|
"typecheck:mypy" = "mypy ."
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
|
@ -98,7 +98,7 @@ include = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.hatch.build.targets.wheel]
|
[tool.hatch.build.targets.wheel]
|
||||||
packages = ["src/opencode"]
|
packages = ["src/opencode_ai"]
|
||||||
|
|
||||||
[tool.hatch.build.targets.sdist]
|
[tool.hatch.build.targets.sdist]
|
||||||
# Basically everything except hidden files/directories (such as .github, .devcontainers, .python-version, etc)
|
# Basically everything except hidden files/directories (such as .github, .devcontainers, .python-version, etc)
|
||||||
|
|
@ -201,7 +201,7 @@ length-sort = true
|
||||||
length-sort-straight = true
|
length-sort-straight = true
|
||||||
combine-as-imports = true
|
combine-as-imports = true
|
||||||
extra-standard-library = ["typing_extensions"]
|
extra-standard-library = ["typing_extensions"]
|
||||||
known-first-party = ["opencode", "tests"]
|
known-first-party = ["opencode_ai", "tests"]
|
||||||
|
|
||||||
[tool.ruff.lint.per-file-ignores]
|
[tool.ruff.lint.per-file-ignores]
|
||||||
"bin/**.py" = ["T201", "T203"]
|
"bin/**.py" = ["T201", "T203"]
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,6 @@
|
||||||
],
|
],
|
||||||
"release-type": "python",
|
"release-type": "python",
|
||||||
"extra-files": [
|
"extra-files": [
|
||||||
"src/opencode/_version.py"
|
"src/opencode_ai/_version.py"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -14,14 +14,14 @@ aiohappyeyeballs==2.6.1
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
aiohttp==3.12.8
|
aiohttp==3.12.8
|
||||||
# via httpx-aiohttp
|
# via httpx-aiohttp
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
aiosignal==1.3.2
|
aiosignal==1.3.2
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
annotated-types==0.6.0
|
annotated-types==0.6.0
|
||||||
# via pydantic
|
# via pydantic
|
||||||
anyio==4.4.0
|
anyio==4.4.0
|
||||||
# via httpx
|
# via httpx
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
argcomplete==3.1.2
|
argcomplete==3.1.2
|
||||||
# via nox
|
# via nox
|
||||||
async-timeout==5.0.1
|
async-timeout==5.0.1
|
||||||
|
|
@ -37,7 +37,7 @@ dirty-equals==0.6.0
|
||||||
distlib==0.3.7
|
distlib==0.3.7
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
distro==1.8.0
|
distro==1.8.0
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
exceptiongroup==1.2.2
|
exceptiongroup==1.2.2
|
||||||
# via anyio
|
# via anyio
|
||||||
# via pytest
|
# via pytest
|
||||||
|
|
@ -54,10 +54,10 @@ httpcore==1.0.2
|
||||||
# via httpx
|
# via httpx
|
||||||
httpx==0.28.1
|
httpx==0.28.1
|
||||||
# via httpx-aiohttp
|
# via httpx-aiohttp
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
# via respx
|
# via respx
|
||||||
httpx-aiohttp==0.1.6
|
httpx-aiohttp==0.1.6
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
idna==3.4
|
idna==3.4
|
||||||
# via anyio
|
# via anyio
|
||||||
# via httpx
|
# via httpx
|
||||||
|
|
@ -90,7 +90,7 @@ propcache==0.3.1
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
# via yarl
|
# via yarl
|
||||||
pydantic==2.10.3
|
pydantic==2.10.3
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
pydantic-core==2.27.1
|
pydantic-core==2.27.1
|
||||||
# via pydantic
|
# via pydantic
|
||||||
pygments==2.18.0
|
pygments==2.18.0
|
||||||
|
|
@ -114,7 +114,7 @@ six==1.16.0
|
||||||
# via python-dateutil
|
# via python-dateutil
|
||||||
sniffio==1.3.0
|
sniffio==1.3.0
|
||||||
# via anyio
|
# via anyio
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
time-machine==2.9.0
|
time-machine==2.9.0
|
||||||
tomli==2.0.2
|
tomli==2.0.2
|
||||||
# via mypy
|
# via mypy
|
||||||
|
|
@ -123,7 +123,7 @@ typing-extensions==4.12.2
|
||||||
# via anyio
|
# via anyio
|
||||||
# via multidict
|
# via multidict
|
||||||
# via mypy
|
# via mypy
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
# via pydantic
|
# via pydantic
|
||||||
# via pydantic-core
|
# via pydantic-core
|
||||||
# via pyright
|
# via pyright
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,14 @@ aiohappyeyeballs==2.6.1
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
aiohttp==3.12.8
|
aiohttp==3.12.8
|
||||||
# via httpx-aiohttp
|
# via httpx-aiohttp
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
aiosignal==1.3.2
|
aiosignal==1.3.2
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
annotated-types==0.6.0
|
annotated-types==0.6.0
|
||||||
# via pydantic
|
# via pydantic
|
||||||
anyio==4.4.0
|
anyio==4.4.0
|
||||||
# via httpx
|
# via httpx
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
async-timeout==5.0.1
|
async-timeout==5.0.1
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
attrs==25.3.0
|
attrs==25.3.0
|
||||||
|
|
@ -30,7 +30,7 @@ certifi==2023.7.22
|
||||||
# via httpcore
|
# via httpcore
|
||||||
# via httpx
|
# via httpx
|
||||||
distro==1.8.0
|
distro==1.8.0
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
exceptiongroup==1.2.2
|
exceptiongroup==1.2.2
|
||||||
# via anyio
|
# via anyio
|
||||||
frozenlist==1.6.2
|
frozenlist==1.6.2
|
||||||
|
|
@ -42,9 +42,9 @@ httpcore==1.0.2
|
||||||
# via httpx
|
# via httpx
|
||||||
httpx==0.28.1
|
httpx==0.28.1
|
||||||
# via httpx-aiohttp
|
# via httpx-aiohttp
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
httpx-aiohttp==0.1.6
|
httpx-aiohttp==0.1.6
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
idna==3.4
|
idna==3.4
|
||||||
# via anyio
|
# via anyio
|
||||||
# via httpx
|
# via httpx
|
||||||
|
|
@ -56,16 +56,16 @@ propcache==0.3.1
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
# via yarl
|
# via yarl
|
||||||
pydantic==2.10.3
|
pydantic==2.10.3
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
pydantic-core==2.27.1
|
pydantic-core==2.27.1
|
||||||
# via pydantic
|
# via pydantic
|
||||||
sniffio==1.3.0
|
sniffio==1.3.0
|
||||||
# via anyio
|
# via anyio
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
typing-extensions==4.12.2
|
typing-extensions==4.12.2
|
||||||
# via anyio
|
# via anyio
|
||||||
# via multidict
|
# via multidict
|
||||||
# via opencode
|
# via opencode-ai
|
||||||
# via pydantic
|
# via pydantic
|
||||||
# via pydantic-core
|
# via pydantic-core
|
||||||
yarl==1.20.0
|
yarl==1.20.0
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,4 @@ echo "==> Running lints"
|
||||||
rye run lint
|
rye run lint
|
||||||
|
|
||||||
echo "==> Making sure it imports"
|
echo "==> Making sure it imports"
|
||||||
rye run python -c 'import opencode'
|
rye run python -c 'import opencode_ai'
|
||||||
|
|
|
||||||
|
|
@ -89,12 +89,12 @@ _setup_logging()
|
||||||
# Update the __module__ attribute for exported symbols so that
|
# Update the __module__ attribute for exported symbols so that
|
||||||
# error messages point to this module instead of the module
|
# error messages point to this module instead of the module
|
||||||
# it was originally defined in, e.g.
|
# it was originally defined in, e.g.
|
||||||
# opencode._exceptions.NotFoundError -> opencode.NotFoundError
|
# opencode_ai._exceptions.NotFoundError -> opencode_ai.NotFoundError
|
||||||
__locals = locals()
|
__locals = locals()
|
||||||
for __name in __all__:
|
for __name in __all__:
|
||||||
if not __name.startswith("__"):
|
if not __name.startswith("__"):
|
||||||
try:
|
try:
|
||||||
__locals[__name].__module__ = "opencode"
|
__locals[__name].__module__ = "opencode_ai"
|
||||||
except (TypeError, AttributeError):
|
except (TypeError, AttributeError):
|
||||||
# Some of our exported symbols are builtins which we can't set attributes for.
|
# Some of our exported symbols are builtins which we can't set attributes for.
|
||||||
pass
|
pass
|
||||||
|
|
@ -389,7 +389,7 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
||||||
|
|
||||||
if max_retries is None: # pyright: ignore[reportUnnecessaryComparison]
|
if max_retries is None: # pyright: ignore[reportUnnecessaryComparison]
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"max_retries cannot be None. If you want to disable retries, pass `0`; if you want unlimited retries, pass `math.inf` or a very high number; if you want the default behavior, pass `opencode.DEFAULT_MAX_RETRIES`"
|
"max_retries cannot be None. If you want to disable retries, pass `0`; if you want unlimited retries, pass `math.inf` or a very high number; if you want the default behavior, pass `opencode_ai.DEFAULT_MAX_RETRIES`"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _enforce_trailing_slash(self, url: URL) -> URL:
|
def _enforce_trailing_slash(self, url: URL) -> URL:
|
||||||
|
|
@ -217,7 +217,9 @@ class BaseAPIResponse(Generic[R]):
|
||||||
and not issubclass(origin, BaseModel)
|
and not issubclass(origin, BaseModel)
|
||||||
and issubclass(origin, pydantic.BaseModel)
|
and issubclass(origin, pydantic.BaseModel)
|
||||||
):
|
):
|
||||||
raise TypeError("Pydantic models must subclass our base model type, e.g. `from opencode import BaseModel`")
|
raise TypeError(
|
||||||
|
"Pydantic models must subclass our base model type, e.g. `from opencode_ai import BaseModel`"
|
||||||
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
cast_to is not object
|
cast_to is not object
|
||||||
|
|
@ -283,7 +285,7 @@ class APIResponse(BaseAPIResponse[R]):
|
||||||
the `to` argument, e.g.
|
the `to` argument, e.g.
|
||||||
|
|
||||||
```py
|
```py
|
||||||
from opencode import BaseModel
|
from opencode_ai import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class MyModel(BaseModel):
|
class MyModel(BaseModel):
|
||||||
|
|
@ -385,7 +387,7 @@ class AsyncAPIResponse(BaseAPIResponse[R]):
|
||||||
the `to` argument, e.g.
|
the `to` argument, e.g.
|
||||||
|
|
||||||
```py
|
```py
|
||||||
from opencode import BaseModel
|
from opencode_ai import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class MyModel(BaseModel):
|
class MyModel(BaseModel):
|
||||||
|
|
@ -556,7 +558,7 @@ class AsyncStreamedBinaryAPIResponse(AsyncAPIResponse[bytes]):
|
||||||
class MissingStreamClassError(TypeError):
|
class MissingStreamClassError(TypeError):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
"The `stream` argument was set to `True` but the `stream_cls` argument was not given. See `opencode._streaming` for reference",
|
"The `stream` argument was set to `True` but the `stream_cls` argument was not given. See `opencode_ai._streaming` for reference",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -81,7 +81,7 @@ HttpxRequestFiles = Union[Mapping[str, HttpxFileTypes], Sequence[Tuple[str, Http
|
||||||
# This unfortunately means that you will either have
|
# This unfortunately means that you will either have
|
||||||
# to import this type and pass it explicitly:
|
# to import this type and pass it explicitly:
|
||||||
#
|
#
|
||||||
# from opencode import NoneType
|
# from opencode_ai import NoneType
|
||||||
# client.get('/foo', cast_to=NoneType)
|
# client.get('/foo', cast_to=NoneType)
|
||||||
#
|
#
|
||||||
# or build it yourself:
|
# or build it yourself:
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger: logging.Logger = logging.getLogger("opencode")
|
logger: logging.Logger = logging.getLogger("opencode_ai")
|
||||||
httpx_logger: logging.Logger = logging.getLogger("httpx")
|
httpx_logger: logging.Logger = logging.getLogger("httpx")
|
||||||
|
|
||||||
|
|
||||||
def _basic_config() -> None:
|
def _basic_config() -> None:
|
||||||
# e.g. [2023-10-05 14:12:26 - opencode._base_client:818 - DEBUG] HTTP Request: POST http://127.0.0.1:4010/foo/bar "200 OK"
|
# e.g. [2023-10-05 14:12:26 - opencode_ai._base_client:818 - DEBUG] HTTP Request: POST http://127.0.0.1:4010/foo/bar "200 OK"
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
format="[%(asctime)s - %(name)s:%(lineno)d - %(levelname)s] %(message)s",
|
format="[%(asctime)s - %(name)s:%(lineno)d - %(levelname)s] %(message)s",
|
||||||
datefmt="%Y-%m-%d %H:%M:%S",
|
datefmt="%Y-%m-%d %H:%M:%S",
|
||||||
|
|
@ -7,17 +7,17 @@ from ._proxy import LazyProxy
|
||||||
|
|
||||||
|
|
||||||
class ResourcesProxy(LazyProxy[Any]):
|
class ResourcesProxy(LazyProxy[Any]):
|
||||||
"""A proxy for the `opencode.resources` module.
|
"""A proxy for the `opencode_ai.resources` module.
|
||||||
|
|
||||||
This is used so that we can lazily import `opencode.resources` only when
|
This is used so that we can lazily import `opencode_ai.resources` only when
|
||||||
needed *and* so that users can just import `opencode` and reference `opencode.resources`
|
needed *and* so that users can just import `opencode_ai` and reference `opencode_ai.resources`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@override
|
@override
|
||||||
def __load__(self) -> Any:
|
def __load__(self) -> Any:
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
mod = importlib.import_module("opencode.resources")
|
mod = importlib.import_module("opencode_ai.resources")
|
||||||
return mod
|
return mod
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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"
|
__title__ = "opencode_ai"
|
||||||
__version__ = "0.1.0-alpha.1" # x-release-please-version
|
__version__ = "0.1.0-alpha.2" # x-release-please-version
|
||||||
4
src/opencode_ai/lib/.keep
Normal file
4
src/opencode_ai/lib/.keep
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
File generated from our OpenAPI spec by Stainless.
|
||||||
|
|
||||||
|
This directory can be used to store custom files to expand the SDK.
|
||||||
|
It is ignored by Stainless code generation and its content (other than this keep file) won't be touched.
|
||||||
|
|
@ -7,9 +7,9 @@ from typing import Any, cast
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from opencode 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.types import App, AppInitResponse
|
from opencode_ai.types import App, AppInitResponse
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ from typing import Any, cast
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from opencode 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.types import Config, ConfigProvidersResponse
|
from opencode_ai.types import Config, ConfigProvidersResponse
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ from typing import Any, cast
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from opencode 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.types import EventListResponse
|
from opencode_ai.types import EventListResponse
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ from typing import Any, cast
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from opencode 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.types import FileSearchResponse
|
from opencode_ai.types import FileSearchResponse
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ from typing import Any, cast
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from opencode 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.types import (
|
from opencode_ai.types import (
|
||||||
Message,
|
Message,
|
||||||
Session,
|
Session,
|
||||||
SessionInitResponse,
|
SessionInitResponse,
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,15 @@ import httpx
|
||||||
import pytest
|
import pytest
|
||||||
from pytest_asyncio import is_async_test
|
from pytest_asyncio import is_async_test
|
||||||
|
|
||||||
from opencode import Opencode, AsyncOpencode, DefaultAioHttpClient
|
from opencode_ai import Opencode, AsyncOpencode, DefaultAioHttpClient
|
||||||
from opencode._utils import is_dict
|
from opencode_ai._utils import is_dict
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage]
|
from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage]
|
||||||
|
|
||||||
pytest.register_assert_rewrite("tests.utils")
|
pytest.register_assert_rewrite("tests.utils")
|
||||||
|
|
||||||
logging.getLogger("opencode").setLevel(logging.DEBUG)
|
logging.getLogger("opencode_ai").setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
|
||||||
# automatically add `pytest.mark.asyncio()` to all of our async tests
|
# automatically add `pytest.mark.asyncio()` to all of our async tests
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ import pytest
|
||||||
from respx import MockRouter
|
from respx import MockRouter
|
||||||
from pydantic import ValidationError
|
from pydantic import ValidationError
|
||||||
|
|
||||||
from opencode import Opencode, AsyncOpencode, APIResponseValidationError
|
from opencode_ai import Opencode, AsyncOpencode, APIResponseValidationError
|
||||||
from opencode._types import Omit
|
from opencode_ai._types import Omit
|
||||||
from opencode._models import BaseModel, FinalRequestOptions
|
from opencode_ai._models import BaseModel, FinalRequestOptions
|
||||||
from opencode._exceptions import APIStatusError, APITimeoutError, APIResponseValidationError
|
from opencode_ai._exceptions import APIStatusError, APITimeoutError, APIResponseValidationError
|
||||||
from opencode._base_client import (
|
from opencode_ai._base_client import (
|
||||||
DEFAULT_TIMEOUT,
|
DEFAULT_TIMEOUT,
|
||||||
HTTPX_DEFAULT_TIMEOUT,
|
HTTPX_DEFAULT_TIMEOUT,
|
||||||
BaseClient,
|
BaseClient,
|
||||||
|
|
@ -223,10 +223,10 @@ class TestOpencode:
|
||||||
# to_raw_response_wrapper leaks through the @functools.wraps() decorator.
|
# to_raw_response_wrapper leaks through the @functools.wraps() decorator.
|
||||||
#
|
#
|
||||||
# removing the decorator fixes the leak for reasons we don't understand.
|
# removing the decorator fixes the leak for reasons we don't understand.
|
||||||
"opencode/_legacy_response.py",
|
"opencode_ai/_legacy_response.py",
|
||||||
"opencode/_response.py",
|
"opencode_ai/_response.py",
|
||||||
# pydantic.BaseModel.model_dump || pydantic.BaseModel.dict leak memory for some reason.
|
# pydantic.BaseModel.model_dump || pydantic.BaseModel.dict leak memory for some reason.
|
||||||
"opencode/_compat.py",
|
"opencode_ai/_compat.py",
|
||||||
# Standard library leaks we don't care about.
|
# Standard library leaks we don't care about.
|
||||||
"/logging/__init__.py",
|
"/logging/__init__.py",
|
||||||
]
|
]
|
||||||
|
|
@ -671,7 +671,7 @@ class TestOpencode:
|
||||||
calculated = client._calculate_retry_timeout(remaining_retries, options, headers)
|
calculated = client._calculate_retry_timeout(remaining_retries, options, headers)
|
||||||
assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType]
|
assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType]
|
||||||
|
|
||||||
@mock.patch("opencode._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
@mock.patch("opencode_ai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
||||||
@pytest.mark.respx(base_url=base_url)
|
@pytest.mark.respx(base_url=base_url)
|
||||||
def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: Opencode) -> None:
|
def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: Opencode) -> None:
|
||||||
respx_mock.get("/event").mock(side_effect=httpx.TimeoutException("Test timeout error"))
|
respx_mock.get("/event").mock(side_effect=httpx.TimeoutException("Test timeout error"))
|
||||||
|
|
@ -681,7 +681,7 @@ class TestOpencode:
|
||||||
|
|
||||||
assert _get_open_connections(self.client) == 0
|
assert _get_open_connections(self.client) == 0
|
||||||
|
|
||||||
@mock.patch("opencode._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
@mock.patch("opencode_ai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
||||||
@pytest.mark.respx(base_url=base_url)
|
@pytest.mark.respx(base_url=base_url)
|
||||||
def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: Opencode) -> None:
|
def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: Opencode) -> None:
|
||||||
respx_mock.get("/event").mock(return_value=httpx.Response(500))
|
respx_mock.get("/event").mock(return_value=httpx.Response(500))
|
||||||
|
|
@ -691,7 +691,7 @@ class TestOpencode:
|
||||||
assert _get_open_connections(self.client) == 0
|
assert _get_open_connections(self.client) == 0
|
||||||
|
|
||||||
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
||||||
@mock.patch("opencode._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
@mock.patch("opencode_ai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
||||||
@pytest.mark.respx(base_url=base_url)
|
@pytest.mark.respx(base_url=base_url)
|
||||||
@pytest.mark.parametrize("failure_mode", ["status", "exception"])
|
@pytest.mark.parametrize("failure_mode", ["status", "exception"])
|
||||||
def test_retries_taken(
|
def test_retries_taken(
|
||||||
|
|
@ -722,7 +722,7 @@ class TestOpencode:
|
||||||
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
|
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
|
||||||
|
|
||||||
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
||||||
@mock.patch("opencode._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
@mock.patch("opencode_ai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
||||||
@pytest.mark.respx(base_url=base_url)
|
@pytest.mark.respx(base_url=base_url)
|
||||||
def test_omit_retry_count_header(
|
def test_omit_retry_count_header(
|
||||||
self, client: Opencode, failures_before_success: int, respx_mock: MockRouter
|
self, client: Opencode, failures_before_success: int, respx_mock: MockRouter
|
||||||
|
|
@ -745,7 +745,7 @@ class TestOpencode:
|
||||||
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
|
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
|
||||||
|
|
||||||
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
||||||
@mock.patch("opencode._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
@mock.patch("opencode_ai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
||||||
@pytest.mark.respx(base_url=base_url)
|
@pytest.mark.respx(base_url=base_url)
|
||||||
def test_overwrite_retry_count_header(
|
def test_overwrite_retry_count_header(
|
||||||
self, client: Opencode, failures_before_success: int, respx_mock: MockRouter
|
self, client: Opencode, failures_before_success: int, respx_mock: MockRouter
|
||||||
|
|
@ -985,10 +985,10 @@ class TestAsyncOpencode:
|
||||||
# to_raw_response_wrapper leaks through the @functools.wraps() decorator.
|
# to_raw_response_wrapper leaks through the @functools.wraps() decorator.
|
||||||
#
|
#
|
||||||
# removing the decorator fixes the leak for reasons we don't understand.
|
# removing the decorator fixes the leak for reasons we don't understand.
|
||||||
"opencode/_legacy_response.py",
|
"opencode_ai/_legacy_response.py",
|
||||||
"opencode/_response.py",
|
"opencode_ai/_response.py",
|
||||||
# pydantic.BaseModel.model_dump || pydantic.BaseModel.dict leak memory for some reason.
|
# pydantic.BaseModel.model_dump || pydantic.BaseModel.dict leak memory for some reason.
|
||||||
"opencode/_compat.py",
|
"opencode_ai/_compat.py",
|
||||||
# Standard library leaks we don't care about.
|
# Standard library leaks we don't care about.
|
||||||
"/logging/__init__.py",
|
"/logging/__init__.py",
|
||||||
]
|
]
|
||||||
|
|
@ -1439,7 +1439,7 @@ class TestAsyncOpencode:
|
||||||
calculated = client._calculate_retry_timeout(remaining_retries, options, headers)
|
calculated = client._calculate_retry_timeout(remaining_retries, options, headers)
|
||||||
assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType]
|
assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType]
|
||||||
|
|
||||||
@mock.patch("opencode._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
@mock.patch("opencode_ai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
||||||
@pytest.mark.respx(base_url=base_url)
|
@pytest.mark.respx(base_url=base_url)
|
||||||
async def test_retrying_timeout_errors_doesnt_leak(
|
async def test_retrying_timeout_errors_doesnt_leak(
|
||||||
self, respx_mock: MockRouter, async_client: AsyncOpencode
|
self, respx_mock: MockRouter, async_client: AsyncOpencode
|
||||||
|
|
@ -1451,7 +1451,7 @@ class TestAsyncOpencode:
|
||||||
|
|
||||||
assert _get_open_connections(self.client) == 0
|
assert _get_open_connections(self.client) == 0
|
||||||
|
|
||||||
@mock.patch("opencode._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
@mock.patch("opencode_ai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
||||||
@pytest.mark.respx(base_url=base_url)
|
@pytest.mark.respx(base_url=base_url)
|
||||||
async def test_retrying_status_errors_doesnt_leak(
|
async def test_retrying_status_errors_doesnt_leak(
|
||||||
self, respx_mock: MockRouter, async_client: AsyncOpencode
|
self, respx_mock: MockRouter, async_client: AsyncOpencode
|
||||||
|
|
@ -1463,7 +1463,7 @@ class TestAsyncOpencode:
|
||||||
assert _get_open_connections(self.client) == 0
|
assert _get_open_connections(self.client) == 0
|
||||||
|
|
||||||
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
||||||
@mock.patch("opencode._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
@mock.patch("opencode_ai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
||||||
@pytest.mark.respx(base_url=base_url)
|
@pytest.mark.respx(base_url=base_url)
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.parametrize("failure_mode", ["status", "exception"])
|
@pytest.mark.parametrize("failure_mode", ["status", "exception"])
|
||||||
|
|
@ -1495,7 +1495,7 @@ class TestAsyncOpencode:
|
||||||
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
|
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
|
||||||
|
|
||||||
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
||||||
@mock.patch("opencode._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
@mock.patch("opencode_ai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
||||||
@pytest.mark.respx(base_url=base_url)
|
@pytest.mark.respx(base_url=base_url)
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_omit_retry_count_header(
|
async def test_omit_retry_count_header(
|
||||||
|
|
@ -1519,7 +1519,7 @@ class TestAsyncOpencode:
|
||||||
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
|
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
|
||||||
|
|
||||||
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
|
||||||
@mock.patch("opencode._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
@mock.patch("opencode_ai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
|
||||||
@pytest.mark.respx(base_url=base_url)
|
@pytest.mark.respx(base_url=base_url)
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_overwrite_retry_count_header(
|
async def test_overwrite_retry_count_header(
|
||||||
|
|
@ -1553,8 +1553,8 @@ class TestAsyncOpencode:
|
||||||
import nest_asyncio
|
import nest_asyncio
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from opencode._utils import asyncify
|
from opencode_ai._utils import asyncify
|
||||||
from opencode._base_client import get_platform
|
from opencode_ai._base_client import get_platform
|
||||||
|
|
||||||
async def test_main() -> None:
|
async def test_main() -> None:
|
||||||
result = await asyncify(get_platform)()
|
result = await asyncify(get_platform)()
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from opencode._utils import deepcopy_minimal
|
from opencode_ai._utils import deepcopy_minimal
|
||||||
|
|
||||||
|
|
||||||
def assert_different_identities(obj1: object, obj2: object) -> None:
|
def assert_different_identities(obj1: object, obj2: object) -> None:
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue