diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 3188ced..315f7d3 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.25" + ".": "0.1.0-alpha.26" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 9110eeb..2ff039c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-69b99aaffe10dd5247638b6a34d6c0b3c1cf5300853d12c947151fd946e7fcdb.yml -openapi_spec_hash: e2c746cf689d71f04c6e9b1bd92e6356 -config_hash: d779331eb3dabf2d99f2a20be154d1c9 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-04eaffcca7fcec3eba3c34ba4e91ba830867173c552015a0abfd65e25084d9b5.yml +openapi_spec_hash: 4dfbcc2ce25451592f610e372ecad0cb +config_hash: 0032a76356d31c6b4c218b39fff635bb diff --git a/CHANGELOG.md b/CHANGELOG.md index 84ac353..4d97d3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 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) diff --git a/api.md b/api.md index aa2f3b1..e4866ed 100644 --- a/api.md +++ b/api.md @@ -145,4 +145,4 @@ from opencode_ai.types import TuiPromptResponse Methods: -- client.tui.prompt() -> TuiPromptResponse +- client.tui.prompt(\*\*params) -> TuiPromptResponse diff --git a/pyproject.toml b/pyproject.toml index 74c0396..349aa84 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "opencode-ai" -version = "0.1.0-alpha.25" +version = "0.1.0-alpha.26" description = "The official Python library for the opencode API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/opencode_ai/_version.py b/src/opencode_ai/_version.py index 20e5605..6d9c11d 100644 --- a/src/opencode_ai/_version.py +++ b/src/opencode_ai/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "opencode_ai" -__version__ = "0.1.0-alpha.25" # x-release-please-version +__version__ = "0.1.0-alpha.26" # x-release-please-version diff --git a/src/opencode_ai/resources/tui.py b/src/opencode_ai/resources/tui.py index 5a8e2e9..fd3cb73 100644 --- a/src/opencode_ai/resources/tui.py +++ b/src/opencode_ai/resources/tui.py @@ -2,9 +2,13 @@ from __future__ import annotations +from typing import Iterable + import httpx +from ..types import tui_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 ( @@ -14,6 +18,7 @@ async_to_streamed_response_wrapper, ) from .._base_client import make_request_options +from ..types.part_param import PartParam from ..types.tui_prompt_response import TuiPromptResponse __all__ = ["TuiResource", "AsyncTuiResource"] @@ -42,6 +47,8 @@ def with_streaming_response(self) -> TuiResourceWithStreamingResponse: def prompt( self, *, + parts: Iterable[PartParam], + 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, @@ -49,9 +56,27 @@ def prompt( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> TuiPromptResponse: - """Send a prompt to the TUI""" + """ + Send a 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/prompt", + body=maybe_transform( + { + "parts": parts, + "text": text, + }, + tui_prompt_params.TuiPromptParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -82,6 +107,8 @@ def with_streaming_response(self) -> AsyncTuiResourceWithStreamingResponse: async def prompt( self, *, + parts: Iterable[PartParam], + 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, @@ -89,9 +116,27 @@ async def prompt( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, ) -> TuiPromptResponse: - """Send a prompt to the TUI""" + """ + Send a 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/prompt", + body=await async_maybe_transform( + { + "parts": parts, + "text": text, + }, + tui_prompt_params.TuiPromptParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/opencode_ai/types/__init__.py b/src/opencode_ai/types/__init__.py index db18d1b..6621bb7 100644 --- a/src/opencode_ai/types/__init__.py +++ b/src/opencode_ai/types/__init__.py @@ -21,14 +21,18 @@ from .file_part import FilePart as FilePart from .text_part import TextPart as TextPart from .tool_part import ToolPart as ToolPart +from .part_param import PartParam as PartParam from .file_source import FileSource as FileSource from .mode_config import ModeConfig as ModeConfig from .user_message import UserMessage as UserMessage from .snapshot_part import SnapshotPart as SnapshotPart from .symbol_source import SymbolSource as SymbolSource 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 .text_part_param import TextPartParam as TextPartParam +from .tool_part_param import ToolPartParam as ToolPartParam from .app_log_response import AppLogResponse as AppLogResponse from .file_part_source import FilePartSource as FilePartSource from .file_read_params import FileReadParams as FileReadParams @@ -41,6 +45,7 @@ from .file_source_param import FileSourceParam as FileSourceParam from .find_files_params import FindFilesParams as FindFilesParams from .mcp_remote_config import McpRemoteConfig as McpRemoteConfig +from .tui_prompt_params import TuiPromptParams as TuiPromptParams from .app_modes_response import AppModesResponse as AppModesResponse from .file_read_response import FileReadResponse as FileReadResponse from .find_text_response import FindTextResponse as FindTextResponse @@ -51,6 +56,7 @@ from .find_symbols_params import FindSymbolsParams as FindSymbolsParams from .session_chat_params import SessionChatParams as SessionChatParams from .session_init_params import SessionInitParams as SessionInitParams +from .snapshot_part_param import SnapshotPartParam as SnapshotPartParam from .symbol_source_param import SymbolSourceParam as SymbolSourceParam from .tui_prompt_response import TuiPromptResponse as TuiPromptResponse from .file_status_response import FileStatusResponse as FileStatusResponse @@ -60,12 +66,18 @@ from .find_symbols_response import FindSymbolsResponse as FindSymbolsResponse from .session_init_response import SessionInitResponse as SessionInitResponse from .session_list_response import SessionListResponse as SessionListResponse +from .step_start_part_param import StepStartPartParam as StepStartPartParam 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 .step_finish_part_param import StepFinishPartParam as StepFinishPartParam +from .tool_state_error_param import ToolStateErrorParam as ToolStateErrorParam from .session_delete_response import SessionDeleteResponse as SessionDeleteResponse from .session_summarize_params import SessionSummarizeParams as SessionSummarizeParams +from .tool_state_pending_param import ToolStatePendingParam as ToolStatePendingParam +from .tool_state_running_param import ToolStateRunningParam as ToolStateRunningParam from .session_messages_response import SessionMessagesResponse as SessionMessagesResponse from .session_summarize_response import SessionSummarizeResponse as SessionSummarizeResponse +from .tool_state_completed_param import ToolStateCompletedParam as ToolStateCompletedParam from .file_part_source_text_param import FilePartSourceTextParam as FilePartSourceTextParam diff --git a/src/opencode_ai/types/file_part_param.py b/src/opencode_ai/types/file_part_param.py new file mode 100644 index 0000000..9de2723 --- /dev/null +++ b/src/opencode_ai/types/file_part_param.py @@ -0,0 +1,28 @@ +# 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 +from .file_part_source_param import FilePartSourceParam + +__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 + + source: FilePartSourceParam diff --git a/src/opencode_ai/types/part_param.py b/src/opencode_ai/types/part_param.py new file mode 100644 index 0000000..8160b98 --- /dev/null +++ b/src/opencode_ai/types/part_param.py @@ -0,0 +1,19 @@ +# 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_part_param import FilePartParam +from .text_part_param import TextPartParam +from .tool_part_param import ToolPartParam +from .snapshot_part_param import SnapshotPartParam +from .step_start_part_param import StepStartPartParam +from .step_finish_part_param import StepFinishPartParam + +__all__ = ["PartParam"] + +PartParam: TypeAlias = Union[ + TextPartParam, FilePartParam, ToolPartParam, StepStartPartParam, StepFinishPartParam, SnapshotPartParam +] diff --git a/src/opencode_ai/types/snapshot_part_param.py b/src/opencode_ai/types/snapshot_part_param.py new file mode 100644 index 0000000..847ba82 --- /dev/null +++ b/src/opencode_ai/types/snapshot_part_param.py @@ -0,0 +1,21 @@ +# 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__ = ["SnapshotPartParam"] + + +class SnapshotPartParam(TypedDict, total=False): + id: Required[str] + + message_id: Required[Annotated[str, PropertyInfo(alias="messageID")]] + + session_id: Required[Annotated[str, PropertyInfo(alias="sessionID")]] + + snapshot: Required[str] + + type: Required[Literal["snapshot"]] diff --git a/src/opencode_ai/types/step_finish_part_param.py b/src/opencode_ai/types/step_finish_part_param.py new file mode 100644 index 0000000..4dabb28 --- /dev/null +++ b/src/opencode_ai/types/step_finish_part_param.py @@ -0,0 +1,39 @@ +# 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__ = ["StepFinishPartParam", "Tokens", "TokensCache"] + + +class TokensCache(TypedDict, total=False): + read: Required[float] + + write: Required[float] + + +class Tokens(TypedDict, total=False): + cache: Required[TokensCache] + + input: Required[float] + + output: Required[float] + + reasoning: Required[float] + + +class StepFinishPartParam(TypedDict, total=False): + id: Required[str] + + cost: Required[float] + + message_id: Required[Annotated[str, PropertyInfo(alias="messageID")]] + + session_id: Required[Annotated[str, PropertyInfo(alias="sessionID")]] + + tokens: Required[Tokens] + + type: Required[Literal["step-finish"]] diff --git a/src/opencode_ai/types/step_start_part_param.py b/src/opencode_ai/types/step_start_part_param.py new file mode 100644 index 0000000..a7d5655 --- /dev/null +++ b/src/opencode_ai/types/step_start_part_param.py @@ -0,0 +1,19 @@ +# 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__ = ["StepStartPartParam"] + + +class StepStartPartParam(TypedDict, total=False): + id: Required[str] + + message_id: Required[Annotated[str, PropertyInfo(alias="messageID")]] + + session_id: Required[Annotated[str, PropertyInfo(alias="sessionID")]] + + type: Required[Literal["step-start"]] diff --git a/src/opencode_ai/types/text_part_param.py b/src/opencode_ai/types/text_part_param.py new file mode 100644 index 0000000..3129256 --- /dev/null +++ b/src/opencode_ai/types/text_part_param.py @@ -0,0 +1,31 @@ +# 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 diff --git a/src/opencode_ai/types/tool_part_param.py b/src/opencode_ai/types/tool_part_param.py new file mode 100644 index 0000000..559c770 --- /dev/null +++ b/src/opencode_ai/types/tool_part_param.py @@ -0,0 +1,32 @@ +# 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 Literal, Required, Annotated, TypeAlias, TypedDict + +from .._utils import PropertyInfo +from .tool_state_error_param import ToolStateErrorParam +from .tool_state_pending_param import ToolStatePendingParam +from .tool_state_running_param import ToolStateRunningParam +from .tool_state_completed_param import ToolStateCompletedParam + +__all__ = ["ToolPartParam", "State"] + +State: TypeAlias = Union[ToolStatePendingParam, ToolStateRunningParam, ToolStateCompletedParam, ToolStateErrorParam] + + +class ToolPartParam(TypedDict, total=False): + id: Required[str] + + call_id: Required[Annotated[str, PropertyInfo(alias="callID")]] + + message_id: Required[Annotated[str, PropertyInfo(alias="messageID")]] + + session_id: Required[Annotated[str, PropertyInfo(alias="sessionID")]] + + state: Required[State] + + tool: Required[str] + + type: Required[Literal["tool"]] diff --git a/src/opencode_ai/types/tool_state_completed_param.py b/src/opencode_ai/types/tool_state_completed_param.py new file mode 100644 index 0000000..cea3758 --- /dev/null +++ b/src/opencode_ai/types/tool_state_completed_param.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ToolStateCompletedParam", "Time"] + + +class Time(TypedDict, total=False): + end: Required[float] + + start: Required[float] + + +class ToolStateCompletedParam(TypedDict, total=False): + input: Required[Dict[str, object]] + + metadata: Required[Dict[str, object]] + + output: Required[str] + + status: Required[Literal["completed"]] + + time: Required[Time] + + title: Required[str] diff --git a/src/opencode_ai/types/tool_state_error_param.py b/src/opencode_ai/types/tool_state_error_param.py new file mode 100644 index 0000000..7622868 --- /dev/null +++ b/src/opencode_ai/types/tool_state_error_param.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ToolStateErrorParam", "Time"] + + +class Time(TypedDict, total=False): + end: Required[float] + + start: Required[float] + + +class ToolStateErrorParam(TypedDict, total=False): + error: Required[str] + + input: Required[Dict[str, object]] + + status: Required[Literal["error"]] + + time: Required[Time] diff --git a/src/opencode_ai/types/tool_state_pending_param.py b/src/opencode_ai/types/tool_state_pending_param.py new file mode 100644 index 0000000..d375cd5 --- /dev/null +++ b/src/opencode_ai/types/tool_state_pending_param.py @@ -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 Literal, Required, TypedDict + +__all__ = ["ToolStatePendingParam"] + + +class ToolStatePendingParam(TypedDict, total=False): + status: Required[Literal["pending"]] diff --git a/src/opencode_ai/types/tool_state_running_param.py b/src/opencode_ai/types/tool_state_running_param.py new file mode 100644 index 0000000..1814d43 --- /dev/null +++ b/src/opencode_ai/types/tool_state_running_param.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ToolStateRunningParam", "Time"] + + +class Time(TypedDict, total=False): + start: Required[float] + + +class ToolStateRunningParam(TypedDict, total=False): + status: Required[Literal["running"]] + + time: Required[Time] + + input: object + + metadata: Dict[str, object] + + title: str diff --git a/src/opencode_ai/types/tui_prompt_params.py b/src/opencode_ai/types/tui_prompt_params.py new file mode 100644 index 0000000..be85887 --- /dev/null +++ b/src/opencode_ai/types/tui_prompt_params.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Required, TypedDict + +from .part_param import PartParam + +__all__ = ["TuiPromptParams"] + + +class TuiPromptParams(TypedDict, total=False): + parts: Required[Iterable[PartParam]] + + text: Required[str] diff --git a/tests/api_resources/test_tui.py b/tests/api_resources/test_tui.py index 92fde65..dbcfd75 100644 --- a/tests/api_resources/test_tui.py +++ b/tests/api_resources/test_tui.py @@ -20,13 +20,35 @@ class TestTui: @pytest.mark.skip() @parametrize def test_method_prompt(self, client: Opencode) -> None: - tui = client.tui.prompt() + tui = client.tui.prompt( + parts=[ + { + "id": "id", + "message_id": "messageID", + "session_id": "sessionID", + "text": "text", + "type": "text", + } + ], + text="text", + ) assert_matches_type(TuiPromptResponse, tui, path=["response"]) @pytest.mark.skip() @parametrize def test_raw_response_prompt(self, client: Opencode) -> None: - response = client.tui.with_raw_response.prompt() + response = client.tui.with_raw_response.prompt( + parts=[ + { + "id": "id", + "message_id": "messageID", + "session_id": "sessionID", + "text": "text", + "type": "text", + } + ], + text="text", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -36,7 +58,18 @@ def test_raw_response_prompt(self, client: Opencode) -> None: @pytest.mark.skip() @parametrize def test_streaming_response_prompt(self, client: Opencode) -> None: - with client.tui.with_streaming_response.prompt() as response: + with client.tui.with_streaming_response.prompt( + parts=[ + { + "id": "id", + "message_id": "messageID", + "session_id": "sessionID", + "text": "text", + "type": "text", + } + ], + text="text", + ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -54,13 +87,35 @@ class TestAsyncTui: @pytest.mark.skip() @parametrize async def test_method_prompt(self, async_client: AsyncOpencode) -> None: - tui = await async_client.tui.prompt() + tui = await async_client.tui.prompt( + parts=[ + { + "id": "id", + "message_id": "messageID", + "session_id": "sessionID", + "text": "text", + "type": "text", + } + ], + text="text", + ) assert_matches_type(TuiPromptResponse, tui, path=["response"]) @pytest.mark.skip() @parametrize async def test_raw_response_prompt(self, async_client: AsyncOpencode) -> None: - response = await async_client.tui.with_raw_response.prompt() + response = await async_client.tui.with_raw_response.prompt( + parts=[ + { + "id": "id", + "message_id": "messageID", + "session_id": "sessionID", + "text": "text", + "type": "text", + } + ], + text="text", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -70,7 +125,18 @@ async def test_raw_response_prompt(self, async_client: AsyncOpencode) -> None: @pytest.mark.skip() @parametrize async def test_streaming_response_prompt(self, async_client: AsyncOpencode) -> None: - async with async_client.tui.with_streaming_response.prompt() as response: + async with async_client.tui.with_streaming_response.prompt( + parts=[ + { + "id": "id", + "message_id": "messageID", + "session_id": "sessionID", + "text": "text", + "type": "text", + } + ], + text="text", + ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python"