summaryrefslogtreecommitdiffhomepage
path: root/packages/sdk/python/src/opencode_ai
diff options
context:
space:
mode:
Diffstat (limited to 'packages/sdk/python/src/opencode_ai')
-rw-r--r--packages/sdk/python/src/opencode_ai/__init__.py14
-rw-r--r--packages/sdk/python/src/opencode_ai/api/__init__.py1
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/__init__.py1
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/app_agents.py160
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/command_list.py164
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/config_get.py155
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/config_providers.py159
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/event_subscribe.py447
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/file_status.py160
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/path_get.py155
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/project_current.py155
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/project_list.py164
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/session_list.py164
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/tool_ids.py164
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/tui_clear_prompt.py153
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/tui_open_help.py153
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/tui_open_models.py153
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/tui_open_sessions.py153
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/tui_open_themes.py153
-rw-r--r--packages/sdk/python/src/opencode_ai/api/default/tui_submit_prompt.py153
-rw-r--r--packages/sdk/python/src/opencode_ai/client.py268
-rw-r--r--packages/sdk/python/src/opencode_ai/errors.py16
-rw-r--r--packages/sdk/python/src/opencode_ai/extras.py186
-rw-r--r--packages/sdk/python/src/opencode_ai/models/__init__.py367
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent.py180
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_config.py173
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_config_permission.py155
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_config_permission_bash_type_1.py74
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_config_tools.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_model.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_options.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_part.py117
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_part_input.py102
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_part_input_source.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_part_source.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_permission.py120
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_permission_bash.py74
-rw-r--r--packages/sdk/python/src/opencode_ai/models/agent_tools.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/api_auth.py69
-rw-r--r--packages/sdk/python/src/opencode_ai/models/assistant_message.py228
-rw-r--r--packages/sdk/python/src/opencode_ai/models/assistant_message_path.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/assistant_message_time.py70
-rw-r--r--packages/sdk/python/src/opencode_ai/models/assistant_message_tokens.py89
-rw-r--r--packages/sdk/python/src/opencode_ai/models/assistant_message_tokens_cache.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/command.py105
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config.py411
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_agent.py113
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_command.py57
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_command_additional_property.py97
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_experimental.py81
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_experimental_hook.py93
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited.py73
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited_additional_property_item.py87
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited_additional_property_item_environment.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_experimental_hook_session_completed_item.py87
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_experimental_hook_session_completed_item_environment.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_formatter.py57
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_formatter_additional_property.py105
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_formatter_additional_property_environment.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_lsp.py86
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_0.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1.py125
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1_env.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1_initialization.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_mcp.py82
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_mode.py97
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_permission.py155
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_permission_bash_type_1.py74
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_provider.py57
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_provider_additional_property.py118
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models.py63
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property.py214
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_cost.py87
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_limit.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_options.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_provider.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_options.py87
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_providers_response_200.py83
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_providers_response_200_default.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_share.py10
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_tools.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_tui.py60
-rw-r--r--packages/sdk/python/src/opencode_ai/models/config_watcher.py61
-rw-r--r--packages/sdk/python/src/opencode_ai/models/error.py65
-rw-r--r--packages/sdk/python/src/opencode_ai/models/error_data.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_file_edited.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_file_edited_properties.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_file_watcher_updated.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_file_watcher_updated_properties.py82
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_ide_installed.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_ide_installed_properties.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_installation_updated.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_installation_updated_properties.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_lsp_client_diagnostics.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_lsp_client_diagnostics_properties.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_message_part_removed.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_message_part_removed_properties.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_message_part_updated.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_message_part_updated_properties.py203
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_message_removed.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_message_removed_properties.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_message_updated.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_message_updated_properties.py89
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_permission_replied.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_permission_replied_properties.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_permission_updated.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_server_connected.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_server_connected_properties.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_session_compacted.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_session_compacted_properties.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_session_deleted.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_session_deleted_properties.py65
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_session_error.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_session_error_properties.py129
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_session_idle.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_session_idle_properties.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_session_updated.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/event_session_updated_properties.py65
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file.py85
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file_content.py92
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file_content_patch.py118
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file_content_patch_hunks_item.py91
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file_node.py93
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file_node_type.py9
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file_part.py154
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file_part_input.py139
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file_part_source_text.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file_source.py83
-rw-r--r--packages/sdk/python/src/opencode_ai/models/file_status.py10
-rw-r--r--packages/sdk/python/src/opencode_ai/models/keybinds_config.py474
-rw-r--r--packages/sdk/python/src/opencode_ai/models/layout_config.py9
-rw-r--r--packages/sdk/python/src/opencode_ai/models/mcp_local_config.py83
-rw-r--r--packages/sdk/python/src/opencode_ai/models/mcp_local_config_environment.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/mcp_remote_config.py83
-rw-r--r--packages/sdk/python/src/opencode_ai/models/mcp_remote_config_headers.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/message_aborted_error.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/message_aborted_error_data.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/message_output_length_error.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/message_output_length_error_data.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/model.py170
-rw-r--r--packages/sdk/python/src/opencode_ai/models/model_cost.py87
-rw-r--r--packages/sdk/python/src/opencode_ai/models/model_limit.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/model_options.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/model_provider.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/o_auth.py85
-rw-r--r--packages/sdk/python/src/opencode_ai/models/patch_part.py101
-rw-r--r--packages/sdk/python/src/opencode_ai/models/path.py83
-rw-r--r--packages/sdk/python/src/opencode_ai/models/permission.py155
-rw-r--r--packages/sdk/python/src/opencode_ai/models/permission_metadata.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/permission_time.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/project.py94
-rw-r--r--packages/sdk/python/src/opencode_ai/models/project_time.py70
-rw-r--r--packages/sdk/python/src/opencode_ai/models/provider.py109
-rw-r--r--packages/sdk/python/src/opencode_ai/models/provider_auth_error.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/provider_auth_error_data.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/provider_models.py57
-rw-r--r--packages/sdk/python/src/opencode_ai/models/range_.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/range_end.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/range_start.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/reasoning_part.py127
-rw-r--r--packages/sdk/python/src/opencode_ai/models/reasoning_part_metadata.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/reasoning_part_time.py70
-rw-r--r--packages/sdk/python/src/opencode_ai/models/session.py152
-rw-r--r--packages/sdk/python/src/opencode_ai/models/session_revert.py88
-rw-r--r--packages/sdk/python/src/opencode_ai/models/session_share.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/session_time.py78
-rw-r--r--packages/sdk/python/src/opencode_ai/models/snapshot_part.py93
-rw-r--r--packages/sdk/python/src/opencode_ai/models/step_finish_part.py107
-rw-r--r--packages/sdk/python/src/opencode_ai/models/step_finish_part_tokens.py89
-rw-r--r--packages/sdk/python/src/opencode_ai/models/step_finish_part_tokens_cache.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/step_start_part.py85
-rw-r--r--packages/sdk/python/src/opencode_ai/models/symbol.py81
-rw-r--r--packages/sdk/python/src/opencode_ai/models/symbol_location.py73
-rw-r--r--packages/sdk/python/src/opencode_ai/models/symbol_source.py109
-rw-r--r--packages/sdk/python/src/opencode_ai/models/text_part.py126
-rw-r--r--packages/sdk/python/src/opencode_ai/models/text_part_input.py111
-rw-r--r--packages/sdk/python/src/opencode_ai/models/text_part_input_time.py70
-rw-r--r--packages/sdk/python/src/opencode_ai/models/text_part_time.py70
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_list_item.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_part.py166
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_completed.py111
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_completed_input.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_completed_metadata.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_completed_time.py78
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_error.py113
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_error_input.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_error_metadata.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_error_time.py67
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_pending.py61
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_running.py112
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_running_metadata.py44
-rw-r--r--packages/sdk/python/src/opencode_ai/models/tool_state_running_time.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/unknown_error.py75
-rw-r--r--packages/sdk/python/src/opencode_ai/models/unknown_error_data.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/user_message.py91
-rw-r--r--packages/sdk/python/src/opencode_ai/models/user_message_time.py59
-rw-r--r--packages/sdk/python/src/opencode_ai/models/well_known_auth.py77
-rw-r--r--packages/sdk/python/src/opencode_ai/py.typed1
-rw-r--r--packages/sdk/python/src/opencode_ai/types.py54
199 files changed, 18505 insertions, 0 deletions
diff --git a/packages/sdk/python/src/opencode_ai/__init__.py b/packages/sdk/python/src/opencode_ai/__init__.py
new file mode 100644
index 000000000..846209d2e
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/__init__.py
@@ -0,0 +1,14 @@
+"""A client library for accessing opencode
+
+This package is generated by openapi-python-client.
+A thin convenience wrapper `OpenCodeClient` is also provided.
+"""
+
+from .client import AuthenticatedClient, Client
+from .extras import OpenCodeClient
+
+__all__ = (
+ "AuthenticatedClient",
+ "Client",
+ "OpenCodeClient",
+)
diff --git a/packages/sdk/python/src/opencode_ai/api/__init__.py b/packages/sdk/python/src/opencode_ai/api/__init__.py
new file mode 100644
index 000000000..81f9fa241
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/__init__.py
@@ -0,0 +1 @@
+"""Contains methods for accessing the API"""
diff --git a/packages/sdk/python/src/opencode_ai/api/default/__init__.py b/packages/sdk/python/src/opencode_ai/api/default/__init__.py
new file mode 100644
index 000000000..2d7c0b23d
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/__init__.py
@@ -0,0 +1 @@
+"""Contains endpoint functions for accessing the API"""
diff --git a/packages/sdk/python/src/opencode_ai/api/default/app_agents.py b/packages/sdk/python/src/opencode_ai/api/default/app_agents.py
new file mode 100644
index 000000000..075b6ed2b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/app_agents.py
@@ -0,0 +1,160 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.agent import Agent
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/agent",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[list["Agent"]]:
+ if response.status_code == 200:
+ response_200 = []
+ _response_200 = response.json()
+ for response_200_item_data in _response_200:
+ response_200_item = Agent.from_dict(response_200_item_data)
+
+ response_200.append(response_200_item)
+
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[list["Agent"]]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[list["Agent"]]:
+ """List all agents
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[list['Agent']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[list["Agent"]]:
+ """List all agents
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ list['Agent']
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[list["Agent"]]:
+ """List all agents
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[list['Agent']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[list["Agent"]]:
+ """List all agents
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ list['Agent']
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/command_list.py b/packages/sdk/python/src/opencode_ai/api/default/command_list.py
new file mode 100644
index 000000000..976a24584
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/command_list.py
@@ -0,0 +1,164 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.command import Command
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/command",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
+) -> Optional[list["Command"]]:
+ if response.status_code == 200:
+ response_200 = []
+ _response_200 = response.json()
+ for response_200_item_data in _response_200:
+ response_200_item = Command.from_dict(response_200_item_data)
+
+ response_200.append(response_200_item)
+
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
+) -> Response[list["Command"]]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[list["Command"]]:
+ """List all commands
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[list['Command']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[list["Command"]]:
+ """List all commands
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ list['Command']
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[list["Command"]]:
+ """List all commands
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[list['Command']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[list["Command"]]:
+ """List all commands
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ list['Command']
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/config_get.py b/packages/sdk/python/src/opencode_ai/api/default/config_get.py
new file mode 100644
index 000000000..71e387ffb
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/config_get.py
@@ -0,0 +1,155 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.config import Config
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/config",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Config]:
+ if response.status_code == 200:
+ response_200 = Config.from_dict(response.json())
+
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Config]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[Config]:
+ """Get config info
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[Config]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[Config]:
+ """Get config info
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Config
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[Config]:
+ """Get config info
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[Config]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[Config]:
+ """Get config info
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Config
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/config_providers.py b/packages/sdk/python/src/opencode_ai/api/default/config_providers.py
new file mode 100644
index 000000000..a7f031c49
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/config_providers.py
@@ -0,0 +1,159 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.config_providers_response_200 import ConfigProvidersResponse200
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/config/providers",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
+) -> Optional[ConfigProvidersResponse200]:
+ if response.status_code == 200:
+ response_200 = ConfigProvidersResponse200.from_dict(response.json())
+
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
+) -> Response[ConfigProvidersResponse200]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[ConfigProvidersResponse200]:
+ """List all providers
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[ConfigProvidersResponse200]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[ConfigProvidersResponse200]:
+ """List all providers
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ ConfigProvidersResponse200
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[ConfigProvidersResponse200]:
+ """List all providers
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[ConfigProvidersResponse200]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[ConfigProvidersResponse200]:
+ """List all providers
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ ConfigProvidersResponse200
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/event_subscribe.py b/packages/sdk/python/src/opencode_ai/api/default/event_subscribe.py
new file mode 100644
index 000000000..9b86214e2
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/event_subscribe.py
@@ -0,0 +1,447 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.event_file_edited import EventFileEdited
+from ...models.event_file_watcher_updated import EventFileWatcherUpdated
+from ...models.event_ide_installed import EventIdeInstalled
+from ...models.event_installation_updated import EventInstallationUpdated
+from ...models.event_lsp_client_diagnostics import EventLspClientDiagnostics
+from ...models.event_message_part_removed import EventMessagePartRemoved
+from ...models.event_message_part_updated import EventMessagePartUpdated
+from ...models.event_message_removed import EventMessageRemoved
+from ...models.event_message_updated import EventMessageUpdated
+from ...models.event_permission_replied import EventPermissionReplied
+from ...models.event_permission_updated import EventPermissionUpdated
+from ...models.event_server_connected import EventServerConnected
+from ...models.event_session_compacted import EventSessionCompacted
+from ...models.event_session_deleted import EventSessionDeleted
+from ...models.event_session_error import EventSessionError
+from ...models.event_session_idle import EventSessionIdle
+from ...models.event_session_updated import EventSessionUpdated
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/event",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[
+ Union[
+ "EventFileEdited",
+ "EventFileWatcherUpdated",
+ "EventIdeInstalled",
+ "EventInstallationUpdated",
+ "EventLspClientDiagnostics",
+ "EventMessagePartRemoved",
+ "EventMessagePartUpdated",
+ "EventMessageRemoved",
+ "EventMessageUpdated",
+ "EventPermissionReplied",
+ "EventPermissionUpdated",
+ "EventServerConnected",
+ "EventSessionCompacted",
+ "EventSessionDeleted",
+ "EventSessionError",
+ "EventSessionIdle",
+ "EventSessionUpdated",
+ ]
+]:
+ if response.status_code == 200:
+
+ def _parse_response_200(
+ data: object,
+ ) -> Union[
+ "EventFileEdited",
+ "EventFileWatcherUpdated",
+ "EventIdeInstalled",
+ "EventInstallationUpdated",
+ "EventLspClientDiagnostics",
+ "EventMessagePartRemoved",
+ "EventMessagePartUpdated",
+ "EventMessageRemoved",
+ "EventMessageUpdated",
+ "EventPermissionReplied",
+ "EventPermissionUpdated",
+ "EventServerConnected",
+ "EventSessionCompacted",
+ "EventSessionDeleted",
+ "EventSessionError",
+ "EventSessionIdle",
+ "EventSessionUpdated",
+ ]:
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_0 = EventInstallationUpdated.from_dict(data)
+
+ return componentsschemas_event_type_0
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_1 = EventLspClientDiagnostics.from_dict(data)
+
+ return componentsschemas_event_type_1
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_2 = EventMessageUpdated.from_dict(data)
+
+ return componentsschemas_event_type_2
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_3 = EventMessageRemoved.from_dict(data)
+
+ return componentsschemas_event_type_3
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_4 = EventMessagePartUpdated.from_dict(data)
+
+ return componentsschemas_event_type_4
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_5 = EventMessagePartRemoved.from_dict(data)
+
+ return componentsschemas_event_type_5
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_6 = EventSessionCompacted.from_dict(data)
+
+ return componentsschemas_event_type_6
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_7 = EventPermissionUpdated.from_dict(data)
+
+ return componentsschemas_event_type_7
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_8 = EventPermissionReplied.from_dict(data)
+
+ return componentsschemas_event_type_8
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_9 = EventFileEdited.from_dict(data)
+
+ return componentsschemas_event_type_9
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_10 = EventSessionIdle.from_dict(data)
+
+ return componentsschemas_event_type_10
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_11 = EventSessionUpdated.from_dict(data)
+
+ return componentsschemas_event_type_11
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_12 = EventSessionDeleted.from_dict(data)
+
+ return componentsschemas_event_type_12
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_13 = EventSessionError.from_dict(data)
+
+ return componentsschemas_event_type_13
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_14 = EventFileWatcherUpdated.from_dict(data)
+
+ return componentsschemas_event_type_14
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_15 = EventServerConnected.from_dict(data)
+
+ return componentsschemas_event_type_15
+ except: # noqa: E722
+ pass
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_event_type_16 = EventIdeInstalled.from_dict(data)
+
+ return componentsschemas_event_type_16
+
+ response_200 = _parse_response_200(response.text)
+
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[
+ Union[
+ "EventFileEdited",
+ "EventFileWatcherUpdated",
+ "EventIdeInstalled",
+ "EventInstallationUpdated",
+ "EventLspClientDiagnostics",
+ "EventMessagePartRemoved",
+ "EventMessagePartUpdated",
+ "EventMessageRemoved",
+ "EventMessageUpdated",
+ "EventPermissionReplied",
+ "EventPermissionUpdated",
+ "EventServerConnected",
+ "EventSessionCompacted",
+ "EventSessionDeleted",
+ "EventSessionError",
+ "EventSessionIdle",
+ "EventSessionUpdated",
+ ]
+]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[
+ Union[
+ "EventFileEdited",
+ "EventFileWatcherUpdated",
+ "EventIdeInstalled",
+ "EventInstallationUpdated",
+ "EventLspClientDiagnostics",
+ "EventMessagePartRemoved",
+ "EventMessagePartUpdated",
+ "EventMessageRemoved",
+ "EventMessageUpdated",
+ "EventPermissionReplied",
+ "EventPermissionUpdated",
+ "EventServerConnected",
+ "EventSessionCompacted",
+ "EventSessionDeleted",
+ "EventSessionError",
+ "EventSessionIdle",
+ "EventSessionUpdated",
+ ]
+]:
+ """Get events
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[Union['EventFileEdited', 'EventFileWatcherUpdated', 'EventIdeInstalled', 'EventInstallationUpdated', 'EventLspClientDiagnostics', 'EventMessagePartRemoved', 'EventMessagePartUpdated', 'EventMessageRemoved', 'EventMessageUpdated', 'EventPermissionReplied', 'EventPermissionUpdated', 'EventServerConnected', 'EventSessionCompacted', 'EventSessionDeleted', 'EventSessionError', 'EventSessionIdle', 'EventSessionUpdated']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[
+ Union[
+ "EventFileEdited",
+ "EventFileWatcherUpdated",
+ "EventIdeInstalled",
+ "EventInstallationUpdated",
+ "EventLspClientDiagnostics",
+ "EventMessagePartRemoved",
+ "EventMessagePartUpdated",
+ "EventMessageRemoved",
+ "EventMessageUpdated",
+ "EventPermissionReplied",
+ "EventPermissionUpdated",
+ "EventServerConnected",
+ "EventSessionCompacted",
+ "EventSessionDeleted",
+ "EventSessionError",
+ "EventSessionIdle",
+ "EventSessionUpdated",
+ ]
+]:
+ """Get events
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Union['EventFileEdited', 'EventFileWatcherUpdated', 'EventIdeInstalled', 'EventInstallationUpdated', 'EventLspClientDiagnostics', 'EventMessagePartRemoved', 'EventMessagePartUpdated', 'EventMessageRemoved', 'EventMessageUpdated', 'EventPermissionReplied', 'EventPermissionUpdated', 'EventServerConnected', 'EventSessionCompacted', 'EventSessionDeleted', 'EventSessionError', 'EventSessionIdle', 'EventSessionUpdated']
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[
+ Union[
+ "EventFileEdited",
+ "EventFileWatcherUpdated",
+ "EventIdeInstalled",
+ "EventInstallationUpdated",
+ "EventLspClientDiagnostics",
+ "EventMessagePartRemoved",
+ "EventMessagePartUpdated",
+ "EventMessageRemoved",
+ "EventMessageUpdated",
+ "EventPermissionReplied",
+ "EventPermissionUpdated",
+ "EventServerConnected",
+ "EventSessionCompacted",
+ "EventSessionDeleted",
+ "EventSessionError",
+ "EventSessionIdle",
+ "EventSessionUpdated",
+ ]
+]:
+ """Get events
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[Union['EventFileEdited', 'EventFileWatcherUpdated', 'EventIdeInstalled', 'EventInstallationUpdated', 'EventLspClientDiagnostics', 'EventMessagePartRemoved', 'EventMessagePartUpdated', 'EventMessageRemoved', 'EventMessageUpdated', 'EventPermissionReplied', 'EventPermissionUpdated', 'EventServerConnected', 'EventSessionCompacted', 'EventSessionDeleted', 'EventSessionError', 'EventSessionIdle', 'EventSessionUpdated']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[
+ Union[
+ "EventFileEdited",
+ "EventFileWatcherUpdated",
+ "EventIdeInstalled",
+ "EventInstallationUpdated",
+ "EventLspClientDiagnostics",
+ "EventMessagePartRemoved",
+ "EventMessagePartUpdated",
+ "EventMessageRemoved",
+ "EventMessageUpdated",
+ "EventPermissionReplied",
+ "EventPermissionUpdated",
+ "EventServerConnected",
+ "EventSessionCompacted",
+ "EventSessionDeleted",
+ "EventSessionError",
+ "EventSessionIdle",
+ "EventSessionUpdated",
+ ]
+]:
+ """Get events
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Union['EventFileEdited', 'EventFileWatcherUpdated', 'EventIdeInstalled', 'EventInstallationUpdated', 'EventLspClientDiagnostics', 'EventMessagePartRemoved', 'EventMessagePartUpdated', 'EventMessageRemoved', 'EventMessageUpdated', 'EventPermissionReplied', 'EventPermissionUpdated', 'EventServerConnected', 'EventSessionCompacted', 'EventSessionDeleted', 'EventSessionError', 'EventSessionIdle', 'EventSessionUpdated']
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/file_status.py b/packages/sdk/python/src/opencode_ai/api/default/file_status.py
new file mode 100644
index 000000000..8eecc3f2d
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/file_status.py
@@ -0,0 +1,160 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.file import File
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/file/status",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[list["File"]]:
+ if response.status_code == 200:
+ response_200 = []
+ _response_200 = response.json()
+ for response_200_item_data in _response_200:
+ response_200_item = File.from_dict(response_200_item_data)
+
+ response_200.append(response_200_item)
+
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[list["File"]]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[list["File"]]:
+ """Get file status
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[list['File']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[list["File"]]:
+ """Get file status
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ list['File']
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[list["File"]]:
+ """Get file status
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[list['File']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[list["File"]]:
+ """Get file status
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ list['File']
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/path_get.py b/packages/sdk/python/src/opencode_ai/api/default/path_get.py
new file mode 100644
index 000000000..c869a4586
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/path_get.py
@@ -0,0 +1,155 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.path import Path
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/path",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Path]:
+ if response.status_code == 200:
+ response_200 = Path.from_dict(response.json())
+
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Path]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[Path]:
+ """Get the current path
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[Path]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[Path]:
+ """Get the current path
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Path
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[Path]:
+ """Get the current path
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[Path]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[Path]:
+ """Get the current path
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Path
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/project_current.py b/packages/sdk/python/src/opencode_ai/api/default/project_current.py
new file mode 100644
index 000000000..712c6fd43
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/project_current.py
@@ -0,0 +1,155 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.project import Project
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/project/current",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Project]:
+ if response.status_code == 200:
+ response_200 = Project.from_dict(response.json())
+
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Project]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[Project]:
+ """Get the current project
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[Project]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[Project]:
+ """Get the current project
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Project
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[Project]:
+ """Get the current project
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[Project]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[Project]:
+ """Get the current project
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Project
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/project_list.py b/packages/sdk/python/src/opencode_ai/api/default/project_list.py
new file mode 100644
index 000000000..5ec38ae2b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/project_list.py
@@ -0,0 +1,164 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.project import Project
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/project",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
+) -> Optional[list["Project"]]:
+ if response.status_code == 200:
+ response_200 = []
+ _response_200 = response.json()
+ for response_200_item_data in _response_200:
+ response_200_item = Project.from_dict(response_200_item_data)
+
+ response_200.append(response_200_item)
+
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
+) -> Response[list["Project"]]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[list["Project"]]:
+ """List all projects
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[list['Project']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[list["Project"]]:
+ """List all projects
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ list['Project']
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[list["Project"]]:
+ """List all projects
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[list['Project']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[list["Project"]]:
+ """List all projects
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ list['Project']
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/session_list.py b/packages/sdk/python/src/opencode_ai/api/default/session_list.py
new file mode 100644
index 000000000..8e7fd6a6f
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/session_list.py
@@ -0,0 +1,164 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.session import Session
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/session",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
+) -> Optional[list["Session"]]:
+ if response.status_code == 200:
+ response_200 = []
+ _response_200 = response.json()
+ for response_200_item_data in _response_200:
+ response_200_item = Session.from_dict(response_200_item_data)
+
+ response_200.append(response_200_item)
+
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
+) -> Response[list["Session"]]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[list["Session"]]:
+ """List all sessions
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[list['Session']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[list["Session"]]:
+ """List all sessions
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ list['Session']
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[list["Session"]]:
+ """List all sessions
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[list['Session']]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[list["Session"]]:
+ """List all sessions
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ list['Session']
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/tool_ids.py b/packages/sdk/python/src/opencode_ai/api/default/tool_ids.py
new file mode 100644
index 000000000..0315cd195
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/tool_ids.py
@@ -0,0 +1,164 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union, cast
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...models.error import Error
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "get",
+ "url": "/experimental/tool/ids",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
+) -> Optional[Union[Error, list[str]]]:
+ if response.status_code == 200:
+ response_200 = cast(list[str], response.json())
+
+ return response_200
+
+ if response.status_code == 400:
+ response_400 = Error.from_dict(response.json())
+
+ return response_400
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
+) -> Response[Union[Error, list[str]]]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[Union[Error, list[str]]]:
+ """List all tool IDs (including built-in and dynamically registered)
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[Union[Error, list[str]]]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[Union[Error, list[str]]]:
+ """List all tool IDs (including built-in and dynamically registered)
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Union[Error, list[str]]
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[Union[Error, list[str]]]:
+ """List all tool IDs (including built-in and dynamically registered)
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[Union[Error, list[str]]]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[Union[Error, list[str]]]:
+ """List all tool IDs (including built-in and dynamically registered)
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Union[Error, list[str]]
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/tui_clear_prompt.py b/packages/sdk/python/src/opencode_ai/api/default/tui_clear_prompt.py
new file mode 100644
index 000000000..a7c5ef50d
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/tui_clear_prompt.py
@@ -0,0 +1,153 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union, cast
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "post",
+ "url": "/tui/clear-prompt",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[bool]:
+ if response.status_code == 200:
+ response_200 = cast(bool, response.json())
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[bool]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Clear the prompt
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Clear the prompt
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Clear the prompt
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Clear the prompt
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/tui_open_help.py b/packages/sdk/python/src/opencode_ai/api/default/tui_open_help.py
new file mode 100644
index 000000000..e7ae959a7
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/tui_open_help.py
@@ -0,0 +1,153 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union, cast
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "post",
+ "url": "/tui/open-help",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[bool]:
+ if response.status_code == 200:
+ response_200 = cast(bool, response.json())
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[bool]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Open the help dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Open the help dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Open the help dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Open the help dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/tui_open_models.py b/packages/sdk/python/src/opencode_ai/api/default/tui_open_models.py
new file mode 100644
index 000000000..a6dddf136
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/tui_open_models.py
@@ -0,0 +1,153 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union, cast
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "post",
+ "url": "/tui/open-models",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[bool]:
+ if response.status_code == 200:
+ response_200 = cast(bool, response.json())
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[bool]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Open the model dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Open the model dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Open the model dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Open the model dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/tui_open_sessions.py b/packages/sdk/python/src/opencode_ai/api/default/tui_open_sessions.py
new file mode 100644
index 000000000..579934f26
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/tui_open_sessions.py
@@ -0,0 +1,153 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union, cast
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "post",
+ "url": "/tui/open-sessions",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[bool]:
+ if response.status_code == 200:
+ response_200 = cast(bool, response.json())
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[bool]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Open the session dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Open the session dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Open the session dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Open the session dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/tui_open_themes.py b/packages/sdk/python/src/opencode_ai/api/default/tui_open_themes.py
new file mode 100644
index 000000000..05db1aadf
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/tui_open_themes.py
@@ -0,0 +1,153 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union, cast
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "post",
+ "url": "/tui/open-themes",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[bool]:
+ if response.status_code == 200:
+ response_200 = cast(bool, response.json())
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[bool]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Open the theme dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Open the theme dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Open the theme dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Open the theme dialog
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/api/default/tui_submit_prompt.py b/packages/sdk/python/src/opencode_ai/api/default/tui_submit_prompt.py
new file mode 100644
index 000000000..d16a75d27
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/api/default/tui_submit_prompt.py
@@ -0,0 +1,153 @@
+from http import HTTPStatus
+from typing import Any, Optional, Union, cast
+
+import httpx
+
+from ... import errors
+from ...client import AuthenticatedClient, Client
+from ...types import UNSET, Response, Unset
+
+
+def _get_kwargs(
+ *,
+ directory: Union[Unset, str] = UNSET,
+) -> dict[str, Any]:
+ params: dict[str, Any] = {}
+
+ params["directory"] = directory
+
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
+
+ _kwargs: dict[str, Any] = {
+ "method": "post",
+ "url": "/tui/submit-prompt",
+ "params": params,
+ }
+
+ return _kwargs
+
+
+def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[bool]:
+ if response.status_code == 200:
+ response_200 = cast(bool, response.json())
+ return response_200
+
+ if client.raise_on_unexpected_status:
+ raise errors.UnexpectedStatus(response.status_code, response.content)
+ else:
+ return None
+
+
+def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[bool]:
+ return Response(
+ status_code=HTTPStatus(response.status_code),
+ content=response.content,
+ headers=response.headers,
+ parsed=_parse_response(client=client, response=response),
+ )
+
+
+def sync_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Submit the prompt
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = client.get_httpx_client().request(
+ **kwargs,
+ )
+
+ return _build_response(client=client, response=response)
+
+
+def sync(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Submit the prompt
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return sync_detailed(
+ client=client,
+ directory=directory,
+ ).parsed
+
+
+async def asyncio_detailed(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Response[bool]:
+ """Submit the prompt
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ Response[bool]
+ """
+
+ kwargs = _get_kwargs(
+ directory=directory,
+ )
+
+ response = await client.get_async_httpx_client().request(**kwargs)
+
+ return _build_response(client=client, response=response)
+
+
+async def asyncio(
+ *,
+ client: Union[AuthenticatedClient, Client],
+ directory: Union[Unset, str] = UNSET,
+) -> Optional[bool]:
+ """Submit the prompt
+
+ Args:
+ directory (Union[Unset, str]):
+
+ Raises:
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
+
+ Returns:
+ bool
+ """
+
+ return (
+ await asyncio_detailed(
+ client=client,
+ directory=directory,
+ )
+ ).parsed
diff --git a/packages/sdk/python/src/opencode_ai/client.py b/packages/sdk/python/src/opencode_ai/client.py
new file mode 100644
index 000000000..e80446f10
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/client.py
@@ -0,0 +1,268 @@
+import ssl
+from typing import Any, Optional, Union
+
+import httpx
+from attrs import define, evolve, field
+
+
+@define
+class Client:
+ """A class for keeping track of data related to the API
+
+ The following are accepted as keyword arguments and will be used to construct httpx Clients internally:
+
+ ``base_url``: The base URL for the API, all requests are made to a relative path to this URL
+
+ ``cookies``: A dictionary of cookies to be sent with every request
+
+ ``headers``: A dictionary of headers to be sent with every request
+
+ ``timeout``: The maximum amount of a time a request can take. API functions will raise
+ httpx.TimeoutException if this is exceeded.
+
+ ``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production,
+ but can be set to False for testing purposes.
+
+ ``follow_redirects``: Whether or not to follow redirects. Default value is False.
+
+ ``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
+
+
+ Attributes:
+ raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a
+ status code that was not documented in the source OpenAPI document. Can also be provided as a keyword
+ argument to the constructor.
+ """
+
+ raise_on_unexpected_status: bool = field(default=False, kw_only=True)
+ _base_url: str = field(alias="base_url")
+ _cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
+ _headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
+ _timeout: Optional[httpx.Timeout] = field(default=None, kw_only=True, alias="timeout")
+ _verify_ssl: Union[str, bool, ssl.SSLContext] = field(default=True, kw_only=True, alias="verify_ssl")
+ _follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects")
+ _httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
+ _client: Optional[httpx.Client] = field(default=None, init=False)
+ _async_client: Optional[httpx.AsyncClient] = field(default=None, init=False)
+
+ def with_headers(self, headers: dict[str, str]) -> "Client":
+ """Get a new client matching this one with additional headers"""
+ if self._client is not None:
+ self._client.headers.update(headers)
+ if self._async_client is not None:
+ self._async_client.headers.update(headers)
+ return evolve(self, headers={**self._headers, **headers})
+
+ def with_cookies(self, cookies: dict[str, str]) -> "Client":
+ """Get a new client matching this one with additional cookies"""
+ if self._client is not None:
+ self._client.cookies.update(cookies)
+ if self._async_client is not None:
+ self._async_client.cookies.update(cookies)
+ return evolve(self, cookies={**self._cookies, **cookies})
+
+ def with_timeout(self, timeout: httpx.Timeout) -> "Client":
+ """Get a new client matching this one with a new timeout (in seconds)"""
+ if self._client is not None:
+ self._client.timeout = timeout
+ if self._async_client is not None:
+ self._async_client.timeout = timeout
+ return evolve(self, timeout=timeout)
+
+ def set_httpx_client(self, client: httpx.Client) -> "Client":
+ """Manually set the underlying httpx.Client
+
+ **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
+ """
+ self._client = client
+ return self
+
+ def get_httpx_client(self) -> httpx.Client:
+ """Get the underlying httpx.Client, constructing a new one if not previously set"""
+ if self._client is None:
+ self._client = httpx.Client(
+ base_url=self._base_url,
+ cookies=self._cookies,
+ headers=self._headers,
+ timeout=self._timeout,
+ verify=self._verify_ssl,
+ follow_redirects=self._follow_redirects,
+ **self._httpx_args,
+ )
+ return self._client
+
+ def __enter__(self) -> "Client":
+ """Enter a context manager for self.client—you cannot enter twice (see httpx docs)"""
+ self.get_httpx_client().__enter__()
+ return self
+
+ def __exit__(self, *args: Any, **kwargs: Any) -> None:
+ """Exit a context manager for internal httpx.Client (see httpx docs)"""
+ self.get_httpx_client().__exit__(*args, **kwargs)
+
+ def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "Client":
+ """Manually the underlying httpx.AsyncClient
+
+ **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
+ """
+ self._async_client = async_client
+ return self
+
+ def get_async_httpx_client(self) -> httpx.AsyncClient:
+ """Get the underlying httpx.AsyncClient, constructing a new one if not previously set"""
+ if self._async_client is None:
+ self._async_client = httpx.AsyncClient(
+ base_url=self._base_url,
+ cookies=self._cookies,
+ headers=self._headers,
+ timeout=self._timeout,
+ verify=self._verify_ssl,
+ follow_redirects=self._follow_redirects,
+ **self._httpx_args,
+ )
+ return self._async_client
+
+ async def __aenter__(self) -> "Client":
+ """Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)"""
+ await self.get_async_httpx_client().__aenter__()
+ return self
+
+ async def __aexit__(self, *args: Any, **kwargs: Any) -> None:
+ """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)"""
+ await self.get_async_httpx_client().__aexit__(*args, **kwargs)
+
+
+@define
+class AuthenticatedClient:
+ """A Client which has been authenticated for use on secured endpoints
+
+ The following are accepted as keyword arguments and will be used to construct httpx Clients internally:
+
+ ``base_url``: The base URL for the API, all requests are made to a relative path to this URL
+
+ ``cookies``: A dictionary of cookies to be sent with every request
+
+ ``headers``: A dictionary of headers to be sent with every request
+
+ ``timeout``: The maximum amount of a time a request can take. API functions will raise
+ httpx.TimeoutException if this is exceeded.
+
+ ``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production,
+ but can be set to False for testing purposes.
+
+ ``follow_redirects``: Whether or not to follow redirects. Default value is False.
+
+ ``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
+
+
+ Attributes:
+ raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a
+ status code that was not documented in the source OpenAPI document. Can also be provided as a keyword
+ argument to the constructor.
+ token: The token to use for authentication
+ prefix: The prefix to use for the Authorization header
+ auth_header_name: The name of the Authorization header
+ """
+
+ raise_on_unexpected_status: bool = field(default=False, kw_only=True)
+ _base_url: str = field(alias="base_url")
+ _cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
+ _headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
+ _timeout: Optional[httpx.Timeout] = field(default=None, kw_only=True, alias="timeout")
+ _verify_ssl: Union[str, bool, ssl.SSLContext] = field(default=True, kw_only=True, alias="verify_ssl")
+ _follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects")
+ _httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
+ _client: Optional[httpx.Client] = field(default=None, init=False)
+ _async_client: Optional[httpx.AsyncClient] = field(default=None, init=False)
+
+ token: str
+ prefix: str = "Bearer"
+ auth_header_name: str = "Authorization"
+
+ def with_headers(self, headers: dict[str, str]) -> "AuthenticatedClient":
+ """Get a new client matching this one with additional headers"""
+ if self._client is not None:
+ self._client.headers.update(headers)
+ if self._async_client is not None:
+ self._async_client.headers.update(headers)
+ return evolve(self, headers={**self._headers, **headers})
+
+ def with_cookies(self, cookies: dict[str, str]) -> "AuthenticatedClient":
+ """Get a new client matching this one with additional cookies"""
+ if self._client is not None:
+ self._client.cookies.update(cookies)
+ if self._async_client is not None:
+ self._async_client.cookies.update(cookies)
+ return evolve(self, cookies={**self._cookies, **cookies})
+
+ def with_timeout(self, timeout: httpx.Timeout) -> "AuthenticatedClient":
+ """Get a new client matching this one with a new timeout (in seconds)"""
+ if self._client is not None:
+ self._client.timeout = timeout
+ if self._async_client is not None:
+ self._async_client.timeout = timeout
+ return evolve(self, timeout=timeout)
+
+ def set_httpx_client(self, client: httpx.Client) -> "AuthenticatedClient":
+ """Manually set the underlying httpx.Client
+
+ **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
+ """
+ self._client = client
+ return self
+
+ def get_httpx_client(self) -> httpx.Client:
+ """Get the underlying httpx.Client, constructing a new one if not previously set"""
+ if self._client is None:
+ self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token
+ self._client = httpx.Client(
+ base_url=self._base_url,
+ cookies=self._cookies,
+ headers=self._headers,
+ timeout=self._timeout,
+ verify=self._verify_ssl,
+ follow_redirects=self._follow_redirects,
+ **self._httpx_args,
+ )
+ return self._client
+
+ def __enter__(self) -> "AuthenticatedClient":
+ """Enter a context manager for self.client—you cannot enter twice (see httpx docs)"""
+ self.get_httpx_client().__enter__()
+ return self
+
+ def __exit__(self, *args: Any, **kwargs: Any) -> None:
+ """Exit a context manager for internal httpx.Client (see httpx docs)"""
+ self.get_httpx_client().__exit__(*args, **kwargs)
+
+ def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "AuthenticatedClient":
+ """Manually the underlying httpx.AsyncClient
+
+ **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
+ """
+ self._async_client = async_client
+ return self
+
+ def get_async_httpx_client(self) -> httpx.AsyncClient:
+ """Get the underlying httpx.AsyncClient, constructing a new one if not previously set"""
+ if self._async_client is None:
+ self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token
+ self._async_client = httpx.AsyncClient(
+ base_url=self._base_url,
+ cookies=self._cookies,
+ headers=self._headers,
+ timeout=self._timeout,
+ verify=self._verify_ssl,
+ follow_redirects=self._follow_redirects,
+ **self._httpx_args,
+ )
+ return self._async_client
+
+ async def __aenter__(self) -> "AuthenticatedClient":
+ """Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)"""
+ await self.get_async_httpx_client().__aenter__()
+ return self
+
+ async def __aexit__(self, *args: Any, **kwargs: Any) -> None:
+ """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)"""
+ await self.get_async_httpx_client().__aexit__(*args, **kwargs)
diff --git a/packages/sdk/python/src/opencode_ai/errors.py b/packages/sdk/python/src/opencode_ai/errors.py
new file mode 100644
index 000000000..5f92e76ac
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/errors.py
@@ -0,0 +1,16 @@
+"""Contains shared errors types that can be raised from API functions"""
+
+
+class UnexpectedStatus(Exception):
+ """Raised by api functions when the response status an undocumented status and Client.raise_on_unexpected_status is True"""
+
+ def __init__(self, status_code: int, content: bytes):
+ self.status_code = status_code
+ self.content = content
+
+ super().__init__(
+ f"Unexpected status code: {status_code}\n\nResponse content:\n{content.decode(errors='ignore')}"
+ )
+
+
+__all__ = ["UnexpectedStatus"]
diff --git a/packages/sdk/python/src/opencode_ai/extras.py b/packages/sdk/python/src/opencode_ai/extras.py
new file mode 100644
index 000000000..1a9110196
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/extras.py
@@ -0,0 +1,186 @@
+from __future__ import annotations
+
+import time
+from typing import AsyncIterator, Dict, Iterator, Optional
+
+import httpx
+
+from .api.default import (
+ app_agents,
+ command_list,
+ config_get,
+ config_providers,
+ file_status,
+ path_get,
+ project_current,
+ project_list,
+ session_list,
+ tool_ids,
+)
+from .client import Client
+from .types import UNSET, Unset
+
+
+class OpenCodeClient:
+ """High-level convenience wrapper around the generated Client.
+
+ Provides sensible defaults and a couple of helper methods, with optional retries.
+ """
+
+ def __init__(
+ self,
+ base_url: str = "http://localhost:4096",
+ *,
+ headers: Optional[Dict[str, str]] = None,
+ timeout: Optional[float] = None,
+ verify_ssl: bool | str | httpx.URLTypes | None = True,
+ token: Optional[str] = None,
+ auth_header_name: str = "Authorization",
+ auth_prefix: str = "Bearer",
+ retries: int = 0,
+ backoff_factor: float = 0.5,
+ status_forcelist: tuple[int, ...] = (429, 500, 502, 503, 504),
+ ) -> None:
+ httpx_timeout = None if timeout is None else httpx.Timeout(timeout)
+ all_headers = dict(headers or {})
+ if token:
+ all_headers[auth_header_name] = f"{auth_prefix} {token}".strip()
+ self._client = Client(
+ base_url=base_url,
+ headers=all_headers,
+ timeout=httpx_timeout,
+ verify_ssl=verify_ssl if isinstance(verify_ssl, bool) else True,
+ )
+ self._retries = max(0, int(retries))
+ self._backoff = float(backoff_factor)
+ self._status_forcelist = set(status_forcelist)
+
+ @property
+ def client(self) -> Client:
+ return self._client
+
+ # ---- Internal retry helper ----
+
+ def _call_with_retries(self, fn, *args, **kwargs):
+ attempt = 0
+ while True:
+ try:
+ return fn(*args, **kwargs)
+ except httpx.RequestError:
+ pass
+ except httpx.HTTPStatusError as e:
+ if e.response is None or e.response.status_code not in self._status_forcelist:
+ raise
+ if attempt >= self._retries:
+ # re-raise last exception if we have one
+ raise
+ sleep = self._backoff * (2**attempt)
+ time.sleep(sleep)
+ attempt += 1
+
+ # ---- Convenience wrappers over generated endpoints ----
+
+ def list_sessions(self, *, directory: str | Unset = UNSET):
+ """Return sessions in the current project.
+
+ Wraps GET /session. Pass `directory` to target a specific project/directory if needed.
+ """
+ return self._call_with_retries(session_list.sync, client=self._client, directory=directory)
+
+ def get_config(self, *, directory: str | Unset = UNSET):
+ """Return opencode configuration for the current project (GET /config)."""
+ return self._call_with_retries(config_get.sync, client=self._client, directory=directory)
+
+ def list_agents(self, *, directory: str | Unset = UNSET):
+ """List configured agents (GET /agent)."""
+ return self._call_with_retries(app_agents.sync, client=self._client, directory=directory)
+
+ def list_projects(self, *, directory: str | Unset = UNSET):
+ """List known projects (GET /project)."""
+ return self._call_with_retries(project_list.sync, client=self._client, directory=directory)
+
+ def current_project(self, *, directory: str | Unset = UNSET):
+ """Return current project (GET /project/current)."""
+ return self._call_with_retries(project_current.sync, client=self._client, directory=directory)
+
+ def file_status(self, *, directory: str | Unset = UNSET):
+ """Return file status list (GET /file/status)."""
+ return self._call_with_retries(file_status.sync, client=self._client, directory=directory)
+
+ def get_path(self, *, directory: str | Unset = UNSET):
+ """Return opencode path info (GET /path)."""
+ return self._call_with_retries(path_get.sync, client=self._client, directory=directory)
+
+ def config_providers(self, *, directory: str | Unset = UNSET):
+ """Return configured providers (GET /config/providers)."""
+ return self._call_with_retries(config_providers.sync, client=self._client, directory=directory)
+
+ def tool_ids(self, *, directory: str | Unset = UNSET):
+ """Return tool identifiers for a provider/model pair (GET /experimental/tool)."""
+ return self._call_with_retries(tool_ids.sync, client=self._client, directory=directory)
+
+ def list_commands(self, *, directory: str | Unset = UNSET):
+ """List commands (GET /command)."""
+ return self._call_with_retries(command_list.sync, client=self._client, directory=directory)
+
+ # ---- Server-Sent Events (SSE) streaming ----
+
+ def subscribe_events(self, *, directory: str | Unset = UNSET) -> Iterator[dict]:
+ """Subscribe to /event SSE endpoint and yield parsed JSON events.
+
+ This is a blocking generator which yields one event dict per message.
+ """
+ client = self._client.get_httpx_client()
+ params: dict[str, str] = {}
+ if directory is not UNSET and directory is not None:
+ params["directory"] = str(directory)
+ with client.stream("GET", "/event", headers={"Accept": "text/event-stream"}, params=params) as r:
+ r.raise_for_status()
+ buf = ""
+ for line_bytes in r.iter_lines():
+ line = line_bytes.decode("utf-8") if isinstance(line_bytes, (bytes, bytearray)) else str(line_bytes)
+ if line.startswith(":"):
+ # comment/heartbeat
+ continue
+ if line == "":
+ if buf:
+ # end of event
+ for part in buf.split("\n"):
+ if part.startswith("data:"):
+ data = part[5:].strip()
+ if data:
+ try:
+ yield httpx._models.jsonlib.loads(data) # type: ignore[attr-defined]
+ except Exception:
+ # fall back: skip malformed
+ pass
+ buf = ""
+ continue
+ buf += line + "\n"
+
+ async def subscribe_events_async(self, *, directory: str | Unset = UNSET) -> AsyncIterator[dict]:
+ """Async variant of subscribe_events using httpx.AsyncClient."""
+ aclient = self._client.get_async_httpx_client()
+ params: dict[str, str] = {}
+ if directory is not UNSET and directory is not None:
+ params["directory"] = str(directory)
+ async with aclient.stream("GET", "/event", headers={"Accept": "text/event-stream"}, params=params) as r:
+ r.raise_for_status()
+ buf = ""
+ async for line_bytes in r.aiter_lines():
+ line = line_bytes
+ if line.startswith(":"):
+ continue
+ if line == "":
+ if buf:
+ for part in buf.split("\n"):
+ if part.startswith("data:"):
+ data = part[5:].strip()
+ if data:
+ try:
+ yield httpx._models.jsonlib.loads(data) # type: ignore[attr-defined]
+ except Exception:
+ pass
+ buf = ""
+ continue
+ buf += line + "\n"
diff --git a/packages/sdk/python/src/opencode_ai/models/__init__.py b/packages/sdk/python/src/opencode_ai/models/__init__.py
new file mode 100644
index 000000000..6c20f7566
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/__init__.py
@@ -0,0 +1,367 @@
+"""Contains all the data models used in inputs/outputs"""
+
+from .agent import Agent
+from .agent_config import AgentConfig
+from .agent_config_permission import AgentConfigPermission
+from .agent_config_permission_bash_type_1 import AgentConfigPermissionBashType1
+from .agent_config_tools import AgentConfigTools
+from .agent_model import AgentModel
+from .agent_options import AgentOptions
+from .agent_part import AgentPart
+from .agent_part_input import AgentPartInput
+from .agent_part_input_source import AgentPartInputSource
+from .agent_part_source import AgentPartSource
+from .agent_permission import AgentPermission
+from .agent_permission_bash import AgentPermissionBash
+from .agent_tools import AgentTools
+from .api_auth import ApiAuth
+from .assistant_message import AssistantMessage
+from .assistant_message_path import AssistantMessagePath
+from .assistant_message_time import AssistantMessageTime
+from .assistant_message_tokens import AssistantMessageTokens
+from .assistant_message_tokens_cache import AssistantMessageTokensCache
+from .command import Command
+from .config import Config
+from .config_agent import ConfigAgent
+from .config_command import ConfigCommand
+from .config_command_additional_property import ConfigCommandAdditionalProperty
+from .config_experimental import ConfigExperimental
+from .config_experimental_hook import ConfigExperimentalHook
+from .config_experimental_hook_file_edited import ConfigExperimentalHookFileEdited
+from .config_experimental_hook_file_edited_additional_property_item import (
+ ConfigExperimentalHookFileEditedAdditionalPropertyItem,
+)
+from .config_experimental_hook_file_edited_additional_property_item_environment import (
+ ConfigExperimentalHookFileEditedAdditionalPropertyItemEnvironment,
+)
+from .config_experimental_hook_session_completed_item import ConfigExperimentalHookSessionCompletedItem
+from .config_experimental_hook_session_completed_item_environment import (
+ ConfigExperimentalHookSessionCompletedItemEnvironment,
+)
+from .config_formatter import ConfigFormatter
+from .config_formatter_additional_property import ConfigFormatterAdditionalProperty
+from .config_formatter_additional_property_environment import ConfigFormatterAdditionalPropertyEnvironment
+from .config_lsp import ConfigLsp
+from .config_lsp_additional_property_type_0 import ConfigLspAdditionalPropertyType0
+from .config_lsp_additional_property_type_1 import ConfigLspAdditionalPropertyType1
+from .config_lsp_additional_property_type_1_env import ConfigLspAdditionalPropertyType1Env
+from .config_lsp_additional_property_type_1_initialization import ConfigLspAdditionalPropertyType1Initialization
+from .config_mcp import ConfigMcp
+from .config_mode import ConfigMode
+from .config_permission import ConfigPermission
+from .config_permission_bash_type_1 import ConfigPermissionBashType1
+from .config_provider import ConfigProvider
+from .config_provider_additional_property import ConfigProviderAdditionalProperty
+from .config_provider_additional_property_models import ConfigProviderAdditionalPropertyModels
+from .config_provider_additional_property_models_additional_property import (
+ ConfigProviderAdditionalPropertyModelsAdditionalProperty,
+)
+from .config_provider_additional_property_models_additional_property_cost import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyCost,
+)
+from .config_provider_additional_property_models_additional_property_limit import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyLimit,
+)
+from .config_provider_additional_property_models_additional_property_options import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyOptions,
+)
+from .config_provider_additional_property_models_additional_property_provider import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyProvider,
+)
+from .config_provider_additional_property_options import ConfigProviderAdditionalPropertyOptions
+from .config_providers_response_200 import ConfigProvidersResponse200
+from .config_providers_response_200_default import ConfigProvidersResponse200Default
+from .config_share import ConfigShare
+from .config_tools import ConfigTools
+from .config_tui import ConfigTui
+from .config_watcher import ConfigWatcher
+from .error import Error
+from .error_data import ErrorData
+from .event_file_edited import EventFileEdited
+from .event_file_edited_properties import EventFileEditedProperties
+from .event_file_watcher_updated import EventFileWatcherUpdated
+from .event_file_watcher_updated_properties import EventFileWatcherUpdatedProperties
+from .event_ide_installed import EventIdeInstalled
+from .event_ide_installed_properties import EventIdeInstalledProperties
+from .event_installation_updated import EventInstallationUpdated
+from .event_installation_updated_properties import EventInstallationUpdatedProperties
+from .event_lsp_client_diagnostics import EventLspClientDiagnostics
+from .event_lsp_client_diagnostics_properties import EventLspClientDiagnosticsProperties
+from .event_message_part_removed import EventMessagePartRemoved
+from .event_message_part_removed_properties import EventMessagePartRemovedProperties
+from .event_message_part_updated import EventMessagePartUpdated
+from .event_message_part_updated_properties import EventMessagePartUpdatedProperties
+from .event_message_removed import EventMessageRemoved
+from .event_message_removed_properties import EventMessageRemovedProperties
+from .event_message_updated import EventMessageUpdated
+from .event_message_updated_properties import EventMessageUpdatedProperties
+from .event_permission_replied import EventPermissionReplied
+from .event_permission_replied_properties import EventPermissionRepliedProperties
+from .event_permission_updated import EventPermissionUpdated
+from .event_server_connected import EventServerConnected
+from .event_server_connected_properties import EventServerConnectedProperties
+from .event_session_compacted import EventSessionCompacted
+from .event_session_compacted_properties import EventSessionCompactedProperties
+from .event_session_deleted import EventSessionDeleted
+from .event_session_deleted_properties import EventSessionDeletedProperties
+from .event_session_error import EventSessionError
+from .event_session_error_properties import EventSessionErrorProperties
+from .event_session_idle import EventSessionIdle
+from .event_session_idle_properties import EventSessionIdleProperties
+from .event_session_updated import EventSessionUpdated
+from .event_session_updated_properties import EventSessionUpdatedProperties
+from .file import File
+from .file_content import FileContent
+from .file_content_patch import FileContentPatch
+from .file_content_patch_hunks_item import FileContentPatchHunksItem
+from .file_node import FileNode
+from .file_node_type import FileNodeType
+from .file_part import FilePart
+from .file_part_input import FilePartInput
+from .file_part_source_text import FilePartSourceText
+from .file_source import FileSource
+from .file_status import FileStatus
+from .keybinds_config import KeybindsConfig
+from .layout_config import LayoutConfig
+from .mcp_local_config import McpLocalConfig
+from .mcp_local_config_environment import McpLocalConfigEnvironment
+from .mcp_remote_config import McpRemoteConfig
+from .mcp_remote_config_headers import McpRemoteConfigHeaders
+from .message_aborted_error import MessageAbortedError
+from .message_aborted_error_data import MessageAbortedErrorData
+from .message_output_length_error import MessageOutputLengthError
+from .message_output_length_error_data import MessageOutputLengthErrorData
+from .model import Model
+from .model_cost import ModelCost
+from .model_limit import ModelLimit
+from .model_options import ModelOptions
+from .model_provider import ModelProvider
+from .o_auth import OAuth
+from .patch_part import PatchPart
+from .path import Path
+from .permission import Permission
+from .permission_metadata import PermissionMetadata
+from .permission_time import PermissionTime
+from .project import Project
+from .project_time import ProjectTime
+from .provider import Provider
+from .provider_auth_error import ProviderAuthError
+from .provider_auth_error_data import ProviderAuthErrorData
+from .provider_models import ProviderModels
+from .range_ import Range
+from .range_end import RangeEnd
+from .range_start import RangeStart
+from .reasoning_part import ReasoningPart
+from .reasoning_part_metadata import ReasoningPartMetadata
+from .reasoning_part_time import ReasoningPartTime
+from .session import Session
+from .session_revert import SessionRevert
+from .session_share import SessionShare
+from .session_time import SessionTime
+from .snapshot_part import SnapshotPart
+from .step_finish_part import StepFinishPart
+from .step_finish_part_tokens import StepFinishPartTokens
+from .step_finish_part_tokens_cache import StepFinishPartTokensCache
+from .step_start_part import StepStartPart
+from .symbol import Symbol
+from .symbol_location import SymbolLocation
+from .symbol_source import SymbolSource
+from .text_part import TextPart
+from .text_part_input import TextPartInput
+from .text_part_input_time import TextPartInputTime
+from .text_part_time import TextPartTime
+from .tool_list_item import ToolListItem
+from .tool_part import ToolPart
+from .tool_state_completed import ToolStateCompleted
+from .tool_state_completed_input import ToolStateCompletedInput
+from .tool_state_completed_metadata import ToolStateCompletedMetadata
+from .tool_state_completed_time import ToolStateCompletedTime
+from .tool_state_error import ToolStateError
+from .tool_state_error_input import ToolStateErrorInput
+from .tool_state_error_metadata import ToolStateErrorMetadata
+from .tool_state_error_time import ToolStateErrorTime
+from .tool_state_pending import ToolStatePending
+from .tool_state_running import ToolStateRunning
+from .tool_state_running_metadata import ToolStateRunningMetadata
+from .tool_state_running_time import ToolStateRunningTime
+from .unknown_error import UnknownError
+from .unknown_error_data import UnknownErrorData
+from .user_message import UserMessage
+from .user_message_time import UserMessageTime
+from .well_known_auth import WellKnownAuth
+
+__all__ = (
+ "Agent",
+ "AgentConfig",
+ "AgentConfigPermission",
+ "AgentConfigPermissionBashType1",
+ "AgentConfigTools",
+ "AgentModel",
+ "AgentOptions",
+ "AgentPart",
+ "AgentPartInput",
+ "AgentPartInputSource",
+ "AgentPartSource",
+ "AgentPermission",
+ "AgentPermissionBash",
+ "AgentTools",
+ "ApiAuth",
+ "AssistantMessage",
+ "AssistantMessagePath",
+ "AssistantMessageTime",
+ "AssistantMessageTokens",
+ "AssistantMessageTokensCache",
+ "Command",
+ "Config",
+ "ConfigAgent",
+ "ConfigCommand",
+ "ConfigCommandAdditionalProperty",
+ "ConfigExperimental",
+ "ConfigExperimentalHook",
+ "ConfigExperimentalHookFileEdited",
+ "ConfigExperimentalHookFileEditedAdditionalPropertyItem",
+ "ConfigExperimentalHookFileEditedAdditionalPropertyItemEnvironment",
+ "ConfigExperimentalHookSessionCompletedItem",
+ "ConfigExperimentalHookSessionCompletedItemEnvironment",
+ "ConfigFormatter",
+ "ConfigFormatterAdditionalProperty",
+ "ConfigFormatterAdditionalPropertyEnvironment",
+ "ConfigLsp",
+ "ConfigLspAdditionalPropertyType0",
+ "ConfigLspAdditionalPropertyType1",
+ "ConfigLspAdditionalPropertyType1Env",
+ "ConfigLspAdditionalPropertyType1Initialization",
+ "ConfigMcp",
+ "ConfigMode",
+ "ConfigPermission",
+ "ConfigPermissionBashType1",
+ "ConfigProvider",
+ "ConfigProviderAdditionalProperty",
+ "ConfigProviderAdditionalPropertyModels",
+ "ConfigProviderAdditionalPropertyModelsAdditionalProperty",
+ "ConfigProviderAdditionalPropertyModelsAdditionalPropertyCost",
+ "ConfigProviderAdditionalPropertyModelsAdditionalPropertyLimit",
+ "ConfigProviderAdditionalPropertyModelsAdditionalPropertyOptions",
+ "ConfigProviderAdditionalPropertyModelsAdditionalPropertyProvider",
+ "ConfigProviderAdditionalPropertyOptions",
+ "ConfigProvidersResponse200",
+ "ConfigProvidersResponse200Default",
+ "ConfigShare",
+ "ConfigTools",
+ "ConfigTui",
+ "ConfigWatcher",
+ "Error",
+ "ErrorData",
+ "EventFileEdited",
+ "EventFileEditedProperties",
+ "EventFileWatcherUpdated",
+ "EventFileWatcherUpdatedProperties",
+ "EventIdeInstalled",
+ "EventIdeInstalledProperties",
+ "EventInstallationUpdated",
+ "EventInstallationUpdatedProperties",
+ "EventLspClientDiagnostics",
+ "EventLspClientDiagnosticsProperties",
+ "EventMessagePartRemoved",
+ "EventMessagePartRemovedProperties",
+ "EventMessagePartUpdated",
+ "EventMessagePartUpdatedProperties",
+ "EventMessageRemoved",
+ "EventMessageRemovedProperties",
+ "EventMessageUpdated",
+ "EventMessageUpdatedProperties",
+ "EventPermissionReplied",
+ "EventPermissionRepliedProperties",
+ "EventPermissionUpdated",
+ "EventServerConnected",
+ "EventServerConnectedProperties",
+ "EventSessionCompacted",
+ "EventSessionCompactedProperties",
+ "EventSessionDeleted",
+ "EventSessionDeletedProperties",
+ "EventSessionError",
+ "EventSessionErrorProperties",
+ "EventSessionIdle",
+ "EventSessionIdleProperties",
+ "EventSessionUpdated",
+ "EventSessionUpdatedProperties",
+ "File",
+ "FileContent",
+ "FileContentPatch",
+ "FileContentPatchHunksItem",
+ "FileNode",
+ "FileNodeType",
+ "FilePart",
+ "FilePartInput",
+ "FilePartSourceText",
+ "FileSource",
+ "FileStatus",
+ "KeybindsConfig",
+ "LayoutConfig",
+ "McpLocalConfig",
+ "McpLocalConfigEnvironment",
+ "McpRemoteConfig",
+ "McpRemoteConfigHeaders",
+ "MessageAbortedError",
+ "MessageAbortedErrorData",
+ "MessageOutputLengthError",
+ "MessageOutputLengthErrorData",
+ "Model",
+ "ModelCost",
+ "ModelLimit",
+ "ModelOptions",
+ "ModelProvider",
+ "OAuth",
+ "PatchPart",
+ "Path",
+ "Permission",
+ "PermissionMetadata",
+ "PermissionTime",
+ "Project",
+ "ProjectTime",
+ "Provider",
+ "ProviderAuthError",
+ "ProviderAuthErrorData",
+ "ProviderModels",
+ "Range",
+ "RangeEnd",
+ "RangeStart",
+ "ReasoningPart",
+ "ReasoningPartMetadata",
+ "ReasoningPartTime",
+ "Session",
+ "SessionRevert",
+ "SessionShare",
+ "SessionTime",
+ "SnapshotPart",
+ "StepFinishPart",
+ "StepFinishPartTokens",
+ "StepFinishPartTokensCache",
+ "StepStartPart",
+ "Symbol",
+ "SymbolLocation",
+ "SymbolSource",
+ "TextPart",
+ "TextPartInput",
+ "TextPartInputTime",
+ "TextPartTime",
+ "ToolListItem",
+ "ToolPart",
+ "ToolStateCompleted",
+ "ToolStateCompletedInput",
+ "ToolStateCompletedMetadata",
+ "ToolStateCompletedTime",
+ "ToolStateError",
+ "ToolStateErrorInput",
+ "ToolStateErrorMetadata",
+ "ToolStateErrorTime",
+ "ToolStatePending",
+ "ToolStateRunning",
+ "ToolStateRunningMetadata",
+ "ToolStateRunningTime",
+ "UnknownError",
+ "UnknownErrorData",
+ "UserMessage",
+ "UserMessageTime",
+ "WellKnownAuth",
+)
diff --git a/packages/sdk/python/src/opencode_ai/models/agent.py b/packages/sdk/python/src/opencode_ai/models/agent.py
new file mode 100644
index 000000000..8044d73a0
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent.py
@@ -0,0 +1,180 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.agent_model import AgentModel
+ from ..models.agent_options import AgentOptions
+ from ..models.agent_permission import AgentPermission
+ from ..models.agent_tools import AgentTools
+
+
+T = TypeVar("T", bound="Agent")
+
+
+@_attrs_define
+class Agent:
+ """
+ Attributes:
+ name (str):
+ mode (Union[Literal['all'], Literal['primary'], Literal['subagent']]):
+ built_in (bool):
+ permission (AgentPermission):
+ tools (AgentTools):
+ options (AgentOptions):
+ description (Union[Unset, str]):
+ top_p (Union[Unset, float]):
+ temperature (Union[Unset, float]):
+ model (Union[Unset, AgentModel]):
+ prompt (Union[Unset, str]):
+ """
+
+ name: str
+ mode: Union[Literal["all"], Literal["primary"], Literal["subagent"]]
+ built_in: bool
+ permission: "AgentPermission"
+ tools: "AgentTools"
+ options: "AgentOptions"
+ description: Union[Unset, str] = UNSET
+ top_p: Union[Unset, float] = UNSET
+ temperature: Union[Unset, float] = UNSET
+ model: Union[Unset, "AgentModel"] = UNSET
+ prompt: Union[Unset, str] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ name = self.name
+
+ mode: Union[Literal["all"], Literal["primary"], Literal["subagent"]]
+ mode = self.mode
+
+ built_in = self.built_in
+
+ permission = self.permission.to_dict()
+
+ tools = self.tools.to_dict()
+
+ options = self.options.to_dict()
+
+ description = self.description
+
+ top_p = self.top_p
+
+ temperature = self.temperature
+
+ model: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.model, Unset):
+ model = self.model.to_dict()
+
+ prompt = self.prompt
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "name": name,
+ "mode": mode,
+ "builtIn": built_in,
+ "permission": permission,
+ "tools": tools,
+ "options": options,
+ }
+ )
+ if description is not UNSET:
+ field_dict["description"] = description
+ if top_p is not UNSET:
+ field_dict["topP"] = top_p
+ if temperature is not UNSET:
+ field_dict["temperature"] = temperature
+ if model is not UNSET:
+ field_dict["model"] = model
+ if prompt is not UNSET:
+ field_dict["prompt"] = prompt
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.agent_model import AgentModel
+ from ..models.agent_options import AgentOptions
+ from ..models.agent_permission import AgentPermission
+ from ..models.agent_tools import AgentTools
+
+ d = dict(src_dict)
+ name = d.pop("name")
+
+ def _parse_mode(data: object) -> Union[Literal["all"], Literal["primary"], Literal["subagent"]]:
+ mode_type_0 = cast(Literal["subagent"], data)
+ if mode_type_0 != "subagent":
+ raise ValueError(f"mode_type_0 must match const 'subagent', got '{mode_type_0}'")
+ return mode_type_0
+ mode_type_1 = cast(Literal["primary"], data)
+ if mode_type_1 != "primary":
+ raise ValueError(f"mode_type_1 must match const 'primary', got '{mode_type_1}'")
+ return mode_type_1
+ mode_type_2 = cast(Literal["all"], data)
+ if mode_type_2 != "all":
+ raise ValueError(f"mode_type_2 must match const 'all', got '{mode_type_2}'")
+ return mode_type_2
+
+ mode = _parse_mode(d.pop("mode"))
+
+ built_in = d.pop("builtIn")
+
+ permission = AgentPermission.from_dict(d.pop("permission"))
+
+ tools = AgentTools.from_dict(d.pop("tools"))
+
+ options = AgentOptions.from_dict(d.pop("options"))
+
+ description = d.pop("description", UNSET)
+
+ top_p = d.pop("topP", UNSET)
+
+ temperature = d.pop("temperature", UNSET)
+
+ _model = d.pop("model", UNSET)
+ model: Union[Unset, AgentModel]
+ if isinstance(_model, Unset):
+ model = UNSET
+ else:
+ model = AgentModel.from_dict(_model)
+
+ prompt = d.pop("prompt", UNSET)
+
+ agent = cls(
+ name=name,
+ mode=mode,
+ built_in=built_in,
+ permission=permission,
+ tools=tools,
+ options=options,
+ description=description,
+ top_p=top_p,
+ temperature=temperature,
+ model=model,
+ prompt=prompt,
+ )
+
+ agent.additional_properties = d
+ return agent
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_config.py b/packages/sdk/python/src/opencode_ai/models/agent_config.py
new file mode 100644
index 000000000..5c56c8b48
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_config.py
@@ -0,0 +1,173 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.agent_config_permission import AgentConfigPermission
+ from ..models.agent_config_tools import AgentConfigTools
+
+
+T = TypeVar("T", bound="AgentConfig")
+
+
+@_attrs_define
+class AgentConfig:
+ """
+ Attributes:
+ model (Union[Unset, str]):
+ temperature (Union[Unset, float]):
+ top_p (Union[Unset, float]):
+ prompt (Union[Unset, str]):
+ tools (Union[Unset, AgentConfigTools]):
+ disable (Union[Unset, bool]):
+ description (Union[Unset, str]): Description of when to use the agent
+ mode (Union[Literal['all'], Literal['primary'], Literal['subagent'], Unset]):
+ permission (Union[Unset, AgentConfigPermission]):
+ """
+
+ model: Union[Unset, str] = UNSET
+ temperature: Union[Unset, float] = UNSET
+ top_p: Union[Unset, float] = UNSET
+ prompt: Union[Unset, str] = UNSET
+ tools: Union[Unset, "AgentConfigTools"] = UNSET
+ disable: Union[Unset, bool] = UNSET
+ description: Union[Unset, str] = UNSET
+ mode: Union[Literal["all"], Literal["primary"], Literal["subagent"], Unset] = UNSET
+ permission: Union[Unset, "AgentConfigPermission"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ model = self.model
+
+ temperature = self.temperature
+
+ top_p = self.top_p
+
+ prompt = self.prompt
+
+ tools: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.tools, Unset):
+ tools = self.tools.to_dict()
+
+ disable = self.disable
+
+ description = self.description
+
+ mode: Union[Literal["all"], Literal["primary"], Literal["subagent"], Unset]
+ if isinstance(self.mode, Unset):
+ mode = UNSET
+ else:
+ mode = self.mode
+
+ permission: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.permission, Unset):
+ permission = self.permission.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if model is not UNSET:
+ field_dict["model"] = model
+ if temperature is not UNSET:
+ field_dict["temperature"] = temperature
+ if top_p is not UNSET:
+ field_dict["top_p"] = top_p
+ if prompt is not UNSET:
+ field_dict["prompt"] = prompt
+ if tools is not UNSET:
+ field_dict["tools"] = tools
+ if disable is not UNSET:
+ field_dict["disable"] = disable
+ if description is not UNSET:
+ field_dict["description"] = description
+ if mode is not UNSET:
+ field_dict["mode"] = mode
+ if permission is not UNSET:
+ field_dict["permission"] = permission
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.agent_config_permission import AgentConfigPermission
+ from ..models.agent_config_tools import AgentConfigTools
+
+ d = dict(src_dict)
+ model = d.pop("model", UNSET)
+
+ temperature = d.pop("temperature", UNSET)
+
+ top_p = d.pop("top_p", UNSET)
+
+ prompt = d.pop("prompt", UNSET)
+
+ _tools = d.pop("tools", UNSET)
+ tools: Union[Unset, AgentConfigTools]
+ if isinstance(_tools, Unset):
+ tools = UNSET
+ else:
+ tools = AgentConfigTools.from_dict(_tools)
+
+ disable = d.pop("disable", UNSET)
+
+ description = d.pop("description", UNSET)
+
+ def _parse_mode(data: object) -> Union[Literal["all"], Literal["primary"], Literal["subagent"], Unset]:
+ if isinstance(data, Unset):
+ return data
+ mode_type_0 = cast(Literal["subagent"], data)
+ if mode_type_0 != "subagent":
+ raise ValueError(f"mode_type_0 must match const 'subagent', got '{mode_type_0}'")
+ return mode_type_0
+ mode_type_1 = cast(Literal["primary"], data)
+ if mode_type_1 != "primary":
+ raise ValueError(f"mode_type_1 must match const 'primary', got '{mode_type_1}'")
+ return mode_type_1
+ mode_type_2 = cast(Literal["all"], data)
+ if mode_type_2 != "all":
+ raise ValueError(f"mode_type_2 must match const 'all', got '{mode_type_2}'")
+ return mode_type_2
+
+ mode = _parse_mode(d.pop("mode", UNSET))
+
+ _permission = d.pop("permission", UNSET)
+ permission: Union[Unset, AgentConfigPermission]
+ if isinstance(_permission, Unset):
+ permission = UNSET
+ else:
+ permission = AgentConfigPermission.from_dict(_permission)
+
+ agent_config = cls(
+ model=model,
+ temperature=temperature,
+ top_p=top_p,
+ prompt=prompt,
+ tools=tools,
+ disable=disable,
+ description=description,
+ mode=mode,
+ permission=permission,
+ )
+
+ agent_config.additional_properties = d
+ return agent_config
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_config_permission.py b/packages/sdk/python/src/opencode_ai/models/agent_config_permission.py
new file mode 100644
index 000000000..d7a499fbe
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_config_permission.py
@@ -0,0 +1,155 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.agent_config_permission_bash_type_1 import AgentConfigPermissionBashType1
+
+
+T = TypeVar("T", bound="AgentConfigPermission")
+
+
+@_attrs_define
+class AgentConfigPermission:
+ """
+ Attributes:
+ edit (Union[Literal['allow'], Literal['ask'], Literal['deny'], Unset]):
+ bash (Union['AgentConfigPermissionBashType1', Literal['allow'], Literal['ask'], Literal['deny'], Unset]):
+ webfetch (Union[Literal['allow'], Literal['ask'], Literal['deny'], Unset]):
+ """
+
+ edit: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset] = UNSET
+ bash: Union["AgentConfigPermissionBashType1", Literal["allow"], Literal["ask"], Literal["deny"], Unset] = UNSET
+ webfetch: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.agent_config_permission_bash_type_1 import AgentConfigPermissionBashType1
+
+ edit: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset]
+ if isinstance(self.edit, Unset):
+ edit = UNSET
+ else:
+ edit = self.edit
+
+ bash: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset, dict[str, Any]]
+ if isinstance(self.bash, Unset):
+ bash = UNSET
+ elif isinstance(self.bash, AgentConfigPermissionBashType1):
+ bash = self.bash.to_dict()
+ else:
+ bash = self.bash
+
+ webfetch: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset]
+ if isinstance(self.webfetch, Unset):
+ webfetch = UNSET
+ else:
+ webfetch = self.webfetch
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if edit is not UNSET:
+ field_dict["edit"] = edit
+ if bash is not UNSET:
+ field_dict["bash"] = bash
+ if webfetch is not UNSET:
+ field_dict["webfetch"] = webfetch
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.agent_config_permission_bash_type_1 import AgentConfigPermissionBashType1
+
+ d = dict(src_dict)
+
+ def _parse_edit(data: object) -> Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset]:
+ if isinstance(data, Unset):
+ return data
+ edit_type_0 = cast(Literal["ask"], data)
+ if edit_type_0 != "ask":
+ raise ValueError(f"edit_type_0 must match const 'ask', got '{edit_type_0}'")
+ return edit_type_0
+ edit_type_1 = cast(Literal["allow"], data)
+ if edit_type_1 != "allow":
+ raise ValueError(f"edit_type_1 must match const 'allow', got '{edit_type_1}'")
+ return edit_type_1
+ edit_type_2 = cast(Literal["deny"], data)
+ if edit_type_2 != "deny":
+ raise ValueError(f"edit_type_2 must match const 'deny', got '{edit_type_2}'")
+ return edit_type_2
+
+ edit = _parse_edit(d.pop("edit", UNSET))
+
+ def _parse_bash(
+ data: object,
+ ) -> Union["AgentConfigPermissionBashType1", Literal["allow"], Literal["ask"], Literal["deny"], Unset]:
+ if isinstance(data, Unset):
+ return data
+ bash_type_0_type_0 = cast(Literal["ask"], data)
+ if bash_type_0_type_0 != "ask":
+ raise ValueError(f"bash_type_0_type_0 must match const 'ask', got '{bash_type_0_type_0}'")
+ return bash_type_0_type_0
+ bash_type_0_type_1 = cast(Literal["allow"], data)
+ if bash_type_0_type_1 != "allow":
+ raise ValueError(f"bash_type_0_type_1 must match const 'allow', got '{bash_type_0_type_1}'")
+ return bash_type_0_type_1
+ bash_type_0_type_2 = cast(Literal["deny"], data)
+ if bash_type_0_type_2 != "deny":
+ raise ValueError(f"bash_type_0_type_2 must match const 'deny', got '{bash_type_0_type_2}'")
+ return bash_type_0_type_2
+ if not isinstance(data, dict):
+ raise TypeError()
+ bash_type_1 = AgentConfigPermissionBashType1.from_dict(data)
+
+ return bash_type_1
+
+ bash = _parse_bash(d.pop("bash", UNSET))
+
+ def _parse_webfetch(data: object) -> Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset]:
+ if isinstance(data, Unset):
+ return data
+ webfetch_type_0 = cast(Literal["ask"], data)
+ if webfetch_type_0 != "ask":
+ raise ValueError(f"webfetch_type_0 must match const 'ask', got '{webfetch_type_0}'")
+ return webfetch_type_0
+ webfetch_type_1 = cast(Literal["allow"], data)
+ if webfetch_type_1 != "allow":
+ raise ValueError(f"webfetch_type_1 must match const 'allow', got '{webfetch_type_1}'")
+ return webfetch_type_1
+ webfetch_type_2 = cast(Literal["deny"], data)
+ if webfetch_type_2 != "deny":
+ raise ValueError(f"webfetch_type_2 must match const 'deny', got '{webfetch_type_2}'")
+ return webfetch_type_2
+
+ webfetch = _parse_webfetch(d.pop("webfetch", UNSET))
+
+ agent_config_permission = cls(
+ edit=edit,
+ bash=bash,
+ webfetch=webfetch,
+ )
+
+ agent_config_permission.additional_properties = d
+ return agent_config_permission
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_config_permission_bash_type_1.py b/packages/sdk/python/src/opencode_ai/models/agent_config_permission_bash_type_1.py
new file mode 100644
index 000000000..a80581bec
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_config_permission_bash_type_1.py
@@ -0,0 +1,74 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="AgentConfigPermissionBashType1")
+
+
+@_attrs_define
+class AgentConfigPermissionBashType1:
+ """ """
+
+ additional_properties: dict[str, Union[Literal["allow"], Literal["ask"], Literal["deny"]]] = _attrs_field(
+ init=False, factory=dict
+ )
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = prop
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ agent_config_permission_bash_type_1 = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+
+ def _parse_additional_property(data: object) -> Union[Literal["allow"], Literal["ask"], Literal["deny"]]:
+ additional_property_type_0 = cast(Literal["ask"], data)
+ if additional_property_type_0 != "ask":
+ raise ValueError(
+ f"AdditionalProperty_type_0 must match const 'ask', got '{additional_property_type_0}'"
+ )
+ return additional_property_type_0
+ additional_property_type_1 = cast(Literal["allow"], data)
+ if additional_property_type_1 != "allow":
+ raise ValueError(
+ f"AdditionalProperty_type_1 must match const 'allow', got '{additional_property_type_1}'"
+ )
+ return additional_property_type_1
+ additional_property_type_2 = cast(Literal["deny"], data)
+ if additional_property_type_2 != "deny":
+ raise ValueError(
+ f"AdditionalProperty_type_2 must match const 'deny', got '{additional_property_type_2}'"
+ )
+ return additional_property_type_2
+
+ additional_property = _parse_additional_property(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ agent_config_permission_bash_type_1.additional_properties = additional_properties
+ return agent_config_permission_bash_type_1
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Union[Literal["allow"], Literal["ask"], Literal["deny"]]:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Union[Literal["allow"], Literal["ask"], Literal["deny"]]) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_config_tools.py b/packages/sdk/python/src/opencode_ai/models/agent_config_tools.py
new file mode 100644
index 000000000..beef8aef5
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_config_tools.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="AgentConfigTools")
+
+
+@_attrs_define
+class AgentConfigTools:
+ """ """
+
+ additional_properties: dict[str, bool] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ agent_config_tools = cls()
+
+ agent_config_tools.additional_properties = d
+ return agent_config_tools
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> bool:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: bool) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_model.py b/packages/sdk/python/src/opencode_ai/models/agent_model.py
new file mode 100644
index 000000000..2d98ee516
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_model.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="AgentModel")
+
+
+@_attrs_define
+class AgentModel:
+ """
+ Attributes:
+ model_id (str):
+ provider_id (str):
+ """
+
+ model_id: str
+ provider_id: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ model_id = self.model_id
+
+ provider_id = self.provider_id
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "modelID": model_id,
+ "providerID": provider_id,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ model_id = d.pop("modelID")
+
+ provider_id = d.pop("providerID")
+
+ agent_model = cls(
+ model_id=model_id,
+ provider_id=provider_id,
+ )
+
+ agent_model.additional_properties = d
+ return agent_model
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_options.py b/packages/sdk/python/src/opencode_ai/models/agent_options.py
new file mode 100644
index 000000000..f68165514
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_options.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="AgentOptions")
+
+
+@_attrs_define
+class AgentOptions:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ agent_options = cls()
+
+ agent_options.additional_properties = d
+ return agent_options
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_part.py b/packages/sdk/python/src/opencode_ai/models/agent_part.py
new file mode 100644
index 000000000..252e67070
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_part.py
@@ -0,0 +1,117 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.agent_part_source import AgentPartSource
+
+
+T = TypeVar("T", bound="AgentPart")
+
+
+@_attrs_define
+class AgentPart:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ message_id (str):
+ type_ (Literal['agent']):
+ name (str):
+ source (Union[Unset, AgentPartSource]):
+ """
+
+ id: str
+ session_id: str
+ message_id: str
+ type_: Literal["agent"]
+ name: str
+ source: Union[Unset, "AgentPartSource"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ type_ = self.type_
+
+ name = self.name
+
+ source: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.source, Unset):
+ source = self.source.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "messageID": message_id,
+ "type": type_,
+ "name": name,
+ }
+ )
+ if source is not UNSET:
+ field_dict["source"] = source
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.agent_part_source import AgentPartSource
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ type_ = cast(Literal["agent"], d.pop("type"))
+ if type_ != "agent":
+ raise ValueError(f"type must match const 'agent', got '{type_}'")
+
+ name = d.pop("name")
+
+ _source = d.pop("source", UNSET)
+ source: Union[Unset, AgentPartSource]
+ if isinstance(_source, Unset):
+ source = UNSET
+ else:
+ source = AgentPartSource.from_dict(_source)
+
+ agent_part = cls(
+ id=id,
+ session_id=session_id,
+ message_id=message_id,
+ type_=type_,
+ name=name,
+ source=source,
+ )
+
+ agent_part.additional_properties = d
+ return agent_part
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_part_input.py b/packages/sdk/python/src/opencode_ai/models/agent_part_input.py
new file mode 100644
index 000000000..e3ed1b7b7
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_part_input.py
@@ -0,0 +1,102 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.agent_part_input_source import AgentPartInputSource
+
+
+T = TypeVar("T", bound="AgentPartInput")
+
+
+@_attrs_define
+class AgentPartInput:
+ """
+ Attributes:
+ type_ (Literal['agent']):
+ name (str):
+ id (Union[Unset, str]):
+ source (Union[Unset, AgentPartInputSource]):
+ """
+
+ type_: Literal["agent"]
+ name: str
+ id: Union[Unset, str] = UNSET
+ source: Union[Unset, "AgentPartInputSource"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ name = self.name
+
+ id = self.id
+
+ source: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.source, Unset):
+ source = self.source.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "name": name,
+ }
+ )
+ if id is not UNSET:
+ field_dict["id"] = id
+ if source is not UNSET:
+ field_dict["source"] = source
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.agent_part_input_source import AgentPartInputSource
+
+ d = dict(src_dict)
+ type_ = cast(Literal["agent"], d.pop("type"))
+ if type_ != "agent":
+ raise ValueError(f"type must match const 'agent', got '{type_}'")
+
+ name = d.pop("name")
+
+ id = d.pop("id", UNSET)
+
+ _source = d.pop("source", UNSET)
+ source: Union[Unset, AgentPartInputSource]
+ if isinstance(_source, Unset):
+ source = UNSET
+ else:
+ source = AgentPartInputSource.from_dict(_source)
+
+ agent_part_input = cls(
+ type_=type_,
+ name=name,
+ id=id,
+ source=source,
+ )
+
+ agent_part_input.additional_properties = d
+ return agent_part_input
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_part_input_source.py b/packages/sdk/python/src/opencode_ai/models/agent_part_input_source.py
new file mode 100644
index 000000000..f49bb6aba
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_part_input_source.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="AgentPartInputSource")
+
+
+@_attrs_define
+class AgentPartInputSource:
+ """
+ Attributes:
+ value (str):
+ start (int):
+ end (int):
+ """
+
+ value: str
+ start: int
+ end: int
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ value = self.value
+
+ start = self.start
+
+ end = self.end
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "value": value,
+ "start": start,
+ "end": end,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ value = d.pop("value")
+
+ start = d.pop("start")
+
+ end = d.pop("end")
+
+ agent_part_input_source = cls(
+ value=value,
+ start=start,
+ end=end,
+ )
+
+ agent_part_input_source.additional_properties = d
+ return agent_part_input_source
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_part_source.py b/packages/sdk/python/src/opencode_ai/models/agent_part_source.py
new file mode 100644
index 000000000..fad27f861
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_part_source.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="AgentPartSource")
+
+
+@_attrs_define
+class AgentPartSource:
+ """
+ Attributes:
+ value (str):
+ start (int):
+ end (int):
+ """
+
+ value: str
+ start: int
+ end: int
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ value = self.value
+
+ start = self.start
+
+ end = self.end
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "value": value,
+ "start": start,
+ "end": end,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ value = d.pop("value")
+
+ start = d.pop("start")
+
+ end = d.pop("end")
+
+ agent_part_source = cls(
+ value=value,
+ start=start,
+ end=end,
+ )
+
+ agent_part_source.additional_properties = d
+ return agent_part_source
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_permission.py b/packages/sdk/python/src/opencode_ai/models/agent_permission.py
new file mode 100644
index 000000000..19e00c891
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_permission.py
@@ -0,0 +1,120 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.agent_permission_bash import AgentPermissionBash
+
+
+T = TypeVar("T", bound="AgentPermission")
+
+
+@_attrs_define
+class AgentPermission:
+ """
+ Attributes:
+ edit (Union[Literal['allow'], Literal['ask'], Literal['deny']]):
+ bash (AgentPermissionBash):
+ webfetch (Union[Literal['allow'], Literal['ask'], Literal['deny'], Unset]):
+ """
+
+ edit: Union[Literal["allow"], Literal["ask"], Literal["deny"]]
+ bash: "AgentPermissionBash"
+ webfetch: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ edit: Union[Literal["allow"], Literal["ask"], Literal["deny"]]
+ edit = self.edit
+
+ bash = self.bash.to_dict()
+
+ webfetch: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset]
+ if isinstance(self.webfetch, Unset):
+ webfetch = UNSET
+ else:
+ webfetch = self.webfetch
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "edit": edit,
+ "bash": bash,
+ }
+ )
+ if webfetch is not UNSET:
+ field_dict["webfetch"] = webfetch
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.agent_permission_bash import AgentPermissionBash
+
+ d = dict(src_dict)
+
+ def _parse_edit(data: object) -> Union[Literal["allow"], Literal["ask"], Literal["deny"]]:
+ edit_type_0 = cast(Literal["ask"], data)
+ if edit_type_0 != "ask":
+ raise ValueError(f"edit_type_0 must match const 'ask', got '{edit_type_0}'")
+ return edit_type_0
+ edit_type_1 = cast(Literal["allow"], data)
+ if edit_type_1 != "allow":
+ raise ValueError(f"edit_type_1 must match const 'allow', got '{edit_type_1}'")
+ return edit_type_1
+ edit_type_2 = cast(Literal["deny"], data)
+ if edit_type_2 != "deny":
+ raise ValueError(f"edit_type_2 must match const 'deny', got '{edit_type_2}'")
+ return edit_type_2
+
+ edit = _parse_edit(d.pop("edit"))
+
+ bash = AgentPermissionBash.from_dict(d.pop("bash"))
+
+ def _parse_webfetch(data: object) -> Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset]:
+ if isinstance(data, Unset):
+ return data
+ webfetch_type_0 = cast(Literal["ask"], data)
+ if webfetch_type_0 != "ask":
+ raise ValueError(f"webfetch_type_0 must match const 'ask', got '{webfetch_type_0}'")
+ return webfetch_type_0
+ webfetch_type_1 = cast(Literal["allow"], data)
+ if webfetch_type_1 != "allow":
+ raise ValueError(f"webfetch_type_1 must match const 'allow', got '{webfetch_type_1}'")
+ return webfetch_type_1
+ webfetch_type_2 = cast(Literal["deny"], data)
+ if webfetch_type_2 != "deny":
+ raise ValueError(f"webfetch_type_2 must match const 'deny', got '{webfetch_type_2}'")
+ return webfetch_type_2
+
+ webfetch = _parse_webfetch(d.pop("webfetch", UNSET))
+
+ agent_permission = cls(
+ edit=edit,
+ bash=bash,
+ webfetch=webfetch,
+ )
+
+ agent_permission.additional_properties = d
+ return agent_permission
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_permission_bash.py b/packages/sdk/python/src/opencode_ai/models/agent_permission_bash.py
new file mode 100644
index 000000000..ea03328f9
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_permission_bash.py
@@ -0,0 +1,74 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="AgentPermissionBash")
+
+
+@_attrs_define
+class AgentPermissionBash:
+ """ """
+
+ additional_properties: dict[str, Union[Literal["allow"], Literal["ask"], Literal["deny"]]] = _attrs_field(
+ init=False, factory=dict
+ )
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = prop
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ agent_permission_bash = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+
+ def _parse_additional_property(data: object) -> Union[Literal["allow"], Literal["ask"], Literal["deny"]]:
+ additional_property_type_0 = cast(Literal["ask"], data)
+ if additional_property_type_0 != "ask":
+ raise ValueError(
+ f"AdditionalProperty_type_0 must match const 'ask', got '{additional_property_type_0}'"
+ )
+ return additional_property_type_0
+ additional_property_type_1 = cast(Literal["allow"], data)
+ if additional_property_type_1 != "allow":
+ raise ValueError(
+ f"AdditionalProperty_type_1 must match const 'allow', got '{additional_property_type_1}'"
+ )
+ return additional_property_type_1
+ additional_property_type_2 = cast(Literal["deny"], data)
+ if additional_property_type_2 != "deny":
+ raise ValueError(
+ f"AdditionalProperty_type_2 must match const 'deny', got '{additional_property_type_2}'"
+ )
+ return additional_property_type_2
+
+ additional_property = _parse_additional_property(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ agent_permission_bash.additional_properties = additional_properties
+ return agent_permission_bash
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Union[Literal["allow"], Literal["ask"], Literal["deny"]]:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Union[Literal["allow"], Literal["ask"], Literal["deny"]]) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/agent_tools.py b/packages/sdk/python/src/opencode_ai/models/agent_tools.py
new file mode 100644
index 000000000..4f60bb9dd
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/agent_tools.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="AgentTools")
+
+
+@_attrs_define
+class AgentTools:
+ """ """
+
+ additional_properties: dict[str, bool] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ agent_tools = cls()
+
+ agent_tools.additional_properties = d
+ return agent_tools
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> bool:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: bool) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/api_auth.py b/packages/sdk/python/src/opencode_ai/models/api_auth.py
new file mode 100644
index 000000000..6cc3a3910
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/api_auth.py
@@ -0,0 +1,69 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ApiAuth")
+
+
+@_attrs_define
+class ApiAuth:
+ """
+ Attributes:
+ type_ (Literal['api']):
+ key (str):
+ """
+
+ type_: Literal["api"]
+ key: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ key = self.key
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "key": key,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ type_ = cast(Literal["api"], d.pop("type"))
+ if type_ != "api":
+ raise ValueError(f"type must match const 'api', got '{type_}'")
+
+ key = d.pop("key")
+
+ api_auth = cls(
+ type_=type_,
+ key=key,
+ )
+
+ api_auth.additional_properties = d
+ return api_auth
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/assistant_message.py b/packages/sdk/python/src/opencode_ai/models/assistant_message.py
new file mode 100644
index 000000000..88aa440e5
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/assistant_message.py
@@ -0,0 +1,228 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.assistant_message_path import AssistantMessagePath
+ from ..models.assistant_message_time import AssistantMessageTime
+ from ..models.assistant_message_tokens import AssistantMessageTokens
+ from ..models.message_aborted_error import MessageAbortedError
+ from ..models.message_output_length_error import MessageOutputLengthError
+ from ..models.provider_auth_error import ProviderAuthError
+ from ..models.unknown_error import UnknownError
+
+
+T = TypeVar("T", bound="AssistantMessage")
+
+
+@_attrs_define
+class AssistantMessage:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ role (Literal['assistant']):
+ time (AssistantMessageTime):
+ system (list[str]):
+ model_id (str):
+ provider_id (str):
+ mode (str):
+ path (AssistantMessagePath):
+ cost (float):
+ tokens (AssistantMessageTokens):
+ error (Union['MessageAbortedError', 'MessageOutputLengthError', 'ProviderAuthError', 'UnknownError', Unset]):
+ summary (Union[Unset, bool]):
+ """
+
+ id: str
+ session_id: str
+ role: Literal["assistant"]
+ time: "AssistantMessageTime"
+ system: list[str]
+ model_id: str
+ provider_id: str
+ mode: str
+ path: "AssistantMessagePath"
+ cost: float
+ tokens: "AssistantMessageTokens"
+ error: Union["MessageAbortedError", "MessageOutputLengthError", "ProviderAuthError", "UnknownError", Unset] = UNSET
+ summary: Union[Unset, bool] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.message_output_length_error import MessageOutputLengthError
+ from ..models.provider_auth_error import ProviderAuthError
+ from ..models.unknown_error import UnknownError
+
+ id = self.id
+
+ session_id = self.session_id
+
+ role = self.role
+
+ time = self.time.to_dict()
+
+ system = self.system
+
+ model_id = self.model_id
+
+ provider_id = self.provider_id
+
+ mode = self.mode
+
+ path = self.path.to_dict()
+
+ cost = self.cost
+
+ tokens = self.tokens.to_dict()
+
+ error: Union[Unset, dict[str, Any]]
+ if isinstance(self.error, Unset):
+ error = UNSET
+ elif isinstance(self.error, ProviderAuthError):
+ error = self.error.to_dict()
+ elif isinstance(self.error, UnknownError):
+ error = self.error.to_dict()
+ elif isinstance(self.error, MessageOutputLengthError):
+ error = self.error.to_dict()
+ else:
+ error = self.error.to_dict()
+
+ summary = self.summary
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "role": role,
+ "time": time,
+ "system": system,
+ "modelID": model_id,
+ "providerID": provider_id,
+ "mode": mode,
+ "path": path,
+ "cost": cost,
+ "tokens": tokens,
+ }
+ )
+ if error is not UNSET:
+ field_dict["error"] = error
+ if summary is not UNSET:
+ field_dict["summary"] = summary
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.assistant_message_path import AssistantMessagePath
+ from ..models.assistant_message_time import AssistantMessageTime
+ from ..models.assistant_message_tokens import AssistantMessageTokens
+ from ..models.message_aborted_error import MessageAbortedError
+ from ..models.message_output_length_error import MessageOutputLengthError
+ from ..models.provider_auth_error import ProviderAuthError
+ from ..models.unknown_error import UnknownError
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ role = cast(Literal["assistant"], d.pop("role"))
+ if role != "assistant":
+ raise ValueError(f"role must match const 'assistant', got '{role}'")
+
+ time = AssistantMessageTime.from_dict(d.pop("time"))
+
+ system = cast(list[str], d.pop("system"))
+
+ model_id = d.pop("modelID")
+
+ provider_id = d.pop("providerID")
+
+ mode = d.pop("mode")
+
+ path = AssistantMessagePath.from_dict(d.pop("path"))
+
+ cost = d.pop("cost")
+
+ tokens = AssistantMessageTokens.from_dict(d.pop("tokens"))
+
+ def _parse_error(
+ data: object,
+ ) -> Union["MessageAbortedError", "MessageOutputLengthError", "ProviderAuthError", "UnknownError", Unset]:
+ if isinstance(data, Unset):
+ return data
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ error_type_0 = ProviderAuthError.from_dict(data)
+
+ return error_type_0
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ error_type_1 = UnknownError.from_dict(data)
+
+ return error_type_1
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ error_type_2 = MessageOutputLengthError.from_dict(data)
+
+ return error_type_2
+ except: # noqa: E722
+ pass
+ if not isinstance(data, dict):
+ raise TypeError()
+ error_type_3 = MessageAbortedError.from_dict(data)
+
+ return error_type_3
+
+ error = _parse_error(d.pop("error", UNSET))
+
+ summary = d.pop("summary", UNSET)
+
+ assistant_message = cls(
+ id=id,
+ session_id=session_id,
+ role=role,
+ time=time,
+ system=system,
+ model_id=model_id,
+ provider_id=provider_id,
+ mode=mode,
+ path=path,
+ cost=cost,
+ tokens=tokens,
+ error=error,
+ summary=summary,
+ )
+
+ assistant_message.additional_properties = d
+ return assistant_message
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/assistant_message_path.py b/packages/sdk/python/src/opencode_ai/models/assistant_message_path.py
new file mode 100644
index 000000000..0781b5b1e
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/assistant_message_path.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="AssistantMessagePath")
+
+
+@_attrs_define
+class AssistantMessagePath:
+ """
+ Attributes:
+ cwd (str):
+ root (str):
+ """
+
+ cwd: str
+ root: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ cwd = self.cwd
+
+ root = self.root
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "cwd": cwd,
+ "root": root,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ cwd = d.pop("cwd")
+
+ root = d.pop("root")
+
+ assistant_message_path = cls(
+ cwd=cwd,
+ root=root,
+ )
+
+ assistant_message_path.additional_properties = d
+ return assistant_message_path
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/assistant_message_time.py b/packages/sdk/python/src/opencode_ai/models/assistant_message_time.py
new file mode 100644
index 000000000..64aac074e
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/assistant_message_time.py
@@ -0,0 +1,70 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="AssistantMessageTime")
+
+
+@_attrs_define
+class AssistantMessageTime:
+ """
+ Attributes:
+ created (float):
+ completed (Union[Unset, float]):
+ """
+
+ created: float
+ completed: Union[Unset, float] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ created = self.created
+
+ completed = self.completed
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "created": created,
+ }
+ )
+ if completed is not UNSET:
+ field_dict["completed"] = completed
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ created = d.pop("created")
+
+ completed = d.pop("completed", UNSET)
+
+ assistant_message_time = cls(
+ created=created,
+ completed=completed,
+ )
+
+ assistant_message_time.additional_properties = d
+ return assistant_message_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/assistant_message_tokens.py b/packages/sdk/python/src/opencode_ai/models/assistant_message_tokens.py
new file mode 100644
index 000000000..6e7bc4e8b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/assistant_message_tokens.py
@@ -0,0 +1,89 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.assistant_message_tokens_cache import AssistantMessageTokensCache
+
+
+T = TypeVar("T", bound="AssistantMessageTokens")
+
+
+@_attrs_define
+class AssistantMessageTokens:
+ """
+ Attributes:
+ input_ (float):
+ output (float):
+ reasoning (float):
+ cache (AssistantMessageTokensCache):
+ """
+
+ input_: float
+ output: float
+ reasoning: float
+ cache: "AssistantMessageTokensCache"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ input_ = self.input_
+
+ output = self.output
+
+ reasoning = self.reasoning
+
+ cache = self.cache.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "input": input_,
+ "output": output,
+ "reasoning": reasoning,
+ "cache": cache,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.assistant_message_tokens_cache import AssistantMessageTokensCache
+
+ d = dict(src_dict)
+ input_ = d.pop("input")
+
+ output = d.pop("output")
+
+ reasoning = d.pop("reasoning")
+
+ cache = AssistantMessageTokensCache.from_dict(d.pop("cache"))
+
+ assistant_message_tokens = cls(
+ input_=input_,
+ output=output,
+ reasoning=reasoning,
+ cache=cache,
+ )
+
+ assistant_message_tokens.additional_properties = d
+ return assistant_message_tokens
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/assistant_message_tokens_cache.py b/packages/sdk/python/src/opencode_ai/models/assistant_message_tokens_cache.py
new file mode 100644
index 000000000..6d631fea0
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/assistant_message_tokens_cache.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="AssistantMessageTokensCache")
+
+
+@_attrs_define
+class AssistantMessageTokensCache:
+ """
+ Attributes:
+ read (float):
+ write (float):
+ """
+
+ read: float
+ write: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ read = self.read
+
+ write = self.write
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "read": read,
+ "write": write,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ read = d.pop("read")
+
+ write = d.pop("write")
+
+ assistant_message_tokens_cache = cls(
+ read=read,
+ write=write,
+ )
+
+ assistant_message_tokens_cache.additional_properties = d
+ return assistant_message_tokens_cache
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/command.py b/packages/sdk/python/src/opencode_ai/models/command.py
new file mode 100644
index 000000000..a6abf3d2f
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/command.py
@@ -0,0 +1,105 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="Command")
+
+
+@_attrs_define
+class Command:
+ """
+ Attributes:
+ name (str):
+ template (str):
+ description (Union[Unset, str]):
+ agent (Union[Unset, str]):
+ model (Union[Unset, str]):
+ subtask (Union[Unset, bool]):
+ """
+
+ name: str
+ template: str
+ description: Union[Unset, str] = UNSET
+ agent: Union[Unset, str] = UNSET
+ model: Union[Unset, str] = UNSET
+ subtask: Union[Unset, bool] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ name = self.name
+
+ template = self.template
+
+ description = self.description
+
+ agent = self.agent
+
+ model = self.model
+
+ subtask = self.subtask
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "name": name,
+ "template": template,
+ }
+ )
+ if description is not UNSET:
+ field_dict["description"] = description
+ if agent is not UNSET:
+ field_dict["agent"] = agent
+ if model is not UNSET:
+ field_dict["model"] = model
+ if subtask is not UNSET:
+ field_dict["subtask"] = subtask
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ name = d.pop("name")
+
+ template = d.pop("template")
+
+ description = d.pop("description", UNSET)
+
+ agent = d.pop("agent", UNSET)
+
+ model = d.pop("model", UNSET)
+
+ subtask = d.pop("subtask", UNSET)
+
+ command = cls(
+ name=name,
+ template=template,
+ description=description,
+ agent=agent,
+ model=model,
+ subtask=subtask,
+ )
+
+ command.additional_properties = d
+ return command
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config.py b/packages/sdk/python/src/opencode_ai/models/config.py
new file mode 100644
index 000000000..38b97637e
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config.py
@@ -0,0 +1,411 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+
+from ..models.config_share import ConfigShare
+from ..models.layout_config import LayoutConfig
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.config_agent import ConfigAgent
+ from ..models.config_command import ConfigCommand
+ from ..models.config_experimental import ConfigExperimental
+ from ..models.config_formatter import ConfigFormatter
+ from ..models.config_lsp import ConfigLsp
+ from ..models.config_mcp import ConfigMcp
+ from ..models.config_mode import ConfigMode
+ from ..models.config_permission import ConfigPermission
+ from ..models.config_provider import ConfigProvider
+ from ..models.config_tools import ConfigTools
+ from ..models.config_tui import ConfigTui
+ from ..models.config_watcher import ConfigWatcher
+ from ..models.keybinds_config import KeybindsConfig
+
+
+T = TypeVar("T", bound="Config")
+
+
+@_attrs_define
+class Config:
+ """
+ Attributes:
+ schema (Union[Unset, str]): JSON schema reference for configuration validation
+ theme (Union[Unset, str]): Theme name to use for the interface
+ keybinds (Union[Unset, KeybindsConfig]): Custom keybind configurations
+ tui (Union[Unset, ConfigTui]): TUI specific settings
+ command (Union[Unset, ConfigCommand]): Command configuration, see https://opencode.ai/docs/commands
+ watcher (Union[Unset, ConfigWatcher]):
+ plugin (Union[Unset, list[str]]):
+ snapshot (Union[Unset, bool]):
+ share (Union[Unset, ConfigShare]): Control sharing behavior:'manual' allows manual sharing via commands, 'auto'
+ enables automatic sharing, 'disabled' disables all sharing
+ autoshare (Union[Unset, bool]): @deprecated Use 'share' field instead. Share newly created sessions
+ automatically
+ autoupdate (Union[Unset, bool]): Automatically update to the latest version
+ disabled_providers (Union[Unset, list[str]]): Disable providers that are loaded automatically
+ model (Union[Unset, str]): Model to use in the format of provider/model, eg anthropic/claude-2
+ small_model (Union[Unset, str]): Small model to use for tasks like title generation in the format of
+ provider/model
+ username (Union[Unset, str]): Custom username to display in conversations instead of system username
+ mode (Union[Unset, ConfigMode]): @deprecated Use `agent` field instead.
+ agent (Union[Unset, ConfigAgent]): Agent configuration, see https://opencode.ai/docs/agent
+ provider (Union[Unset, ConfigProvider]): Custom provider configurations and model overrides
+ mcp (Union[Unset, ConfigMcp]): MCP (Model Context Protocol) server configurations
+ formatter (Union[Unset, ConfigFormatter]):
+ lsp (Union[Unset, ConfigLsp]):
+ instructions (Union[Unset, list[str]]): Additional instruction files or patterns to include
+ layout (Union[Unset, LayoutConfig]): @deprecated Always uses stretch layout.
+ permission (Union[Unset, ConfigPermission]):
+ tools (Union[Unset, ConfigTools]):
+ experimental (Union[Unset, ConfigExperimental]):
+ """
+
+ schema: Union[Unset, str] = UNSET
+ theme: Union[Unset, str] = UNSET
+ keybinds: Union[Unset, "KeybindsConfig"] = UNSET
+ tui: Union[Unset, "ConfigTui"] = UNSET
+ command: Union[Unset, "ConfigCommand"] = UNSET
+ watcher: Union[Unset, "ConfigWatcher"] = UNSET
+ plugin: Union[Unset, list[str]] = UNSET
+ snapshot: Union[Unset, bool] = UNSET
+ share: Union[Unset, ConfigShare] = UNSET
+ autoshare: Union[Unset, bool] = UNSET
+ autoupdate: Union[Unset, bool] = UNSET
+ disabled_providers: Union[Unset, list[str]] = UNSET
+ model: Union[Unset, str] = UNSET
+ small_model: Union[Unset, str] = UNSET
+ username: Union[Unset, str] = UNSET
+ mode: Union[Unset, "ConfigMode"] = UNSET
+ agent: Union[Unset, "ConfigAgent"] = UNSET
+ provider: Union[Unset, "ConfigProvider"] = UNSET
+ mcp: Union[Unset, "ConfigMcp"] = UNSET
+ formatter: Union[Unset, "ConfigFormatter"] = UNSET
+ lsp: Union[Unset, "ConfigLsp"] = UNSET
+ instructions: Union[Unset, list[str]] = UNSET
+ layout: Union[Unset, LayoutConfig] = UNSET
+ permission: Union[Unset, "ConfigPermission"] = UNSET
+ tools: Union[Unset, "ConfigTools"] = UNSET
+ experimental: Union[Unset, "ConfigExperimental"] = UNSET
+
+ def to_dict(self) -> dict[str, Any]:
+ schema = self.schema
+
+ theme = self.theme
+
+ keybinds: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.keybinds, Unset):
+ keybinds = self.keybinds.to_dict()
+
+ tui: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.tui, Unset):
+ tui = self.tui.to_dict()
+
+ command: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.command, Unset):
+ command = self.command.to_dict()
+
+ watcher: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.watcher, Unset):
+ watcher = self.watcher.to_dict()
+
+ plugin: Union[Unset, list[str]] = UNSET
+ if not isinstance(self.plugin, Unset):
+ plugin = self.plugin
+
+ snapshot = self.snapshot
+
+ share: Union[Unset, str] = UNSET
+ if not isinstance(self.share, Unset):
+ share = self.share.value
+
+ autoshare = self.autoshare
+
+ autoupdate = self.autoupdate
+
+ disabled_providers: Union[Unset, list[str]] = UNSET
+ if not isinstance(self.disabled_providers, Unset):
+ disabled_providers = self.disabled_providers
+
+ model = self.model
+
+ small_model = self.small_model
+
+ username = self.username
+
+ mode: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.mode, Unset):
+ mode = self.mode.to_dict()
+
+ agent: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.agent, Unset):
+ agent = self.agent.to_dict()
+
+ provider: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.provider, Unset):
+ provider = self.provider.to_dict()
+
+ mcp: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.mcp, Unset):
+ mcp = self.mcp.to_dict()
+
+ formatter: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.formatter, Unset):
+ formatter = self.formatter.to_dict()
+
+ lsp: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.lsp, Unset):
+ lsp = self.lsp.to_dict()
+
+ instructions: Union[Unset, list[str]] = UNSET
+ if not isinstance(self.instructions, Unset):
+ instructions = self.instructions
+
+ layout: Union[Unset, str] = UNSET
+ if not isinstance(self.layout, Unset):
+ layout = self.layout.value
+
+ permission: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.permission, Unset):
+ permission = self.permission.to_dict()
+
+ tools: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.tools, Unset):
+ tools = self.tools.to_dict()
+
+ experimental: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.experimental, Unset):
+ experimental = self.experimental.to_dict()
+
+ field_dict: dict[str, Any] = {}
+
+ field_dict.update({})
+ if schema is not UNSET:
+ field_dict["$schema"] = schema
+ if theme is not UNSET:
+ field_dict["theme"] = theme
+ if keybinds is not UNSET:
+ field_dict["keybinds"] = keybinds
+ if tui is not UNSET:
+ field_dict["tui"] = tui
+ if command is not UNSET:
+ field_dict["command"] = command
+ if watcher is not UNSET:
+ field_dict["watcher"] = watcher
+ if plugin is not UNSET:
+ field_dict["plugin"] = plugin
+ if snapshot is not UNSET:
+ field_dict["snapshot"] = snapshot
+ if share is not UNSET:
+ field_dict["share"] = share
+ if autoshare is not UNSET:
+ field_dict["autoshare"] = autoshare
+ if autoupdate is not UNSET:
+ field_dict["autoupdate"] = autoupdate
+ if disabled_providers is not UNSET:
+ field_dict["disabled_providers"] = disabled_providers
+ if model is not UNSET:
+ field_dict["model"] = model
+ if small_model is not UNSET:
+ field_dict["small_model"] = small_model
+ if username is not UNSET:
+ field_dict["username"] = username
+ if mode is not UNSET:
+ field_dict["mode"] = mode
+ if agent is not UNSET:
+ field_dict["agent"] = agent
+ if provider is not UNSET:
+ field_dict["provider"] = provider
+ if mcp is not UNSET:
+ field_dict["mcp"] = mcp
+ if formatter is not UNSET:
+ field_dict["formatter"] = formatter
+ if lsp is not UNSET:
+ field_dict["lsp"] = lsp
+ if instructions is not UNSET:
+ field_dict["instructions"] = instructions
+ if layout is not UNSET:
+ field_dict["layout"] = layout
+ if permission is not UNSET:
+ field_dict["permission"] = permission
+ if tools is not UNSET:
+ field_dict["tools"] = tools
+ if experimental is not UNSET:
+ field_dict["experimental"] = experimental
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_agent import ConfigAgent
+ from ..models.config_command import ConfigCommand
+ from ..models.config_experimental import ConfigExperimental
+ from ..models.config_formatter import ConfigFormatter
+ from ..models.config_lsp import ConfigLsp
+ from ..models.config_mcp import ConfigMcp
+ from ..models.config_mode import ConfigMode
+ from ..models.config_permission import ConfigPermission
+ from ..models.config_provider import ConfigProvider
+ from ..models.config_tools import ConfigTools
+ from ..models.config_tui import ConfigTui
+ from ..models.config_watcher import ConfigWatcher
+ from ..models.keybinds_config import KeybindsConfig
+
+ d = dict(src_dict)
+ schema = d.pop("$schema", UNSET)
+
+ theme = d.pop("theme", UNSET)
+
+ _keybinds = d.pop("keybinds", UNSET)
+ keybinds: Union[Unset, KeybindsConfig]
+ if isinstance(_keybinds, Unset):
+ keybinds = UNSET
+ else:
+ keybinds = KeybindsConfig.from_dict(_keybinds)
+
+ _tui = d.pop("tui", UNSET)
+ tui: Union[Unset, ConfigTui]
+ if isinstance(_tui, Unset):
+ tui = UNSET
+ else:
+ tui = ConfigTui.from_dict(_tui)
+
+ _command = d.pop("command", UNSET)
+ command: Union[Unset, ConfigCommand]
+ if isinstance(_command, Unset):
+ command = UNSET
+ else:
+ command = ConfigCommand.from_dict(_command)
+
+ _watcher = d.pop("watcher", UNSET)
+ watcher: Union[Unset, ConfigWatcher]
+ if isinstance(_watcher, Unset):
+ watcher = UNSET
+ else:
+ watcher = ConfigWatcher.from_dict(_watcher)
+
+ plugin = cast(list[str], d.pop("plugin", UNSET))
+
+ snapshot = d.pop("snapshot", UNSET)
+
+ _share = d.pop("share", UNSET)
+ share: Union[Unset, ConfigShare]
+ if isinstance(_share, Unset):
+ share = UNSET
+ else:
+ share = ConfigShare(_share)
+
+ autoshare = d.pop("autoshare", UNSET)
+
+ autoupdate = d.pop("autoupdate", UNSET)
+
+ disabled_providers = cast(list[str], d.pop("disabled_providers", UNSET))
+
+ model = d.pop("model", UNSET)
+
+ small_model = d.pop("small_model", UNSET)
+
+ username = d.pop("username", UNSET)
+
+ _mode = d.pop("mode", UNSET)
+ mode: Union[Unset, ConfigMode]
+ if isinstance(_mode, Unset):
+ mode = UNSET
+ else:
+ mode = ConfigMode.from_dict(_mode)
+
+ _agent = d.pop("agent", UNSET)
+ agent: Union[Unset, ConfigAgent]
+ if isinstance(_agent, Unset):
+ agent = UNSET
+ else:
+ agent = ConfigAgent.from_dict(_agent)
+
+ _provider = d.pop("provider", UNSET)
+ provider: Union[Unset, ConfigProvider]
+ if isinstance(_provider, Unset):
+ provider = UNSET
+ else:
+ provider = ConfigProvider.from_dict(_provider)
+
+ _mcp = d.pop("mcp", UNSET)
+ mcp: Union[Unset, ConfigMcp]
+ if isinstance(_mcp, Unset):
+ mcp = UNSET
+ else:
+ mcp = ConfigMcp.from_dict(_mcp)
+
+ _formatter = d.pop("formatter", UNSET)
+ formatter: Union[Unset, ConfigFormatter]
+ if isinstance(_formatter, Unset):
+ formatter = UNSET
+ else:
+ formatter = ConfigFormatter.from_dict(_formatter)
+
+ _lsp = d.pop("lsp", UNSET)
+ lsp: Union[Unset, ConfigLsp]
+ if isinstance(_lsp, Unset):
+ lsp = UNSET
+ else:
+ lsp = ConfigLsp.from_dict(_lsp)
+
+ instructions = cast(list[str], d.pop("instructions", UNSET))
+
+ _layout = d.pop("layout", UNSET)
+ layout: Union[Unset, LayoutConfig]
+ if isinstance(_layout, Unset):
+ layout = UNSET
+ else:
+ layout = LayoutConfig(_layout)
+
+ _permission = d.pop("permission", UNSET)
+ permission: Union[Unset, ConfigPermission]
+ if isinstance(_permission, Unset):
+ permission = UNSET
+ else:
+ permission = ConfigPermission.from_dict(_permission)
+
+ _tools = d.pop("tools", UNSET)
+ tools: Union[Unset, ConfigTools]
+ if isinstance(_tools, Unset):
+ tools = UNSET
+ else:
+ tools = ConfigTools.from_dict(_tools)
+
+ _experimental = d.pop("experimental", UNSET)
+ experimental: Union[Unset, ConfigExperimental]
+ if isinstance(_experimental, Unset):
+ experimental = UNSET
+ else:
+ experimental = ConfigExperimental.from_dict(_experimental)
+
+ config = cls(
+ schema=schema,
+ theme=theme,
+ keybinds=keybinds,
+ tui=tui,
+ command=command,
+ watcher=watcher,
+ plugin=plugin,
+ snapshot=snapshot,
+ share=share,
+ autoshare=autoshare,
+ autoupdate=autoupdate,
+ disabled_providers=disabled_providers,
+ model=model,
+ small_model=small_model,
+ username=username,
+ mode=mode,
+ agent=agent,
+ provider=provider,
+ mcp=mcp,
+ formatter=formatter,
+ lsp=lsp,
+ instructions=instructions,
+ layout=layout,
+ permission=permission,
+ tools=tools,
+ experimental=experimental,
+ )
+
+ return config
diff --git a/packages/sdk/python/src/opencode_ai/models/config_agent.py b/packages/sdk/python/src/opencode_ai/models/config_agent.py
new file mode 100644
index 000000000..c69897a5b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_agent.py
@@ -0,0 +1,113 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.agent_config import AgentConfig
+
+
+T = TypeVar("T", bound="ConfigAgent")
+
+
+@_attrs_define
+class ConfigAgent:
+ """Agent configuration, see https://opencode.ai/docs/agent
+
+ Attributes:
+ plan (Union[Unset, AgentConfig]):
+ build (Union[Unset, AgentConfig]):
+ general (Union[Unset, AgentConfig]):
+ """
+
+ plan: Union[Unset, "AgentConfig"] = UNSET
+ build: Union[Unset, "AgentConfig"] = UNSET
+ general: Union[Unset, "AgentConfig"] = UNSET
+ additional_properties: dict[str, "AgentConfig"] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ plan: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.plan, Unset):
+ plan = self.plan.to_dict()
+
+ build: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.build, Unset):
+ build = self.build.to_dict()
+
+ general: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.general, Unset):
+ general = self.general.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = prop.to_dict()
+
+ field_dict.update({})
+ if plan is not UNSET:
+ field_dict["plan"] = plan
+ if build is not UNSET:
+ field_dict["build"] = build
+ if general is not UNSET:
+ field_dict["general"] = general
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.agent_config import AgentConfig
+
+ d = dict(src_dict)
+ _plan = d.pop("plan", UNSET)
+ plan: Union[Unset, AgentConfig]
+ if isinstance(_plan, Unset):
+ plan = UNSET
+ else:
+ plan = AgentConfig.from_dict(_plan)
+
+ _build = d.pop("build", UNSET)
+ build: Union[Unset, AgentConfig]
+ if isinstance(_build, Unset):
+ build = UNSET
+ else:
+ build = AgentConfig.from_dict(_build)
+
+ _general = d.pop("general", UNSET)
+ general: Union[Unset, AgentConfig]
+ if isinstance(_general, Unset):
+ general = UNSET
+ else:
+ general = AgentConfig.from_dict(_general)
+
+ config_agent = cls(
+ plan=plan,
+ build=build,
+ general=general,
+ )
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+ additional_property = AgentConfig.from_dict(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ config_agent.additional_properties = additional_properties
+ return config_agent
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> "AgentConfig":
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: "AgentConfig") -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_command.py b/packages/sdk/python/src/opencode_ai/models/config_command.py
new file mode 100644
index 000000000..908f5f44c
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_command.py
@@ -0,0 +1,57 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.config_command_additional_property import ConfigCommandAdditionalProperty
+
+
+T = TypeVar("T", bound="ConfigCommand")
+
+
+@_attrs_define
+class ConfigCommand:
+ """Command configuration, see https://opencode.ai/docs/commands"""
+
+ additional_properties: dict[str, "ConfigCommandAdditionalProperty"] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = prop.to_dict()
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_command_additional_property import ConfigCommandAdditionalProperty
+
+ d = dict(src_dict)
+ config_command = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+ additional_property = ConfigCommandAdditionalProperty.from_dict(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ config_command.additional_properties = additional_properties
+ return config_command
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> "ConfigCommandAdditionalProperty":
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: "ConfigCommandAdditionalProperty") -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_command_additional_property.py b/packages/sdk/python/src/opencode_ai/models/config_command_additional_property.py
new file mode 100644
index 000000000..64c39db18
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_command_additional_property.py
@@ -0,0 +1,97 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="ConfigCommandAdditionalProperty")
+
+
+@_attrs_define
+class ConfigCommandAdditionalProperty:
+ """
+ Attributes:
+ template (str):
+ description (Union[Unset, str]):
+ agent (Union[Unset, str]):
+ model (Union[Unset, str]):
+ subtask (Union[Unset, bool]):
+ """
+
+ template: str
+ description: Union[Unset, str] = UNSET
+ agent: Union[Unset, str] = UNSET
+ model: Union[Unset, str] = UNSET
+ subtask: Union[Unset, bool] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ template = self.template
+
+ description = self.description
+
+ agent = self.agent
+
+ model = self.model
+
+ subtask = self.subtask
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "template": template,
+ }
+ )
+ if description is not UNSET:
+ field_dict["description"] = description
+ if agent is not UNSET:
+ field_dict["agent"] = agent
+ if model is not UNSET:
+ field_dict["model"] = model
+ if subtask is not UNSET:
+ field_dict["subtask"] = subtask
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ template = d.pop("template")
+
+ description = d.pop("description", UNSET)
+
+ agent = d.pop("agent", UNSET)
+
+ model = d.pop("model", UNSET)
+
+ subtask = d.pop("subtask", UNSET)
+
+ config_command_additional_property = cls(
+ template=template,
+ description=description,
+ agent=agent,
+ model=model,
+ subtask=subtask,
+ )
+
+ config_command_additional_property.additional_properties = d
+ return config_command_additional_property
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_experimental.py b/packages/sdk/python/src/opencode_ai/models/config_experimental.py
new file mode 100644
index 000000000..f67c0422a
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_experimental.py
@@ -0,0 +1,81 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.config_experimental_hook import ConfigExperimentalHook
+
+
+T = TypeVar("T", bound="ConfigExperimental")
+
+
+@_attrs_define
+class ConfigExperimental:
+ """
+ Attributes:
+ hook (Union[Unset, ConfigExperimentalHook]):
+ disable_paste_summary (Union[Unset, bool]):
+ """
+
+ hook: Union[Unset, "ConfigExperimentalHook"] = UNSET
+ disable_paste_summary: Union[Unset, bool] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ hook: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.hook, Unset):
+ hook = self.hook.to_dict()
+
+ disable_paste_summary = self.disable_paste_summary
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if hook is not UNSET:
+ field_dict["hook"] = hook
+ if disable_paste_summary is not UNSET:
+ field_dict["disable_paste_summary"] = disable_paste_summary
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_experimental_hook import ConfigExperimentalHook
+
+ d = dict(src_dict)
+ _hook = d.pop("hook", UNSET)
+ hook: Union[Unset, ConfigExperimentalHook]
+ if isinstance(_hook, Unset):
+ hook = UNSET
+ else:
+ hook = ConfigExperimentalHook.from_dict(_hook)
+
+ disable_paste_summary = d.pop("disable_paste_summary", UNSET)
+
+ config_experimental = cls(
+ hook=hook,
+ disable_paste_summary=disable_paste_summary,
+ )
+
+ config_experimental.additional_properties = d
+ return config_experimental
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_experimental_hook.py b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook.py
new file mode 100644
index 000000000..014e97a0a
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook.py
@@ -0,0 +1,93 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.config_experimental_hook_file_edited import ConfigExperimentalHookFileEdited
+ from ..models.config_experimental_hook_session_completed_item import ConfigExperimentalHookSessionCompletedItem
+
+
+T = TypeVar("T", bound="ConfigExperimentalHook")
+
+
+@_attrs_define
+class ConfigExperimentalHook:
+ """
+ Attributes:
+ file_edited (Union[Unset, ConfigExperimentalHookFileEdited]):
+ session_completed (Union[Unset, list['ConfigExperimentalHookSessionCompletedItem']]):
+ """
+
+ file_edited: Union[Unset, "ConfigExperimentalHookFileEdited"] = UNSET
+ session_completed: Union[Unset, list["ConfigExperimentalHookSessionCompletedItem"]] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ file_edited: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.file_edited, Unset):
+ file_edited = self.file_edited.to_dict()
+
+ session_completed: Union[Unset, list[dict[str, Any]]] = UNSET
+ if not isinstance(self.session_completed, Unset):
+ session_completed = []
+ for session_completed_item_data in self.session_completed:
+ session_completed_item = session_completed_item_data.to_dict()
+ session_completed.append(session_completed_item)
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if file_edited is not UNSET:
+ field_dict["file_edited"] = file_edited
+ if session_completed is not UNSET:
+ field_dict["session_completed"] = session_completed
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_experimental_hook_file_edited import ConfigExperimentalHookFileEdited
+ from ..models.config_experimental_hook_session_completed_item import ConfigExperimentalHookSessionCompletedItem
+
+ d = dict(src_dict)
+ _file_edited = d.pop("file_edited", UNSET)
+ file_edited: Union[Unset, ConfigExperimentalHookFileEdited]
+ if isinstance(_file_edited, Unset):
+ file_edited = UNSET
+ else:
+ file_edited = ConfigExperimentalHookFileEdited.from_dict(_file_edited)
+
+ session_completed = []
+ _session_completed = d.pop("session_completed", UNSET)
+ for session_completed_item_data in _session_completed or []:
+ session_completed_item = ConfigExperimentalHookSessionCompletedItem.from_dict(session_completed_item_data)
+
+ session_completed.append(session_completed_item)
+
+ config_experimental_hook = cls(
+ file_edited=file_edited,
+ session_completed=session_completed,
+ )
+
+ config_experimental_hook.additional_properties = d
+ return config_experimental_hook
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited.py b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited.py
new file mode 100644
index 000000000..8d662f1ce
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited.py
@@ -0,0 +1,73 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.config_experimental_hook_file_edited_additional_property_item import (
+ ConfigExperimentalHookFileEditedAdditionalPropertyItem,
+ )
+
+
+T = TypeVar("T", bound="ConfigExperimentalHookFileEdited")
+
+
+@_attrs_define
+class ConfigExperimentalHookFileEdited:
+ """ """
+
+ additional_properties: dict[str, list["ConfigExperimentalHookFileEditedAdditionalPropertyItem"]] = _attrs_field(
+ init=False, factory=dict
+ )
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = []
+ for additional_property_item_data in prop:
+ additional_property_item = additional_property_item_data.to_dict()
+ field_dict[prop_name].append(additional_property_item)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_experimental_hook_file_edited_additional_property_item import (
+ ConfigExperimentalHookFileEditedAdditionalPropertyItem,
+ )
+
+ d = dict(src_dict)
+ config_experimental_hook_file_edited = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+ additional_property = []
+ _additional_property = prop_dict
+ for additional_property_item_data in _additional_property:
+ additional_property_item = ConfigExperimentalHookFileEditedAdditionalPropertyItem.from_dict(
+ additional_property_item_data
+ )
+
+ additional_property.append(additional_property_item)
+
+ additional_properties[prop_name] = additional_property
+
+ config_experimental_hook_file_edited.additional_properties = additional_properties
+ return config_experimental_hook_file_edited
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> list["ConfigExperimentalHookFileEditedAdditionalPropertyItem"]:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: list["ConfigExperimentalHookFileEditedAdditionalPropertyItem"]) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited_additional_property_item.py b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited_additional_property_item.py
new file mode 100644
index 000000000..a9f27a17e
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited_additional_property_item.py
@@ -0,0 +1,87 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.config_experimental_hook_file_edited_additional_property_item_environment import (
+ ConfigExperimentalHookFileEditedAdditionalPropertyItemEnvironment,
+ )
+
+
+T = TypeVar("T", bound="ConfigExperimentalHookFileEditedAdditionalPropertyItem")
+
+
+@_attrs_define
+class ConfigExperimentalHookFileEditedAdditionalPropertyItem:
+ """
+ Attributes:
+ command (list[str]):
+ environment (Union[Unset, ConfigExperimentalHookFileEditedAdditionalPropertyItemEnvironment]):
+ """
+
+ command: list[str]
+ environment: Union[Unset, "ConfigExperimentalHookFileEditedAdditionalPropertyItemEnvironment"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ command = self.command
+
+ environment: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.environment, Unset):
+ environment = self.environment.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "command": command,
+ }
+ )
+ if environment is not UNSET:
+ field_dict["environment"] = environment
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_experimental_hook_file_edited_additional_property_item_environment import (
+ ConfigExperimentalHookFileEditedAdditionalPropertyItemEnvironment,
+ )
+
+ d = dict(src_dict)
+ command = cast(list[str], d.pop("command"))
+
+ _environment = d.pop("environment", UNSET)
+ environment: Union[Unset, ConfigExperimentalHookFileEditedAdditionalPropertyItemEnvironment]
+ if isinstance(_environment, Unset):
+ environment = UNSET
+ else:
+ environment = ConfigExperimentalHookFileEditedAdditionalPropertyItemEnvironment.from_dict(_environment)
+
+ config_experimental_hook_file_edited_additional_property_item = cls(
+ command=command,
+ environment=environment,
+ )
+
+ config_experimental_hook_file_edited_additional_property_item.additional_properties = d
+ return config_experimental_hook_file_edited_additional_property_item
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited_additional_property_item_environment.py b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited_additional_property_item_environment.py
new file mode 100644
index 000000000..545464996
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_file_edited_additional_property_item_environment.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigExperimentalHookFileEditedAdditionalPropertyItemEnvironment")
+
+
+@_attrs_define
+class ConfigExperimentalHookFileEditedAdditionalPropertyItemEnvironment:
+ """ """
+
+ additional_properties: dict[str, str] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ config_experimental_hook_file_edited_additional_property_item_environment = cls()
+
+ config_experimental_hook_file_edited_additional_property_item_environment.additional_properties = d
+ return config_experimental_hook_file_edited_additional_property_item_environment
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> str:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: str) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_session_completed_item.py b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_session_completed_item.py
new file mode 100644
index 000000000..912f1b1e4
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_session_completed_item.py
@@ -0,0 +1,87 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.config_experimental_hook_session_completed_item_environment import (
+ ConfigExperimentalHookSessionCompletedItemEnvironment,
+ )
+
+
+T = TypeVar("T", bound="ConfigExperimentalHookSessionCompletedItem")
+
+
+@_attrs_define
+class ConfigExperimentalHookSessionCompletedItem:
+ """
+ Attributes:
+ command (list[str]):
+ environment (Union[Unset, ConfigExperimentalHookSessionCompletedItemEnvironment]):
+ """
+
+ command: list[str]
+ environment: Union[Unset, "ConfigExperimentalHookSessionCompletedItemEnvironment"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ command = self.command
+
+ environment: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.environment, Unset):
+ environment = self.environment.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "command": command,
+ }
+ )
+ if environment is not UNSET:
+ field_dict["environment"] = environment
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_experimental_hook_session_completed_item_environment import (
+ ConfigExperimentalHookSessionCompletedItemEnvironment,
+ )
+
+ d = dict(src_dict)
+ command = cast(list[str], d.pop("command"))
+
+ _environment = d.pop("environment", UNSET)
+ environment: Union[Unset, ConfigExperimentalHookSessionCompletedItemEnvironment]
+ if isinstance(_environment, Unset):
+ environment = UNSET
+ else:
+ environment = ConfigExperimentalHookSessionCompletedItemEnvironment.from_dict(_environment)
+
+ config_experimental_hook_session_completed_item = cls(
+ command=command,
+ environment=environment,
+ )
+
+ config_experimental_hook_session_completed_item.additional_properties = d
+ return config_experimental_hook_session_completed_item
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_session_completed_item_environment.py b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_session_completed_item_environment.py
new file mode 100644
index 000000000..ca87e0728
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_experimental_hook_session_completed_item_environment.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigExperimentalHookSessionCompletedItemEnvironment")
+
+
+@_attrs_define
+class ConfigExperimentalHookSessionCompletedItemEnvironment:
+ """ """
+
+ additional_properties: dict[str, str] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ config_experimental_hook_session_completed_item_environment = cls()
+
+ config_experimental_hook_session_completed_item_environment.additional_properties = d
+ return config_experimental_hook_session_completed_item_environment
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> str:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: str) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_formatter.py b/packages/sdk/python/src/opencode_ai/models/config_formatter.py
new file mode 100644
index 000000000..9002e2e87
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_formatter.py
@@ -0,0 +1,57 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.config_formatter_additional_property import ConfigFormatterAdditionalProperty
+
+
+T = TypeVar("T", bound="ConfigFormatter")
+
+
+@_attrs_define
+class ConfigFormatter:
+ """ """
+
+ additional_properties: dict[str, "ConfigFormatterAdditionalProperty"] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = prop.to_dict()
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_formatter_additional_property import ConfigFormatterAdditionalProperty
+
+ d = dict(src_dict)
+ config_formatter = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+ additional_property = ConfigFormatterAdditionalProperty.from_dict(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ config_formatter.additional_properties = additional_properties
+ return config_formatter
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> "ConfigFormatterAdditionalProperty":
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: "ConfigFormatterAdditionalProperty") -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_formatter_additional_property.py b/packages/sdk/python/src/opencode_ai/models/config_formatter_additional_property.py
new file mode 100644
index 000000000..6db120256
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_formatter_additional_property.py
@@ -0,0 +1,105 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.config_formatter_additional_property_environment import ConfigFormatterAdditionalPropertyEnvironment
+
+
+T = TypeVar("T", bound="ConfigFormatterAdditionalProperty")
+
+
+@_attrs_define
+class ConfigFormatterAdditionalProperty:
+ """
+ Attributes:
+ disabled (Union[Unset, bool]):
+ command (Union[Unset, list[str]]):
+ environment (Union[Unset, ConfigFormatterAdditionalPropertyEnvironment]):
+ extensions (Union[Unset, list[str]]):
+ """
+
+ disabled: Union[Unset, bool] = UNSET
+ command: Union[Unset, list[str]] = UNSET
+ environment: Union[Unset, "ConfigFormatterAdditionalPropertyEnvironment"] = UNSET
+ extensions: Union[Unset, list[str]] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ disabled = self.disabled
+
+ command: Union[Unset, list[str]] = UNSET
+ if not isinstance(self.command, Unset):
+ command = self.command
+
+ environment: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.environment, Unset):
+ environment = self.environment.to_dict()
+
+ extensions: Union[Unset, list[str]] = UNSET
+ if not isinstance(self.extensions, Unset):
+ extensions = self.extensions
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if disabled is not UNSET:
+ field_dict["disabled"] = disabled
+ if command is not UNSET:
+ field_dict["command"] = command
+ if environment is not UNSET:
+ field_dict["environment"] = environment
+ if extensions is not UNSET:
+ field_dict["extensions"] = extensions
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_formatter_additional_property_environment import (
+ ConfigFormatterAdditionalPropertyEnvironment,
+ )
+
+ d = dict(src_dict)
+ disabled = d.pop("disabled", UNSET)
+
+ command = cast(list[str], d.pop("command", UNSET))
+
+ _environment = d.pop("environment", UNSET)
+ environment: Union[Unset, ConfigFormatterAdditionalPropertyEnvironment]
+ if isinstance(_environment, Unset):
+ environment = UNSET
+ else:
+ environment = ConfigFormatterAdditionalPropertyEnvironment.from_dict(_environment)
+
+ extensions = cast(list[str], d.pop("extensions", UNSET))
+
+ config_formatter_additional_property = cls(
+ disabled=disabled,
+ command=command,
+ environment=environment,
+ extensions=extensions,
+ )
+
+ config_formatter_additional_property.additional_properties = d
+ return config_formatter_additional_property
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_formatter_additional_property_environment.py b/packages/sdk/python/src/opencode_ai/models/config_formatter_additional_property_environment.py
new file mode 100644
index 000000000..7aa6e91a5
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_formatter_additional_property_environment.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigFormatterAdditionalPropertyEnvironment")
+
+
+@_attrs_define
+class ConfigFormatterAdditionalPropertyEnvironment:
+ """ """
+
+ additional_properties: dict[str, str] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ config_formatter_additional_property_environment = cls()
+
+ config_formatter_additional_property_environment.additional_properties = d
+ return config_formatter_additional_property_environment
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> str:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: str) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_lsp.py b/packages/sdk/python/src/opencode_ai/models/config_lsp.py
new file mode 100644
index 000000000..a974f5265
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_lsp.py
@@ -0,0 +1,86 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.config_lsp_additional_property_type_0 import ConfigLspAdditionalPropertyType0
+ from ..models.config_lsp_additional_property_type_1 import ConfigLspAdditionalPropertyType1
+
+
+T = TypeVar("T", bound="ConfigLsp")
+
+
+@_attrs_define
+class ConfigLsp:
+ """ """
+
+ additional_properties: dict[str, Union["ConfigLspAdditionalPropertyType0", "ConfigLspAdditionalPropertyType1"]] = (
+ _attrs_field(init=False, factory=dict)
+ )
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.config_lsp_additional_property_type_0 import ConfigLspAdditionalPropertyType0
+
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ if isinstance(prop, ConfigLspAdditionalPropertyType0):
+ field_dict[prop_name] = prop.to_dict()
+ else:
+ field_dict[prop_name] = prop.to_dict()
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_lsp_additional_property_type_0 import ConfigLspAdditionalPropertyType0
+ from ..models.config_lsp_additional_property_type_1 import ConfigLspAdditionalPropertyType1
+
+ d = dict(src_dict)
+ config_lsp = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+
+ def _parse_additional_property(
+ data: object,
+ ) -> Union["ConfigLspAdditionalPropertyType0", "ConfigLspAdditionalPropertyType1"]:
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ additional_property_type_0 = ConfigLspAdditionalPropertyType0.from_dict(data)
+
+ return additional_property_type_0
+ except: # noqa: E722
+ pass
+ if not isinstance(data, dict):
+ raise TypeError()
+ additional_property_type_1 = ConfigLspAdditionalPropertyType1.from_dict(data)
+
+ return additional_property_type_1
+
+ additional_property = _parse_additional_property(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ config_lsp.additional_properties = additional_properties
+ return config_lsp
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Union["ConfigLspAdditionalPropertyType0", "ConfigLspAdditionalPropertyType1"]:
+ return self.additional_properties[key]
+
+ def __setitem__(
+ self, key: str, value: Union["ConfigLspAdditionalPropertyType0", "ConfigLspAdditionalPropertyType1"]
+ ) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_0.py b/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_0.py
new file mode 100644
index 000000000..819d7d597
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_0.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigLspAdditionalPropertyType0")
+
+
+@_attrs_define
+class ConfigLspAdditionalPropertyType0:
+ """
+ Attributes:
+ disabled (bool):
+ """
+
+ disabled: bool
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ disabled = self.disabled
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "disabled": disabled,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ disabled = d.pop("disabled")
+
+ config_lsp_additional_property_type_0 = cls(
+ disabled=disabled,
+ )
+
+ config_lsp_additional_property_type_0.additional_properties = d
+ return config_lsp_additional_property_type_0
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1.py b/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1.py
new file mode 100644
index 000000000..cd3d39b2d
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1.py
@@ -0,0 +1,125 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.config_lsp_additional_property_type_1_env import ConfigLspAdditionalPropertyType1Env
+ from ..models.config_lsp_additional_property_type_1_initialization import (
+ ConfigLspAdditionalPropertyType1Initialization,
+ )
+
+
+T = TypeVar("T", bound="ConfigLspAdditionalPropertyType1")
+
+
+@_attrs_define
+class ConfigLspAdditionalPropertyType1:
+ """
+ Attributes:
+ command (list[str]):
+ extensions (Union[Unset, list[str]]):
+ disabled (Union[Unset, bool]):
+ env (Union[Unset, ConfigLspAdditionalPropertyType1Env]):
+ initialization (Union[Unset, ConfigLspAdditionalPropertyType1Initialization]):
+ """
+
+ command: list[str]
+ extensions: Union[Unset, list[str]] = UNSET
+ disabled: Union[Unset, bool] = UNSET
+ env: Union[Unset, "ConfigLspAdditionalPropertyType1Env"] = UNSET
+ initialization: Union[Unset, "ConfigLspAdditionalPropertyType1Initialization"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ command = self.command
+
+ extensions: Union[Unset, list[str]] = UNSET
+ if not isinstance(self.extensions, Unset):
+ extensions = self.extensions
+
+ disabled = self.disabled
+
+ env: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.env, Unset):
+ env = self.env.to_dict()
+
+ initialization: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.initialization, Unset):
+ initialization = self.initialization.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "command": command,
+ }
+ )
+ if extensions is not UNSET:
+ field_dict["extensions"] = extensions
+ if disabled is not UNSET:
+ field_dict["disabled"] = disabled
+ if env is not UNSET:
+ field_dict["env"] = env
+ if initialization is not UNSET:
+ field_dict["initialization"] = initialization
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_lsp_additional_property_type_1_env import ConfigLspAdditionalPropertyType1Env
+ from ..models.config_lsp_additional_property_type_1_initialization import (
+ ConfigLspAdditionalPropertyType1Initialization,
+ )
+
+ d = dict(src_dict)
+ command = cast(list[str], d.pop("command"))
+
+ extensions = cast(list[str], d.pop("extensions", UNSET))
+
+ disabled = d.pop("disabled", UNSET)
+
+ _env = d.pop("env", UNSET)
+ env: Union[Unset, ConfigLspAdditionalPropertyType1Env]
+ if isinstance(_env, Unset):
+ env = UNSET
+ else:
+ env = ConfigLspAdditionalPropertyType1Env.from_dict(_env)
+
+ _initialization = d.pop("initialization", UNSET)
+ initialization: Union[Unset, ConfigLspAdditionalPropertyType1Initialization]
+ if isinstance(_initialization, Unset):
+ initialization = UNSET
+ else:
+ initialization = ConfigLspAdditionalPropertyType1Initialization.from_dict(_initialization)
+
+ config_lsp_additional_property_type_1 = cls(
+ command=command,
+ extensions=extensions,
+ disabled=disabled,
+ env=env,
+ initialization=initialization,
+ )
+
+ config_lsp_additional_property_type_1.additional_properties = d
+ return config_lsp_additional_property_type_1
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1_env.py b/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1_env.py
new file mode 100644
index 000000000..0ae2280a5
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1_env.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigLspAdditionalPropertyType1Env")
+
+
+@_attrs_define
+class ConfigLspAdditionalPropertyType1Env:
+ """ """
+
+ additional_properties: dict[str, str] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ config_lsp_additional_property_type_1_env = cls()
+
+ config_lsp_additional_property_type_1_env.additional_properties = d
+ return config_lsp_additional_property_type_1_env
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> str:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: str) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1_initialization.py b/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1_initialization.py
new file mode 100644
index 000000000..52d192f62
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_lsp_additional_property_type_1_initialization.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigLspAdditionalPropertyType1Initialization")
+
+
+@_attrs_define
+class ConfigLspAdditionalPropertyType1Initialization:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ config_lsp_additional_property_type_1_initialization = cls()
+
+ config_lsp_additional_property_type_1_initialization.additional_properties = d
+ return config_lsp_additional_property_type_1_initialization
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_mcp.py b/packages/sdk/python/src/opencode_ai/models/config_mcp.py
new file mode 100644
index 000000000..dbd018509
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_mcp.py
@@ -0,0 +1,82 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.mcp_local_config import McpLocalConfig
+ from ..models.mcp_remote_config import McpRemoteConfig
+
+
+T = TypeVar("T", bound="ConfigMcp")
+
+
+@_attrs_define
+class ConfigMcp:
+ """MCP (Model Context Protocol) server configurations"""
+
+ additional_properties: dict[str, Union["McpLocalConfig", "McpRemoteConfig"]] = _attrs_field(
+ init=False, factory=dict
+ )
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.mcp_local_config import McpLocalConfig
+
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ if isinstance(prop, McpLocalConfig):
+ field_dict[prop_name] = prop.to_dict()
+ else:
+ field_dict[prop_name] = prop.to_dict()
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.mcp_local_config import McpLocalConfig
+ from ..models.mcp_remote_config import McpRemoteConfig
+
+ d = dict(src_dict)
+ config_mcp = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+
+ def _parse_additional_property(data: object) -> Union["McpLocalConfig", "McpRemoteConfig"]:
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ additional_property_type_0 = McpLocalConfig.from_dict(data)
+
+ return additional_property_type_0
+ except: # noqa: E722
+ pass
+ if not isinstance(data, dict):
+ raise TypeError()
+ additional_property_type_1 = McpRemoteConfig.from_dict(data)
+
+ return additional_property_type_1
+
+ additional_property = _parse_additional_property(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ config_mcp.additional_properties = additional_properties
+ return config_mcp
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Union["McpLocalConfig", "McpRemoteConfig"]:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Union["McpLocalConfig", "McpRemoteConfig"]) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_mode.py b/packages/sdk/python/src/opencode_ai/models/config_mode.py
new file mode 100644
index 000000000..8ef64947c
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_mode.py
@@ -0,0 +1,97 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.agent_config import AgentConfig
+
+
+T = TypeVar("T", bound="ConfigMode")
+
+
+@_attrs_define
+class ConfigMode:
+ """@deprecated Use `agent` field instead.
+
+ Attributes:
+ build (Union[Unset, AgentConfig]):
+ plan (Union[Unset, AgentConfig]):
+ """
+
+ build: Union[Unset, "AgentConfig"] = UNSET
+ plan: Union[Unset, "AgentConfig"] = UNSET
+ additional_properties: dict[str, "AgentConfig"] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ build: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.build, Unset):
+ build = self.build.to_dict()
+
+ plan: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.plan, Unset):
+ plan = self.plan.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = prop.to_dict()
+
+ field_dict.update({})
+ if build is not UNSET:
+ field_dict["build"] = build
+ if plan is not UNSET:
+ field_dict["plan"] = plan
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.agent_config import AgentConfig
+
+ d = dict(src_dict)
+ _build = d.pop("build", UNSET)
+ build: Union[Unset, AgentConfig]
+ if isinstance(_build, Unset):
+ build = UNSET
+ else:
+ build = AgentConfig.from_dict(_build)
+
+ _plan = d.pop("plan", UNSET)
+ plan: Union[Unset, AgentConfig]
+ if isinstance(_plan, Unset):
+ plan = UNSET
+ else:
+ plan = AgentConfig.from_dict(_plan)
+
+ config_mode = cls(
+ build=build,
+ plan=plan,
+ )
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+ additional_property = AgentConfig.from_dict(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ config_mode.additional_properties = additional_properties
+ return config_mode
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> "AgentConfig":
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: "AgentConfig") -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_permission.py b/packages/sdk/python/src/opencode_ai/models/config_permission.py
new file mode 100644
index 000000000..baf3c3b52
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_permission.py
@@ -0,0 +1,155 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.config_permission_bash_type_1 import ConfigPermissionBashType1
+
+
+T = TypeVar("T", bound="ConfigPermission")
+
+
+@_attrs_define
+class ConfigPermission:
+ """
+ Attributes:
+ edit (Union[Literal['allow'], Literal['ask'], Literal['deny'], Unset]):
+ bash (Union['ConfigPermissionBashType1', Literal['allow'], Literal['ask'], Literal['deny'], Unset]):
+ webfetch (Union[Literal['allow'], Literal['ask'], Literal['deny'], Unset]):
+ """
+
+ edit: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset] = UNSET
+ bash: Union["ConfigPermissionBashType1", Literal["allow"], Literal["ask"], Literal["deny"], Unset] = UNSET
+ webfetch: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.config_permission_bash_type_1 import ConfigPermissionBashType1
+
+ edit: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset]
+ if isinstance(self.edit, Unset):
+ edit = UNSET
+ else:
+ edit = self.edit
+
+ bash: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset, dict[str, Any]]
+ if isinstance(self.bash, Unset):
+ bash = UNSET
+ elif isinstance(self.bash, ConfigPermissionBashType1):
+ bash = self.bash.to_dict()
+ else:
+ bash = self.bash
+
+ webfetch: Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset]
+ if isinstance(self.webfetch, Unset):
+ webfetch = UNSET
+ else:
+ webfetch = self.webfetch
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if edit is not UNSET:
+ field_dict["edit"] = edit
+ if bash is not UNSET:
+ field_dict["bash"] = bash
+ if webfetch is not UNSET:
+ field_dict["webfetch"] = webfetch
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_permission_bash_type_1 import ConfigPermissionBashType1
+
+ d = dict(src_dict)
+
+ def _parse_edit(data: object) -> Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset]:
+ if isinstance(data, Unset):
+ return data
+ edit_type_0 = cast(Literal["ask"], data)
+ if edit_type_0 != "ask":
+ raise ValueError(f"edit_type_0 must match const 'ask', got '{edit_type_0}'")
+ return edit_type_0
+ edit_type_1 = cast(Literal["allow"], data)
+ if edit_type_1 != "allow":
+ raise ValueError(f"edit_type_1 must match const 'allow', got '{edit_type_1}'")
+ return edit_type_1
+ edit_type_2 = cast(Literal["deny"], data)
+ if edit_type_2 != "deny":
+ raise ValueError(f"edit_type_2 must match const 'deny', got '{edit_type_2}'")
+ return edit_type_2
+
+ edit = _parse_edit(d.pop("edit", UNSET))
+
+ def _parse_bash(
+ data: object,
+ ) -> Union["ConfigPermissionBashType1", Literal["allow"], Literal["ask"], Literal["deny"], Unset]:
+ if isinstance(data, Unset):
+ return data
+ bash_type_0_type_0 = cast(Literal["ask"], data)
+ if bash_type_0_type_0 != "ask":
+ raise ValueError(f"bash_type_0_type_0 must match const 'ask', got '{bash_type_0_type_0}'")
+ return bash_type_0_type_0
+ bash_type_0_type_1 = cast(Literal["allow"], data)
+ if bash_type_0_type_1 != "allow":
+ raise ValueError(f"bash_type_0_type_1 must match const 'allow', got '{bash_type_0_type_1}'")
+ return bash_type_0_type_1
+ bash_type_0_type_2 = cast(Literal["deny"], data)
+ if bash_type_0_type_2 != "deny":
+ raise ValueError(f"bash_type_0_type_2 must match const 'deny', got '{bash_type_0_type_2}'")
+ return bash_type_0_type_2
+ if not isinstance(data, dict):
+ raise TypeError()
+ bash_type_1 = ConfigPermissionBashType1.from_dict(data)
+
+ return bash_type_1
+
+ bash = _parse_bash(d.pop("bash", UNSET))
+
+ def _parse_webfetch(data: object) -> Union[Literal["allow"], Literal["ask"], Literal["deny"], Unset]:
+ if isinstance(data, Unset):
+ return data
+ webfetch_type_0 = cast(Literal["ask"], data)
+ if webfetch_type_0 != "ask":
+ raise ValueError(f"webfetch_type_0 must match const 'ask', got '{webfetch_type_0}'")
+ return webfetch_type_0
+ webfetch_type_1 = cast(Literal["allow"], data)
+ if webfetch_type_1 != "allow":
+ raise ValueError(f"webfetch_type_1 must match const 'allow', got '{webfetch_type_1}'")
+ return webfetch_type_1
+ webfetch_type_2 = cast(Literal["deny"], data)
+ if webfetch_type_2 != "deny":
+ raise ValueError(f"webfetch_type_2 must match const 'deny', got '{webfetch_type_2}'")
+ return webfetch_type_2
+
+ webfetch = _parse_webfetch(d.pop("webfetch", UNSET))
+
+ config_permission = cls(
+ edit=edit,
+ bash=bash,
+ webfetch=webfetch,
+ )
+
+ config_permission.additional_properties = d
+ return config_permission
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_permission_bash_type_1.py b/packages/sdk/python/src/opencode_ai/models/config_permission_bash_type_1.py
new file mode 100644
index 000000000..bc7b0dc58
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_permission_bash_type_1.py
@@ -0,0 +1,74 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigPermissionBashType1")
+
+
+@_attrs_define
+class ConfigPermissionBashType1:
+ """ """
+
+ additional_properties: dict[str, Union[Literal["allow"], Literal["ask"], Literal["deny"]]] = _attrs_field(
+ init=False, factory=dict
+ )
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = prop
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ config_permission_bash_type_1 = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+
+ def _parse_additional_property(data: object) -> Union[Literal["allow"], Literal["ask"], Literal["deny"]]:
+ additional_property_type_0 = cast(Literal["ask"], data)
+ if additional_property_type_0 != "ask":
+ raise ValueError(
+ f"AdditionalProperty_type_0 must match const 'ask', got '{additional_property_type_0}'"
+ )
+ return additional_property_type_0
+ additional_property_type_1 = cast(Literal["allow"], data)
+ if additional_property_type_1 != "allow":
+ raise ValueError(
+ f"AdditionalProperty_type_1 must match const 'allow', got '{additional_property_type_1}'"
+ )
+ return additional_property_type_1
+ additional_property_type_2 = cast(Literal["deny"], data)
+ if additional_property_type_2 != "deny":
+ raise ValueError(
+ f"AdditionalProperty_type_2 must match const 'deny', got '{additional_property_type_2}'"
+ )
+ return additional_property_type_2
+
+ additional_property = _parse_additional_property(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ config_permission_bash_type_1.additional_properties = additional_properties
+ return config_permission_bash_type_1
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Union[Literal["allow"], Literal["ask"], Literal["deny"]]:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Union[Literal["allow"], Literal["ask"], Literal["deny"]]) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_provider.py b/packages/sdk/python/src/opencode_ai/models/config_provider.py
new file mode 100644
index 000000000..577b9b056
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_provider.py
@@ -0,0 +1,57 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.config_provider_additional_property import ConfigProviderAdditionalProperty
+
+
+T = TypeVar("T", bound="ConfigProvider")
+
+
+@_attrs_define
+class ConfigProvider:
+ """Custom provider configurations and model overrides"""
+
+ additional_properties: dict[str, "ConfigProviderAdditionalProperty"] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = prop.to_dict()
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_provider_additional_property import ConfigProviderAdditionalProperty
+
+ d = dict(src_dict)
+ config_provider = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+ additional_property = ConfigProviderAdditionalProperty.from_dict(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ config_provider.additional_properties = additional_properties
+ return config_provider
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> "ConfigProviderAdditionalProperty":
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: "ConfigProviderAdditionalProperty") -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property.py b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property.py
new file mode 100644
index 000000000..a6aef270b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property.py
@@ -0,0 +1,118 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.config_provider_additional_property_models import ConfigProviderAdditionalPropertyModels
+ from ..models.config_provider_additional_property_options import ConfigProviderAdditionalPropertyOptions
+
+
+T = TypeVar("T", bound="ConfigProviderAdditionalProperty")
+
+
+@_attrs_define
+class ConfigProviderAdditionalProperty:
+ """
+ Attributes:
+ api (Union[Unset, str]):
+ name (Union[Unset, str]):
+ env (Union[Unset, list[str]]):
+ id (Union[Unset, str]):
+ npm (Union[Unset, str]):
+ models (Union[Unset, ConfigProviderAdditionalPropertyModels]):
+ options (Union[Unset, ConfigProviderAdditionalPropertyOptions]):
+ """
+
+ api: Union[Unset, str] = UNSET
+ name: Union[Unset, str] = UNSET
+ env: Union[Unset, list[str]] = UNSET
+ id: Union[Unset, str] = UNSET
+ npm: Union[Unset, str] = UNSET
+ models: Union[Unset, "ConfigProviderAdditionalPropertyModels"] = UNSET
+ options: Union[Unset, "ConfigProviderAdditionalPropertyOptions"] = UNSET
+
+ def to_dict(self) -> dict[str, Any]:
+ api = self.api
+
+ name = self.name
+
+ env: Union[Unset, list[str]] = UNSET
+ if not isinstance(self.env, Unset):
+ env = self.env
+
+ id = self.id
+
+ npm = self.npm
+
+ models: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.models, Unset):
+ models = self.models.to_dict()
+
+ options: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.options, Unset):
+ options = self.options.to_dict()
+
+ field_dict: dict[str, Any] = {}
+
+ field_dict.update({})
+ if api is not UNSET:
+ field_dict["api"] = api
+ if name is not UNSET:
+ field_dict["name"] = name
+ if env is not UNSET:
+ field_dict["env"] = env
+ if id is not UNSET:
+ field_dict["id"] = id
+ if npm is not UNSET:
+ field_dict["npm"] = npm
+ if models is not UNSET:
+ field_dict["models"] = models
+ if options is not UNSET:
+ field_dict["options"] = options
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_provider_additional_property_models import ConfigProviderAdditionalPropertyModels
+ from ..models.config_provider_additional_property_options import ConfigProviderAdditionalPropertyOptions
+
+ d = dict(src_dict)
+ api = d.pop("api", UNSET)
+
+ name = d.pop("name", UNSET)
+
+ env = cast(list[str], d.pop("env", UNSET))
+
+ id = d.pop("id", UNSET)
+
+ npm = d.pop("npm", UNSET)
+
+ _models = d.pop("models", UNSET)
+ models: Union[Unset, ConfigProviderAdditionalPropertyModels]
+ if isinstance(_models, Unset):
+ models = UNSET
+ else:
+ models = ConfigProviderAdditionalPropertyModels.from_dict(_models)
+
+ _options = d.pop("options", UNSET)
+ options: Union[Unset, ConfigProviderAdditionalPropertyOptions]
+ if isinstance(_options, Unset):
+ options = UNSET
+ else:
+ options = ConfigProviderAdditionalPropertyOptions.from_dict(_options)
+
+ config_provider_additional_property = cls(
+ api=api,
+ name=name,
+ env=env,
+ id=id,
+ npm=npm,
+ models=models,
+ options=options,
+ )
+
+ return config_provider_additional_property
diff --git a/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models.py b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models.py
new file mode 100644
index 000000000..8277df5ad
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models.py
@@ -0,0 +1,63 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.config_provider_additional_property_models_additional_property import (
+ ConfigProviderAdditionalPropertyModelsAdditionalProperty,
+ )
+
+
+T = TypeVar("T", bound="ConfigProviderAdditionalPropertyModels")
+
+
+@_attrs_define
+class ConfigProviderAdditionalPropertyModels:
+ """ """
+
+ additional_properties: dict[str, "ConfigProviderAdditionalPropertyModelsAdditionalProperty"] = _attrs_field(
+ init=False, factory=dict
+ )
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = prop.to_dict()
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_provider_additional_property_models_additional_property import (
+ ConfigProviderAdditionalPropertyModelsAdditionalProperty,
+ )
+
+ d = dict(src_dict)
+ config_provider_additional_property_models = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+ additional_property = ConfigProviderAdditionalPropertyModelsAdditionalProperty.from_dict(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ config_provider_additional_property_models.additional_properties = additional_properties
+ return config_provider_additional_property_models
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> "ConfigProviderAdditionalPropertyModelsAdditionalProperty":
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: "ConfigProviderAdditionalPropertyModelsAdditionalProperty") -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property.py b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property.py
new file mode 100644
index 000000000..eac949c7b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property.py
@@ -0,0 +1,214 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.config_provider_additional_property_models_additional_property_cost import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyCost,
+ )
+ from ..models.config_provider_additional_property_models_additional_property_limit import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyLimit,
+ )
+ from ..models.config_provider_additional_property_models_additional_property_options import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyOptions,
+ )
+ from ..models.config_provider_additional_property_models_additional_property_provider import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyProvider,
+ )
+
+
+T = TypeVar("T", bound="ConfigProviderAdditionalPropertyModelsAdditionalProperty")
+
+
+@_attrs_define
+class ConfigProviderAdditionalPropertyModelsAdditionalProperty:
+ """
+ Attributes:
+ id (Union[Unset, str]):
+ name (Union[Unset, str]):
+ release_date (Union[Unset, str]):
+ attachment (Union[Unset, bool]):
+ reasoning (Union[Unset, bool]):
+ temperature (Union[Unset, bool]):
+ tool_call (Union[Unset, bool]):
+ cost (Union[Unset, ConfigProviderAdditionalPropertyModelsAdditionalPropertyCost]):
+ limit (Union[Unset, ConfigProviderAdditionalPropertyModelsAdditionalPropertyLimit]):
+ experimental (Union[Unset, bool]):
+ options (Union[Unset, ConfigProviderAdditionalPropertyModelsAdditionalPropertyOptions]):
+ provider (Union[Unset, ConfigProviderAdditionalPropertyModelsAdditionalPropertyProvider]):
+ """
+
+ id: Union[Unset, str] = UNSET
+ name: Union[Unset, str] = UNSET
+ release_date: Union[Unset, str] = UNSET
+ attachment: Union[Unset, bool] = UNSET
+ reasoning: Union[Unset, bool] = UNSET
+ temperature: Union[Unset, bool] = UNSET
+ tool_call: Union[Unset, bool] = UNSET
+ cost: Union[Unset, "ConfigProviderAdditionalPropertyModelsAdditionalPropertyCost"] = UNSET
+ limit: Union[Unset, "ConfigProviderAdditionalPropertyModelsAdditionalPropertyLimit"] = UNSET
+ experimental: Union[Unset, bool] = UNSET
+ options: Union[Unset, "ConfigProviderAdditionalPropertyModelsAdditionalPropertyOptions"] = UNSET
+ provider: Union[Unset, "ConfigProviderAdditionalPropertyModelsAdditionalPropertyProvider"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ name = self.name
+
+ release_date = self.release_date
+
+ attachment = self.attachment
+
+ reasoning = self.reasoning
+
+ temperature = self.temperature
+
+ tool_call = self.tool_call
+
+ cost: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.cost, Unset):
+ cost = self.cost.to_dict()
+
+ limit: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.limit, Unset):
+ limit = self.limit.to_dict()
+
+ experimental = self.experimental
+
+ options: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.options, Unset):
+ options = self.options.to_dict()
+
+ provider: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.provider, Unset):
+ provider = self.provider.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if id is not UNSET:
+ field_dict["id"] = id
+ if name is not UNSET:
+ field_dict["name"] = name
+ if release_date is not UNSET:
+ field_dict["release_date"] = release_date
+ if attachment is not UNSET:
+ field_dict["attachment"] = attachment
+ if reasoning is not UNSET:
+ field_dict["reasoning"] = reasoning
+ if temperature is not UNSET:
+ field_dict["temperature"] = temperature
+ if tool_call is not UNSET:
+ field_dict["tool_call"] = tool_call
+ if cost is not UNSET:
+ field_dict["cost"] = cost
+ if limit is not UNSET:
+ field_dict["limit"] = limit
+ if experimental is not UNSET:
+ field_dict["experimental"] = experimental
+ if options is not UNSET:
+ field_dict["options"] = options
+ if provider is not UNSET:
+ field_dict["provider"] = provider
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_provider_additional_property_models_additional_property_cost import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyCost,
+ )
+ from ..models.config_provider_additional_property_models_additional_property_limit import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyLimit,
+ )
+ from ..models.config_provider_additional_property_models_additional_property_options import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyOptions,
+ )
+ from ..models.config_provider_additional_property_models_additional_property_provider import (
+ ConfigProviderAdditionalPropertyModelsAdditionalPropertyProvider,
+ )
+
+ d = dict(src_dict)
+ id = d.pop("id", UNSET)
+
+ name = d.pop("name", UNSET)
+
+ release_date = d.pop("release_date", UNSET)
+
+ attachment = d.pop("attachment", UNSET)
+
+ reasoning = d.pop("reasoning", UNSET)
+
+ temperature = d.pop("temperature", UNSET)
+
+ tool_call = d.pop("tool_call", UNSET)
+
+ _cost = d.pop("cost", UNSET)
+ cost: Union[Unset, ConfigProviderAdditionalPropertyModelsAdditionalPropertyCost]
+ if isinstance(_cost, Unset):
+ cost = UNSET
+ else:
+ cost = ConfigProviderAdditionalPropertyModelsAdditionalPropertyCost.from_dict(_cost)
+
+ _limit = d.pop("limit", UNSET)
+ limit: Union[Unset, ConfigProviderAdditionalPropertyModelsAdditionalPropertyLimit]
+ if isinstance(_limit, Unset):
+ limit = UNSET
+ else:
+ limit = ConfigProviderAdditionalPropertyModelsAdditionalPropertyLimit.from_dict(_limit)
+
+ experimental = d.pop("experimental", UNSET)
+
+ _options = d.pop("options", UNSET)
+ options: Union[Unset, ConfigProviderAdditionalPropertyModelsAdditionalPropertyOptions]
+ if isinstance(_options, Unset):
+ options = UNSET
+ else:
+ options = ConfigProviderAdditionalPropertyModelsAdditionalPropertyOptions.from_dict(_options)
+
+ _provider = d.pop("provider", UNSET)
+ provider: Union[Unset, ConfigProviderAdditionalPropertyModelsAdditionalPropertyProvider]
+ if isinstance(_provider, Unset):
+ provider = UNSET
+ else:
+ provider = ConfigProviderAdditionalPropertyModelsAdditionalPropertyProvider.from_dict(_provider)
+
+ config_provider_additional_property_models_additional_property = cls(
+ id=id,
+ name=name,
+ release_date=release_date,
+ attachment=attachment,
+ reasoning=reasoning,
+ temperature=temperature,
+ tool_call=tool_call,
+ cost=cost,
+ limit=limit,
+ experimental=experimental,
+ options=options,
+ provider=provider,
+ )
+
+ config_provider_additional_property_models_additional_property.additional_properties = d
+ return config_provider_additional_property_models_additional_property
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_cost.py b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_cost.py
new file mode 100644
index 000000000..07e38e713
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_cost.py
@@ -0,0 +1,87 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="ConfigProviderAdditionalPropertyModelsAdditionalPropertyCost")
+
+
+@_attrs_define
+class ConfigProviderAdditionalPropertyModelsAdditionalPropertyCost:
+ """
+ Attributes:
+ input_ (float):
+ output (float):
+ cache_read (Union[Unset, float]):
+ cache_write (Union[Unset, float]):
+ """
+
+ input_: float
+ output: float
+ cache_read: Union[Unset, float] = UNSET
+ cache_write: Union[Unset, float] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ input_ = self.input_
+
+ output = self.output
+
+ cache_read = self.cache_read
+
+ cache_write = self.cache_write
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "input": input_,
+ "output": output,
+ }
+ )
+ if cache_read is not UNSET:
+ field_dict["cache_read"] = cache_read
+ if cache_write is not UNSET:
+ field_dict["cache_write"] = cache_write
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ input_ = d.pop("input")
+
+ output = d.pop("output")
+
+ cache_read = d.pop("cache_read", UNSET)
+
+ cache_write = d.pop("cache_write", UNSET)
+
+ config_provider_additional_property_models_additional_property_cost = cls(
+ input_=input_,
+ output=output,
+ cache_read=cache_read,
+ cache_write=cache_write,
+ )
+
+ config_provider_additional_property_models_additional_property_cost.additional_properties = d
+ return config_provider_additional_property_models_additional_property_cost
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_limit.py b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_limit.py
new file mode 100644
index 000000000..6e610550f
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_limit.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigProviderAdditionalPropertyModelsAdditionalPropertyLimit")
+
+
+@_attrs_define
+class ConfigProviderAdditionalPropertyModelsAdditionalPropertyLimit:
+ """
+ Attributes:
+ context (float):
+ output (float):
+ """
+
+ context: float
+ output: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ context = self.context
+
+ output = self.output
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "context": context,
+ "output": output,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ context = d.pop("context")
+
+ output = d.pop("output")
+
+ config_provider_additional_property_models_additional_property_limit = cls(
+ context=context,
+ output=output,
+ )
+
+ config_provider_additional_property_models_additional_property_limit.additional_properties = d
+ return config_provider_additional_property_models_additional_property_limit
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_options.py b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_options.py
new file mode 100644
index 000000000..f46f1b504
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_options.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigProviderAdditionalPropertyModelsAdditionalPropertyOptions")
+
+
+@_attrs_define
+class ConfigProviderAdditionalPropertyModelsAdditionalPropertyOptions:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ config_provider_additional_property_models_additional_property_options = cls()
+
+ config_provider_additional_property_models_additional_property_options.additional_properties = d
+ return config_provider_additional_property_models_additional_property_options
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_provider.py b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_provider.py
new file mode 100644
index 000000000..dd3f57c4b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_models_additional_property_provider.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigProviderAdditionalPropertyModelsAdditionalPropertyProvider")
+
+
+@_attrs_define
+class ConfigProviderAdditionalPropertyModelsAdditionalPropertyProvider:
+ """
+ Attributes:
+ npm (str):
+ """
+
+ npm: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ npm = self.npm
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "npm": npm,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ npm = d.pop("npm")
+
+ config_provider_additional_property_models_additional_property_provider = cls(
+ npm=npm,
+ )
+
+ config_provider_additional_property_models_additional_property_provider.additional_properties = d
+ return config_provider_additional_property_models_additional_property_provider
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_options.py b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_options.py
new file mode 100644
index 000000000..119523633
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_provider_additional_property_options.py
@@ -0,0 +1,87 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="ConfigProviderAdditionalPropertyOptions")
+
+
+@_attrs_define
+class ConfigProviderAdditionalPropertyOptions:
+ """
+ Attributes:
+ api_key (Union[Unset, str]):
+ base_url (Union[Unset, str]):
+ timeout (Union[Unset, bool, int]): Timeout in milliseconds for requests to this provider. Default is 300000 (5
+ minutes). Set to false to disable timeout.
+ """
+
+ api_key: Union[Unset, str] = UNSET
+ base_url: Union[Unset, str] = UNSET
+ timeout: Union[Unset, bool, int] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ api_key = self.api_key
+
+ base_url = self.base_url
+
+ timeout: Union[Unset, bool, int]
+ if isinstance(self.timeout, Unset):
+ timeout = UNSET
+ else:
+ timeout = self.timeout
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if api_key is not UNSET:
+ field_dict["apiKey"] = api_key
+ if base_url is not UNSET:
+ field_dict["baseURL"] = base_url
+ if timeout is not UNSET:
+ field_dict["timeout"] = timeout
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ api_key = d.pop("apiKey", UNSET)
+
+ base_url = d.pop("baseURL", UNSET)
+
+ def _parse_timeout(data: object) -> Union[Unset, bool, int]:
+ if isinstance(data, Unset):
+ return data
+ return cast(Union[Unset, bool, int], data)
+
+ timeout = _parse_timeout(d.pop("timeout", UNSET))
+
+ config_provider_additional_property_options = cls(
+ api_key=api_key,
+ base_url=base_url,
+ timeout=timeout,
+ )
+
+ config_provider_additional_property_options.additional_properties = d
+ return config_provider_additional_property_options
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_providers_response_200.py b/packages/sdk/python/src/opencode_ai/models/config_providers_response_200.py
new file mode 100644
index 000000000..bb245e5ae
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_providers_response_200.py
@@ -0,0 +1,83 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.config_providers_response_200_default import ConfigProvidersResponse200Default
+ from ..models.provider import Provider
+
+
+T = TypeVar("T", bound="ConfigProvidersResponse200")
+
+
+@_attrs_define
+class ConfigProvidersResponse200:
+ """
+ Attributes:
+ providers (list['Provider']):
+ default (ConfigProvidersResponse200Default):
+ """
+
+ providers: list["Provider"]
+ default: "ConfigProvidersResponse200Default"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ providers = []
+ for providers_item_data in self.providers:
+ providers_item = providers_item_data.to_dict()
+ providers.append(providers_item)
+
+ default = self.default.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "providers": providers,
+ "default": default,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.config_providers_response_200_default import ConfigProvidersResponse200Default
+ from ..models.provider import Provider
+
+ d = dict(src_dict)
+ providers = []
+ _providers = d.pop("providers")
+ for providers_item_data in _providers:
+ providers_item = Provider.from_dict(providers_item_data)
+
+ providers.append(providers_item)
+
+ default = ConfigProvidersResponse200Default.from_dict(d.pop("default"))
+
+ config_providers_response_200 = cls(
+ providers=providers,
+ default=default,
+ )
+
+ config_providers_response_200.additional_properties = d
+ return config_providers_response_200
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_providers_response_200_default.py b/packages/sdk/python/src/opencode_ai/models/config_providers_response_200_default.py
new file mode 100644
index 000000000..6be679e34
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_providers_response_200_default.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigProvidersResponse200Default")
+
+
+@_attrs_define
+class ConfigProvidersResponse200Default:
+ """ """
+
+ additional_properties: dict[str, str] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ config_providers_response_200_default = cls()
+
+ config_providers_response_200_default.additional_properties = d
+ return config_providers_response_200_default
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> str:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: str) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_share.py b/packages/sdk/python/src/opencode_ai/models/config_share.py
new file mode 100644
index 000000000..5979e51e9
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_share.py
@@ -0,0 +1,10 @@
+from enum import Enum
+
+
+class ConfigShare(str, Enum):
+ AUTO = "auto"
+ DISABLED = "disabled"
+ MANUAL = "manual"
+
+ def __str__(self) -> str:
+ return str(self.value)
diff --git a/packages/sdk/python/src/opencode_ai/models/config_tools.py b/packages/sdk/python/src/opencode_ai/models/config_tools.py
new file mode 100644
index 000000000..ab1460584
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_tools.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ConfigTools")
+
+
+@_attrs_define
+class ConfigTools:
+ """ """
+
+ additional_properties: dict[str, bool] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ config_tools = cls()
+
+ config_tools.additional_properties = d
+ return config_tools
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> bool:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: bool) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_tui.py b/packages/sdk/python/src/opencode_ai/models/config_tui.py
new file mode 100644
index 000000000..d28fbdfb2
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_tui.py
@@ -0,0 +1,60 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="ConfigTui")
+
+
+@_attrs_define
+class ConfigTui:
+ """TUI specific settings
+
+ Attributes:
+ scroll_speed (Union[Unset, float]): TUI scroll speed Default: 2.0.
+ """
+
+ scroll_speed: Union[Unset, float] = 2.0
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ scroll_speed = self.scroll_speed
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if scroll_speed is not UNSET:
+ field_dict["scroll_speed"] = scroll_speed
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ scroll_speed = d.pop("scroll_speed", UNSET)
+
+ config_tui = cls(
+ scroll_speed=scroll_speed,
+ )
+
+ config_tui.additional_properties = d
+ return config_tui
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/config_watcher.py b/packages/sdk/python/src/opencode_ai/models/config_watcher.py
new file mode 100644
index 000000000..4cee47b28
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/config_watcher.py
@@ -0,0 +1,61 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="ConfigWatcher")
+
+
+@_attrs_define
+class ConfigWatcher:
+ """
+ Attributes:
+ ignore (Union[Unset, list[str]]):
+ """
+
+ ignore: Union[Unset, list[str]] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ ignore: Union[Unset, list[str]] = UNSET
+ if not isinstance(self.ignore, Unset):
+ ignore = self.ignore
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if ignore is not UNSET:
+ field_dict["ignore"] = ignore
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ ignore = cast(list[str], d.pop("ignore", UNSET))
+
+ config_watcher = cls(
+ ignore=ignore,
+ )
+
+ config_watcher.additional_properties = d
+ return config_watcher
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/error.py b/packages/sdk/python/src/opencode_ai/models/error.py
new file mode 100644
index 000000000..18c7ecf47
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/error.py
@@ -0,0 +1,65 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.error_data import ErrorData
+
+
+T = TypeVar("T", bound="Error")
+
+
+@_attrs_define
+class Error:
+ """
+ Attributes:
+ data (ErrorData):
+ """
+
+ data: "ErrorData"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ data = self.data.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "data": data,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.error_data import ErrorData
+
+ d = dict(src_dict)
+ data = ErrorData.from_dict(d.pop("data"))
+
+ error = cls(
+ data=data,
+ )
+
+ error.additional_properties = d
+ return error
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/error_data.py b/packages/sdk/python/src/opencode_ai/models/error_data.py
new file mode 100644
index 000000000..fddda9e2f
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/error_data.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ErrorData")
+
+
+@_attrs_define
+class ErrorData:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ error_data = cls()
+
+ error_data.additional_properties = d
+ return error_data
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_file_edited.py b/packages/sdk/python/src/opencode_ai/models/event_file_edited.py
new file mode 100644
index 000000000..2a784b829
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_file_edited.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_file_edited_properties import EventFileEditedProperties
+
+
+T = TypeVar("T", bound="EventFileEdited")
+
+
+@_attrs_define
+class EventFileEdited:
+ """
+ Attributes:
+ type_ (Literal['file.edited']):
+ properties (EventFileEditedProperties):
+ """
+
+ type_: Literal["file.edited"]
+ properties: "EventFileEditedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_file_edited_properties import EventFileEditedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["file.edited"], d.pop("type"))
+ if type_ != "file.edited":
+ raise ValueError(f"type must match const 'file.edited', got '{type_}'")
+
+ properties = EventFileEditedProperties.from_dict(d.pop("properties"))
+
+ event_file_edited = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_file_edited.additional_properties = d
+ return event_file_edited
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_file_edited_properties.py b/packages/sdk/python/src/opencode_ai/models/event_file_edited_properties.py
new file mode 100644
index 000000000..3fc250cef
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_file_edited_properties.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventFileEditedProperties")
+
+
+@_attrs_define
+class EventFileEditedProperties:
+ """
+ Attributes:
+ file (str):
+ """
+
+ file: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ file = self.file
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "file": file,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ file = d.pop("file")
+
+ event_file_edited_properties = cls(
+ file=file,
+ )
+
+ event_file_edited_properties.additional_properties = d
+ return event_file_edited_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_file_watcher_updated.py b/packages/sdk/python/src/opencode_ai/models/event_file_watcher_updated.py
new file mode 100644
index 000000000..869545c0a
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_file_watcher_updated.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_file_watcher_updated_properties import EventFileWatcherUpdatedProperties
+
+
+T = TypeVar("T", bound="EventFileWatcherUpdated")
+
+
+@_attrs_define
+class EventFileWatcherUpdated:
+ """
+ Attributes:
+ type_ (Literal['file.watcher.updated']):
+ properties (EventFileWatcherUpdatedProperties):
+ """
+
+ type_: Literal["file.watcher.updated"]
+ properties: "EventFileWatcherUpdatedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_file_watcher_updated_properties import EventFileWatcherUpdatedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["file.watcher.updated"], d.pop("type"))
+ if type_ != "file.watcher.updated":
+ raise ValueError(f"type must match const 'file.watcher.updated', got '{type_}'")
+
+ properties = EventFileWatcherUpdatedProperties.from_dict(d.pop("properties"))
+
+ event_file_watcher_updated = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_file_watcher_updated.additional_properties = d
+ return event_file_watcher_updated
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_file_watcher_updated_properties.py b/packages/sdk/python/src/opencode_ai/models/event_file_watcher_updated_properties.py
new file mode 100644
index 000000000..4694f7fc8
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_file_watcher_updated_properties.py
@@ -0,0 +1,82 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventFileWatcherUpdatedProperties")
+
+
+@_attrs_define
+class EventFileWatcherUpdatedProperties:
+ """
+ Attributes:
+ file (str):
+ event (Union[Literal['add'], Literal['change'], Literal['unlink']]):
+ """
+
+ file: str
+ event: Union[Literal["add"], Literal["change"], Literal["unlink"]]
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ file = self.file
+
+ event: Union[Literal["add"], Literal["change"], Literal["unlink"]]
+ event = self.event
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "file": file,
+ "event": event,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ file = d.pop("file")
+
+ def _parse_event(data: object) -> Union[Literal["add"], Literal["change"], Literal["unlink"]]:
+ event_type_0 = cast(Literal["add"], data)
+ if event_type_0 != "add":
+ raise ValueError(f"event_type_0 must match const 'add', got '{event_type_0}'")
+ return event_type_0
+ event_type_1 = cast(Literal["change"], data)
+ if event_type_1 != "change":
+ raise ValueError(f"event_type_1 must match const 'change', got '{event_type_1}'")
+ return event_type_1
+ event_type_2 = cast(Literal["unlink"], data)
+ if event_type_2 != "unlink":
+ raise ValueError(f"event_type_2 must match const 'unlink', got '{event_type_2}'")
+ return event_type_2
+
+ event = _parse_event(d.pop("event"))
+
+ event_file_watcher_updated_properties = cls(
+ file=file,
+ event=event,
+ )
+
+ event_file_watcher_updated_properties.additional_properties = d
+ return event_file_watcher_updated_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_ide_installed.py b/packages/sdk/python/src/opencode_ai/models/event_ide_installed.py
new file mode 100644
index 000000000..f30eeb37b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_ide_installed.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_ide_installed_properties import EventIdeInstalledProperties
+
+
+T = TypeVar("T", bound="EventIdeInstalled")
+
+
+@_attrs_define
+class EventIdeInstalled:
+ """
+ Attributes:
+ type_ (Literal['ide.installed']):
+ properties (EventIdeInstalledProperties):
+ """
+
+ type_: Literal["ide.installed"]
+ properties: "EventIdeInstalledProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_ide_installed_properties import EventIdeInstalledProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["ide.installed"], d.pop("type"))
+ if type_ != "ide.installed":
+ raise ValueError(f"type must match const 'ide.installed', got '{type_}'")
+
+ properties = EventIdeInstalledProperties.from_dict(d.pop("properties"))
+
+ event_ide_installed = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_ide_installed.additional_properties = d
+ return event_ide_installed
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_ide_installed_properties.py b/packages/sdk/python/src/opencode_ai/models/event_ide_installed_properties.py
new file mode 100644
index 000000000..6af180239
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_ide_installed_properties.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventIdeInstalledProperties")
+
+
+@_attrs_define
+class EventIdeInstalledProperties:
+ """
+ Attributes:
+ ide (str):
+ """
+
+ ide: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ ide = self.ide
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "ide": ide,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ ide = d.pop("ide")
+
+ event_ide_installed_properties = cls(
+ ide=ide,
+ )
+
+ event_ide_installed_properties.additional_properties = d
+ return event_ide_installed_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_installation_updated.py b/packages/sdk/python/src/opencode_ai/models/event_installation_updated.py
new file mode 100644
index 000000000..e2831ccb2
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_installation_updated.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_installation_updated_properties import EventInstallationUpdatedProperties
+
+
+T = TypeVar("T", bound="EventInstallationUpdated")
+
+
+@_attrs_define
+class EventInstallationUpdated:
+ """
+ Attributes:
+ type_ (Literal['installation.updated']):
+ properties (EventInstallationUpdatedProperties):
+ """
+
+ type_: Literal["installation.updated"]
+ properties: "EventInstallationUpdatedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_installation_updated_properties import EventInstallationUpdatedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["installation.updated"], d.pop("type"))
+ if type_ != "installation.updated":
+ raise ValueError(f"type must match const 'installation.updated', got '{type_}'")
+
+ properties = EventInstallationUpdatedProperties.from_dict(d.pop("properties"))
+
+ event_installation_updated = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_installation_updated.additional_properties = d
+ return event_installation_updated
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_installation_updated_properties.py b/packages/sdk/python/src/opencode_ai/models/event_installation_updated_properties.py
new file mode 100644
index 000000000..45c0523e9
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_installation_updated_properties.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventInstallationUpdatedProperties")
+
+
+@_attrs_define
+class EventInstallationUpdatedProperties:
+ """
+ Attributes:
+ version (str):
+ """
+
+ version: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ version = self.version
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "version": version,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ version = d.pop("version")
+
+ event_installation_updated_properties = cls(
+ version=version,
+ )
+
+ event_installation_updated_properties.additional_properties = d
+ return event_installation_updated_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_lsp_client_diagnostics.py b/packages/sdk/python/src/opencode_ai/models/event_lsp_client_diagnostics.py
new file mode 100644
index 000000000..d10dabec7
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_lsp_client_diagnostics.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_lsp_client_diagnostics_properties import EventLspClientDiagnosticsProperties
+
+
+T = TypeVar("T", bound="EventLspClientDiagnostics")
+
+
+@_attrs_define
+class EventLspClientDiagnostics:
+ """
+ Attributes:
+ type_ (Literal['lsp.client.diagnostics']):
+ properties (EventLspClientDiagnosticsProperties):
+ """
+
+ type_: Literal["lsp.client.diagnostics"]
+ properties: "EventLspClientDiagnosticsProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_lsp_client_diagnostics_properties import EventLspClientDiagnosticsProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["lsp.client.diagnostics"], d.pop("type"))
+ if type_ != "lsp.client.diagnostics":
+ raise ValueError(f"type must match const 'lsp.client.diagnostics', got '{type_}'")
+
+ properties = EventLspClientDiagnosticsProperties.from_dict(d.pop("properties"))
+
+ event_lsp_client_diagnostics = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_lsp_client_diagnostics.additional_properties = d
+ return event_lsp_client_diagnostics
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_lsp_client_diagnostics_properties.py b/packages/sdk/python/src/opencode_ai/models/event_lsp_client_diagnostics_properties.py
new file mode 100644
index 000000000..296555fba
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_lsp_client_diagnostics_properties.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventLspClientDiagnosticsProperties")
+
+
+@_attrs_define
+class EventLspClientDiagnosticsProperties:
+ """
+ Attributes:
+ server_id (str):
+ path (str):
+ """
+
+ server_id: str
+ path: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ server_id = self.server_id
+
+ path = self.path
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "serverID": server_id,
+ "path": path,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ server_id = d.pop("serverID")
+
+ path = d.pop("path")
+
+ event_lsp_client_diagnostics_properties = cls(
+ server_id=server_id,
+ path=path,
+ )
+
+ event_lsp_client_diagnostics_properties.additional_properties = d
+ return event_lsp_client_diagnostics_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_message_part_removed.py b/packages/sdk/python/src/opencode_ai/models/event_message_part_removed.py
new file mode 100644
index 000000000..3b26f3ec7
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_message_part_removed.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_message_part_removed_properties import EventMessagePartRemovedProperties
+
+
+T = TypeVar("T", bound="EventMessagePartRemoved")
+
+
+@_attrs_define
+class EventMessagePartRemoved:
+ """
+ Attributes:
+ type_ (Literal['message.part.removed']):
+ properties (EventMessagePartRemovedProperties):
+ """
+
+ type_: Literal["message.part.removed"]
+ properties: "EventMessagePartRemovedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_message_part_removed_properties import EventMessagePartRemovedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["message.part.removed"], d.pop("type"))
+ if type_ != "message.part.removed":
+ raise ValueError(f"type must match const 'message.part.removed', got '{type_}'")
+
+ properties = EventMessagePartRemovedProperties.from_dict(d.pop("properties"))
+
+ event_message_part_removed = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_message_part_removed.additional_properties = d
+ return event_message_part_removed
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_message_part_removed_properties.py b/packages/sdk/python/src/opencode_ai/models/event_message_part_removed_properties.py
new file mode 100644
index 000000000..957a4549d
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_message_part_removed_properties.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventMessagePartRemovedProperties")
+
+
+@_attrs_define
+class EventMessagePartRemovedProperties:
+ """
+ Attributes:
+ session_id (str):
+ message_id (str):
+ part_id (str):
+ """
+
+ session_id: str
+ message_id: str
+ part_id: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ part_id = self.part_id
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "sessionID": session_id,
+ "messageID": message_id,
+ "partID": part_id,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ part_id = d.pop("partID")
+
+ event_message_part_removed_properties = cls(
+ session_id=session_id,
+ message_id=message_id,
+ part_id=part_id,
+ )
+
+ event_message_part_removed_properties.additional_properties = d
+ return event_message_part_removed_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_message_part_updated.py b/packages/sdk/python/src/opencode_ai/models/event_message_part_updated.py
new file mode 100644
index 000000000..75e80bb85
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_message_part_updated.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_message_part_updated_properties import EventMessagePartUpdatedProperties
+
+
+T = TypeVar("T", bound="EventMessagePartUpdated")
+
+
+@_attrs_define
+class EventMessagePartUpdated:
+ """
+ Attributes:
+ type_ (Literal['message.part.updated']):
+ properties (EventMessagePartUpdatedProperties):
+ """
+
+ type_: Literal["message.part.updated"]
+ properties: "EventMessagePartUpdatedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_message_part_updated_properties import EventMessagePartUpdatedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["message.part.updated"], d.pop("type"))
+ if type_ != "message.part.updated":
+ raise ValueError(f"type must match const 'message.part.updated', got '{type_}'")
+
+ properties = EventMessagePartUpdatedProperties.from_dict(d.pop("properties"))
+
+ event_message_part_updated = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_message_part_updated.additional_properties = d
+ return event_message_part_updated
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_message_part_updated_properties.py b/packages/sdk/python/src/opencode_ai/models/event_message_part_updated_properties.py
new file mode 100644
index 000000000..ab8d1b2a9
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_message_part_updated_properties.py
@@ -0,0 +1,203 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.agent_part import AgentPart
+ from ..models.file_part import FilePart
+ from ..models.patch_part import PatchPart
+ from ..models.reasoning_part import ReasoningPart
+ from ..models.snapshot_part import SnapshotPart
+ from ..models.step_finish_part import StepFinishPart
+ from ..models.step_start_part import StepStartPart
+ from ..models.text_part import TextPart
+ from ..models.tool_part import ToolPart
+
+
+T = TypeVar("T", bound="EventMessagePartUpdatedProperties")
+
+
+@_attrs_define
+class EventMessagePartUpdatedProperties:
+ """
+ Attributes:
+ part (Union['AgentPart', 'FilePart', 'PatchPart', 'ReasoningPart', 'SnapshotPart', 'StepFinishPart',
+ 'StepStartPart', 'TextPart', 'ToolPart']):
+ """
+
+ part: Union[
+ "AgentPart",
+ "FilePart",
+ "PatchPart",
+ "ReasoningPart",
+ "SnapshotPart",
+ "StepFinishPart",
+ "StepStartPart",
+ "TextPart",
+ "ToolPart",
+ ]
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.file_part import FilePart
+ from ..models.patch_part import PatchPart
+ from ..models.reasoning_part import ReasoningPart
+ from ..models.snapshot_part import SnapshotPart
+ from ..models.step_finish_part import StepFinishPart
+ from ..models.step_start_part import StepStartPart
+ from ..models.text_part import TextPart
+ from ..models.tool_part import ToolPart
+
+ part: dict[str, Any]
+ if isinstance(self.part, TextPart):
+ part = self.part.to_dict()
+ elif isinstance(self.part, ReasoningPart):
+ part = self.part.to_dict()
+ elif isinstance(self.part, FilePart):
+ part = self.part.to_dict()
+ elif isinstance(self.part, ToolPart):
+ part = self.part.to_dict()
+ elif isinstance(self.part, StepStartPart):
+ part = self.part.to_dict()
+ elif isinstance(self.part, StepFinishPart):
+ part = self.part.to_dict()
+ elif isinstance(self.part, SnapshotPart):
+ part = self.part.to_dict()
+ elif isinstance(self.part, PatchPart):
+ part = self.part.to_dict()
+ else:
+ part = self.part.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "part": part,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.agent_part import AgentPart
+ from ..models.file_part import FilePart
+ from ..models.patch_part import PatchPart
+ from ..models.reasoning_part import ReasoningPart
+ from ..models.snapshot_part import SnapshotPart
+ from ..models.step_finish_part import StepFinishPart
+ from ..models.step_start_part import StepStartPart
+ from ..models.text_part import TextPart
+ from ..models.tool_part import ToolPart
+
+ d = dict(src_dict)
+
+ def _parse_part(
+ data: object,
+ ) -> Union[
+ "AgentPart",
+ "FilePart",
+ "PatchPart",
+ "ReasoningPart",
+ "SnapshotPart",
+ "StepFinishPart",
+ "StepStartPart",
+ "TextPart",
+ "ToolPart",
+ ]:
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_part_type_0 = TextPart.from_dict(data)
+
+ return componentsschemas_part_type_0
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_part_type_1 = ReasoningPart.from_dict(data)
+
+ return componentsschemas_part_type_1
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_part_type_2 = FilePart.from_dict(data)
+
+ return componentsschemas_part_type_2
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_part_type_3 = ToolPart.from_dict(data)
+
+ return componentsschemas_part_type_3
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_part_type_4 = StepStartPart.from_dict(data)
+
+ return componentsschemas_part_type_4
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_part_type_5 = StepFinishPart.from_dict(data)
+
+ return componentsschemas_part_type_5
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_part_type_6 = SnapshotPart.from_dict(data)
+
+ return componentsschemas_part_type_6
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_part_type_7 = PatchPart.from_dict(data)
+
+ return componentsschemas_part_type_7
+ except: # noqa: E722
+ pass
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_part_type_8 = AgentPart.from_dict(data)
+
+ return componentsschemas_part_type_8
+
+ part = _parse_part(d.pop("part"))
+
+ event_message_part_updated_properties = cls(
+ part=part,
+ )
+
+ event_message_part_updated_properties.additional_properties = d
+ return event_message_part_updated_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_message_removed.py b/packages/sdk/python/src/opencode_ai/models/event_message_removed.py
new file mode 100644
index 000000000..0be451235
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_message_removed.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_message_removed_properties import EventMessageRemovedProperties
+
+
+T = TypeVar("T", bound="EventMessageRemoved")
+
+
+@_attrs_define
+class EventMessageRemoved:
+ """
+ Attributes:
+ type_ (Literal['message.removed']):
+ properties (EventMessageRemovedProperties):
+ """
+
+ type_: Literal["message.removed"]
+ properties: "EventMessageRemovedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_message_removed_properties import EventMessageRemovedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["message.removed"], d.pop("type"))
+ if type_ != "message.removed":
+ raise ValueError(f"type must match const 'message.removed', got '{type_}'")
+
+ properties = EventMessageRemovedProperties.from_dict(d.pop("properties"))
+
+ event_message_removed = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_message_removed.additional_properties = d
+ return event_message_removed
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_message_removed_properties.py b/packages/sdk/python/src/opencode_ai/models/event_message_removed_properties.py
new file mode 100644
index 000000000..85446e963
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_message_removed_properties.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventMessageRemovedProperties")
+
+
+@_attrs_define
+class EventMessageRemovedProperties:
+ """
+ Attributes:
+ session_id (str):
+ message_id (str):
+ """
+
+ session_id: str
+ message_id: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "sessionID": session_id,
+ "messageID": message_id,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ event_message_removed_properties = cls(
+ session_id=session_id,
+ message_id=message_id,
+ )
+
+ event_message_removed_properties.additional_properties = d
+ return event_message_removed_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_message_updated.py b/packages/sdk/python/src/opencode_ai/models/event_message_updated.py
new file mode 100644
index 000000000..9a5a8c2ad
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_message_updated.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_message_updated_properties import EventMessageUpdatedProperties
+
+
+T = TypeVar("T", bound="EventMessageUpdated")
+
+
+@_attrs_define
+class EventMessageUpdated:
+ """
+ Attributes:
+ type_ (Literal['message.updated']):
+ properties (EventMessageUpdatedProperties):
+ """
+
+ type_: Literal["message.updated"]
+ properties: "EventMessageUpdatedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_message_updated_properties import EventMessageUpdatedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["message.updated"], d.pop("type"))
+ if type_ != "message.updated":
+ raise ValueError(f"type must match const 'message.updated', got '{type_}'")
+
+ properties = EventMessageUpdatedProperties.from_dict(d.pop("properties"))
+
+ event_message_updated = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_message_updated.additional_properties = d
+ return event_message_updated
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_message_updated_properties.py b/packages/sdk/python/src/opencode_ai/models/event_message_updated_properties.py
new file mode 100644
index 000000000..1ec6714e8
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_message_updated_properties.py
@@ -0,0 +1,89 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.assistant_message import AssistantMessage
+ from ..models.user_message import UserMessage
+
+
+T = TypeVar("T", bound="EventMessageUpdatedProperties")
+
+
+@_attrs_define
+class EventMessageUpdatedProperties:
+ """
+ Attributes:
+ info (Union['AssistantMessage', 'UserMessage']):
+ """
+
+ info: Union["AssistantMessage", "UserMessage"]
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.user_message import UserMessage
+
+ info: dict[str, Any]
+ if isinstance(self.info, UserMessage):
+ info = self.info.to_dict()
+ else:
+ info = self.info.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "info": info,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.assistant_message import AssistantMessage
+ from ..models.user_message import UserMessage
+
+ d = dict(src_dict)
+
+ def _parse_info(data: object) -> Union["AssistantMessage", "UserMessage"]:
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_message_type_0 = UserMessage.from_dict(data)
+
+ return componentsschemas_message_type_0
+ except: # noqa: E722
+ pass
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_message_type_1 = AssistantMessage.from_dict(data)
+
+ return componentsschemas_message_type_1
+
+ info = _parse_info(d.pop("info"))
+
+ event_message_updated_properties = cls(
+ info=info,
+ )
+
+ event_message_updated_properties.additional_properties = d
+ return event_message_updated_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_permission_replied.py b/packages/sdk/python/src/opencode_ai/models/event_permission_replied.py
new file mode 100644
index 000000000..4fdfa3f94
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_permission_replied.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_permission_replied_properties import EventPermissionRepliedProperties
+
+
+T = TypeVar("T", bound="EventPermissionReplied")
+
+
+@_attrs_define
+class EventPermissionReplied:
+ """
+ Attributes:
+ type_ (Literal['permission.replied']):
+ properties (EventPermissionRepliedProperties):
+ """
+
+ type_: Literal["permission.replied"]
+ properties: "EventPermissionRepliedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_permission_replied_properties import EventPermissionRepliedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["permission.replied"], d.pop("type"))
+ if type_ != "permission.replied":
+ raise ValueError(f"type must match const 'permission.replied', got '{type_}'")
+
+ properties = EventPermissionRepliedProperties.from_dict(d.pop("properties"))
+
+ event_permission_replied = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_permission_replied.additional_properties = d
+ return event_permission_replied
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_permission_replied_properties.py b/packages/sdk/python/src/opencode_ai/models/event_permission_replied_properties.py
new file mode 100644
index 000000000..483cf9508
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_permission_replied_properties.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventPermissionRepliedProperties")
+
+
+@_attrs_define
+class EventPermissionRepliedProperties:
+ """
+ Attributes:
+ session_id (str):
+ permission_id (str):
+ response (str):
+ """
+
+ session_id: str
+ permission_id: str
+ response: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ session_id = self.session_id
+
+ permission_id = self.permission_id
+
+ response = self.response
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "sessionID": session_id,
+ "permissionID": permission_id,
+ "response": response,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ session_id = d.pop("sessionID")
+
+ permission_id = d.pop("permissionID")
+
+ response = d.pop("response")
+
+ event_permission_replied_properties = cls(
+ session_id=session_id,
+ permission_id=permission_id,
+ response=response,
+ )
+
+ event_permission_replied_properties.additional_properties = d
+ return event_permission_replied_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_permission_updated.py b/packages/sdk/python/src/opencode_ai/models/event_permission_updated.py
new file mode 100644
index 000000000..8b8633358
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_permission_updated.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.permission import Permission
+
+
+T = TypeVar("T", bound="EventPermissionUpdated")
+
+
+@_attrs_define
+class EventPermissionUpdated:
+ """
+ Attributes:
+ type_ (Literal['permission.updated']):
+ properties (Permission):
+ """
+
+ type_: Literal["permission.updated"]
+ properties: "Permission"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.permission import Permission
+
+ d = dict(src_dict)
+ type_ = cast(Literal["permission.updated"], d.pop("type"))
+ if type_ != "permission.updated":
+ raise ValueError(f"type must match const 'permission.updated', got '{type_}'")
+
+ properties = Permission.from_dict(d.pop("properties"))
+
+ event_permission_updated = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_permission_updated.additional_properties = d
+ return event_permission_updated
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_server_connected.py b/packages/sdk/python/src/opencode_ai/models/event_server_connected.py
new file mode 100644
index 000000000..80393a580
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_server_connected.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_server_connected_properties import EventServerConnectedProperties
+
+
+T = TypeVar("T", bound="EventServerConnected")
+
+
+@_attrs_define
+class EventServerConnected:
+ """
+ Attributes:
+ type_ (Literal['server.connected']):
+ properties (EventServerConnectedProperties):
+ """
+
+ type_: Literal["server.connected"]
+ properties: "EventServerConnectedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_server_connected_properties import EventServerConnectedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["server.connected"], d.pop("type"))
+ if type_ != "server.connected":
+ raise ValueError(f"type must match const 'server.connected', got '{type_}'")
+
+ properties = EventServerConnectedProperties.from_dict(d.pop("properties"))
+
+ event_server_connected = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_server_connected.additional_properties = d
+ return event_server_connected
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_server_connected_properties.py b/packages/sdk/python/src/opencode_ai/models/event_server_connected_properties.py
new file mode 100644
index 000000000..1a0e9191a
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_server_connected_properties.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventServerConnectedProperties")
+
+
+@_attrs_define
+class EventServerConnectedProperties:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ event_server_connected_properties = cls()
+
+ event_server_connected_properties.additional_properties = d
+ return event_server_connected_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_session_compacted.py b/packages/sdk/python/src/opencode_ai/models/event_session_compacted.py
new file mode 100644
index 000000000..8d3cfc3a6
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_session_compacted.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_session_compacted_properties import EventSessionCompactedProperties
+
+
+T = TypeVar("T", bound="EventSessionCompacted")
+
+
+@_attrs_define
+class EventSessionCompacted:
+ """
+ Attributes:
+ type_ (Literal['session.compacted']):
+ properties (EventSessionCompactedProperties):
+ """
+
+ type_: Literal["session.compacted"]
+ properties: "EventSessionCompactedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_session_compacted_properties import EventSessionCompactedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["session.compacted"], d.pop("type"))
+ if type_ != "session.compacted":
+ raise ValueError(f"type must match const 'session.compacted', got '{type_}'")
+
+ properties = EventSessionCompactedProperties.from_dict(d.pop("properties"))
+
+ event_session_compacted = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_session_compacted.additional_properties = d
+ return event_session_compacted
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_session_compacted_properties.py b/packages/sdk/python/src/opencode_ai/models/event_session_compacted_properties.py
new file mode 100644
index 000000000..27b1c9455
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_session_compacted_properties.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventSessionCompactedProperties")
+
+
+@_attrs_define
+class EventSessionCompactedProperties:
+ """
+ Attributes:
+ session_id (str):
+ """
+
+ session_id: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ session_id = self.session_id
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "sessionID": session_id,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ session_id = d.pop("sessionID")
+
+ event_session_compacted_properties = cls(
+ session_id=session_id,
+ )
+
+ event_session_compacted_properties.additional_properties = d
+ return event_session_compacted_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_session_deleted.py b/packages/sdk/python/src/opencode_ai/models/event_session_deleted.py
new file mode 100644
index 000000000..3b39c834f
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_session_deleted.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_session_deleted_properties import EventSessionDeletedProperties
+
+
+T = TypeVar("T", bound="EventSessionDeleted")
+
+
+@_attrs_define
+class EventSessionDeleted:
+ """
+ Attributes:
+ type_ (Literal['session.deleted']):
+ properties (EventSessionDeletedProperties):
+ """
+
+ type_: Literal["session.deleted"]
+ properties: "EventSessionDeletedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_session_deleted_properties import EventSessionDeletedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["session.deleted"], d.pop("type"))
+ if type_ != "session.deleted":
+ raise ValueError(f"type must match const 'session.deleted', got '{type_}'")
+
+ properties = EventSessionDeletedProperties.from_dict(d.pop("properties"))
+
+ event_session_deleted = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_session_deleted.additional_properties = d
+ return event_session_deleted
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_session_deleted_properties.py b/packages/sdk/python/src/opencode_ai/models/event_session_deleted_properties.py
new file mode 100644
index 000000000..d630cc31c
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_session_deleted_properties.py
@@ -0,0 +1,65 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.session import Session
+
+
+T = TypeVar("T", bound="EventSessionDeletedProperties")
+
+
+@_attrs_define
+class EventSessionDeletedProperties:
+ """
+ Attributes:
+ info (Session):
+ """
+
+ info: "Session"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ info = self.info.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "info": info,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.session import Session
+
+ d = dict(src_dict)
+ info = Session.from_dict(d.pop("info"))
+
+ event_session_deleted_properties = cls(
+ info=info,
+ )
+
+ event_session_deleted_properties.additional_properties = d
+ return event_session_deleted_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_session_error.py b/packages/sdk/python/src/opencode_ai/models/event_session_error.py
new file mode 100644
index 000000000..eaa85e137
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_session_error.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_session_error_properties import EventSessionErrorProperties
+
+
+T = TypeVar("T", bound="EventSessionError")
+
+
+@_attrs_define
+class EventSessionError:
+ """
+ Attributes:
+ type_ (Literal['session.error']):
+ properties (EventSessionErrorProperties):
+ """
+
+ type_: Literal["session.error"]
+ properties: "EventSessionErrorProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_session_error_properties import EventSessionErrorProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["session.error"], d.pop("type"))
+ if type_ != "session.error":
+ raise ValueError(f"type must match const 'session.error', got '{type_}'")
+
+ properties = EventSessionErrorProperties.from_dict(d.pop("properties"))
+
+ event_session_error = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_session_error.additional_properties = d
+ return event_session_error
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_session_error_properties.py b/packages/sdk/python/src/opencode_ai/models/event_session_error_properties.py
new file mode 100644
index 000000000..420318de1
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_session_error_properties.py
@@ -0,0 +1,129 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.message_aborted_error import MessageAbortedError
+ from ..models.message_output_length_error import MessageOutputLengthError
+ from ..models.provider_auth_error import ProviderAuthError
+ from ..models.unknown_error import UnknownError
+
+
+T = TypeVar("T", bound="EventSessionErrorProperties")
+
+
+@_attrs_define
+class EventSessionErrorProperties:
+ """
+ Attributes:
+ session_id (Union[Unset, str]):
+ error (Union['MessageAbortedError', 'MessageOutputLengthError', 'ProviderAuthError', 'UnknownError', Unset]):
+ """
+
+ session_id: Union[Unset, str] = UNSET
+ error: Union["MessageAbortedError", "MessageOutputLengthError", "ProviderAuthError", "UnknownError", Unset] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.message_output_length_error import MessageOutputLengthError
+ from ..models.provider_auth_error import ProviderAuthError
+ from ..models.unknown_error import UnknownError
+
+ session_id = self.session_id
+
+ error: Union[Unset, dict[str, Any]]
+ if isinstance(self.error, Unset):
+ error = UNSET
+ elif isinstance(self.error, ProviderAuthError):
+ error = self.error.to_dict()
+ elif isinstance(self.error, UnknownError):
+ error = self.error.to_dict()
+ elif isinstance(self.error, MessageOutputLengthError):
+ error = self.error.to_dict()
+ else:
+ error = self.error.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update({})
+ if session_id is not UNSET:
+ field_dict["sessionID"] = session_id
+ if error is not UNSET:
+ field_dict["error"] = error
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.message_aborted_error import MessageAbortedError
+ from ..models.message_output_length_error import MessageOutputLengthError
+ from ..models.provider_auth_error import ProviderAuthError
+ from ..models.unknown_error import UnknownError
+
+ d = dict(src_dict)
+ session_id = d.pop("sessionID", UNSET)
+
+ def _parse_error(
+ data: object,
+ ) -> Union["MessageAbortedError", "MessageOutputLengthError", "ProviderAuthError", "UnknownError", Unset]:
+ if isinstance(data, Unset):
+ return data
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ error_type_0 = ProviderAuthError.from_dict(data)
+
+ return error_type_0
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ error_type_1 = UnknownError.from_dict(data)
+
+ return error_type_1
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ error_type_2 = MessageOutputLengthError.from_dict(data)
+
+ return error_type_2
+ except: # noqa: E722
+ pass
+ if not isinstance(data, dict):
+ raise TypeError()
+ error_type_3 = MessageAbortedError.from_dict(data)
+
+ return error_type_3
+
+ error = _parse_error(d.pop("error", UNSET))
+
+ event_session_error_properties = cls(
+ session_id=session_id,
+ error=error,
+ )
+
+ event_session_error_properties.additional_properties = d
+ return event_session_error_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_session_idle.py b/packages/sdk/python/src/opencode_ai/models/event_session_idle.py
new file mode 100644
index 000000000..d4b688abb
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_session_idle.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_session_idle_properties import EventSessionIdleProperties
+
+
+T = TypeVar("T", bound="EventSessionIdle")
+
+
+@_attrs_define
+class EventSessionIdle:
+ """
+ Attributes:
+ type_ (Literal['session.idle']):
+ properties (EventSessionIdleProperties):
+ """
+
+ type_: Literal["session.idle"]
+ properties: "EventSessionIdleProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_session_idle_properties import EventSessionIdleProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["session.idle"], d.pop("type"))
+ if type_ != "session.idle":
+ raise ValueError(f"type must match const 'session.idle', got '{type_}'")
+
+ properties = EventSessionIdleProperties.from_dict(d.pop("properties"))
+
+ event_session_idle = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_session_idle.additional_properties = d
+ return event_session_idle
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_session_idle_properties.py b/packages/sdk/python/src/opencode_ai/models/event_session_idle_properties.py
new file mode 100644
index 000000000..1224837e4
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_session_idle_properties.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="EventSessionIdleProperties")
+
+
+@_attrs_define
+class EventSessionIdleProperties:
+ """
+ Attributes:
+ session_id (str):
+ """
+
+ session_id: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ session_id = self.session_id
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "sessionID": session_id,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ session_id = d.pop("sessionID")
+
+ event_session_idle_properties = cls(
+ session_id=session_id,
+ )
+
+ event_session_idle_properties.additional_properties = d
+ return event_session_idle_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_session_updated.py b/packages/sdk/python/src/opencode_ai/models/event_session_updated.py
new file mode 100644
index 000000000..a99efb455
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_session_updated.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.event_session_updated_properties import EventSessionUpdatedProperties
+
+
+T = TypeVar("T", bound="EventSessionUpdated")
+
+
+@_attrs_define
+class EventSessionUpdated:
+ """
+ Attributes:
+ type_ (Literal['session.updated']):
+ properties (EventSessionUpdatedProperties):
+ """
+
+ type_: Literal["session.updated"]
+ properties: "EventSessionUpdatedProperties"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ properties = self.properties.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "properties": properties,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.event_session_updated_properties import EventSessionUpdatedProperties
+
+ d = dict(src_dict)
+ type_ = cast(Literal["session.updated"], d.pop("type"))
+ if type_ != "session.updated":
+ raise ValueError(f"type must match const 'session.updated', got '{type_}'")
+
+ properties = EventSessionUpdatedProperties.from_dict(d.pop("properties"))
+
+ event_session_updated = cls(
+ type_=type_,
+ properties=properties,
+ )
+
+ event_session_updated.additional_properties = d
+ return event_session_updated
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/event_session_updated_properties.py b/packages/sdk/python/src/opencode_ai/models/event_session_updated_properties.py
new file mode 100644
index 000000000..0f9e83e28
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/event_session_updated_properties.py
@@ -0,0 +1,65 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.session import Session
+
+
+T = TypeVar("T", bound="EventSessionUpdatedProperties")
+
+
+@_attrs_define
+class EventSessionUpdatedProperties:
+ """
+ Attributes:
+ info (Session):
+ """
+
+ info: "Session"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ info = self.info.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "info": info,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.session import Session
+
+ d = dict(src_dict)
+ info = Session.from_dict(d.pop("info"))
+
+ event_session_updated_properties = cls(
+ info=info,
+ )
+
+ event_session_updated_properties.additional_properties = d
+ return event_session_updated_properties
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/file.py b/packages/sdk/python/src/opencode_ai/models/file.py
new file mode 100644
index 000000000..c18c2feca
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file.py
@@ -0,0 +1,85 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..models.file_status import FileStatus
+
+T = TypeVar("T", bound="File")
+
+
+@_attrs_define
+class File:
+ """
+ Attributes:
+ path (str):
+ added (int):
+ removed (int):
+ status (FileStatus):
+ """
+
+ path: str
+ added: int
+ removed: int
+ status: FileStatus
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ path = self.path
+
+ added = self.added
+
+ removed = self.removed
+
+ status = self.status.value
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "path": path,
+ "added": added,
+ "removed": removed,
+ "status": status,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ path = d.pop("path")
+
+ added = d.pop("added")
+
+ removed = d.pop("removed")
+
+ status = FileStatus(d.pop("status"))
+
+ file = cls(
+ path=path,
+ added=added,
+ removed=removed,
+ status=status,
+ )
+
+ file.additional_properties = d
+ return file
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/file_content.py b/packages/sdk/python/src/opencode_ai/models/file_content.py
new file mode 100644
index 000000000..2654d678f
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file_content.py
@@ -0,0 +1,92 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.file_content_patch import FileContentPatch
+
+
+T = TypeVar("T", bound="FileContent")
+
+
+@_attrs_define
+class FileContent:
+ """
+ Attributes:
+ content (str):
+ diff (Union[Unset, str]):
+ patch (Union[Unset, FileContentPatch]):
+ """
+
+ content: str
+ diff: Union[Unset, str] = UNSET
+ patch: Union[Unset, "FileContentPatch"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ content = self.content
+
+ diff = self.diff
+
+ patch: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.patch, Unset):
+ patch = self.patch.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "content": content,
+ }
+ )
+ if diff is not UNSET:
+ field_dict["diff"] = diff
+ if patch is not UNSET:
+ field_dict["patch"] = patch
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.file_content_patch import FileContentPatch
+
+ d = dict(src_dict)
+ content = d.pop("content")
+
+ diff = d.pop("diff", UNSET)
+
+ _patch = d.pop("patch", UNSET)
+ patch: Union[Unset, FileContentPatch]
+ if isinstance(_patch, Unset):
+ patch = UNSET
+ else:
+ patch = FileContentPatch.from_dict(_patch)
+
+ file_content = cls(
+ content=content,
+ diff=diff,
+ patch=patch,
+ )
+
+ file_content.additional_properties = d
+ return file_content
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/file_content_patch.py b/packages/sdk/python/src/opencode_ai/models/file_content_patch.py
new file mode 100644
index 000000000..01d29ebf6
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file_content_patch.py
@@ -0,0 +1,118 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.file_content_patch_hunks_item import FileContentPatchHunksItem
+
+
+T = TypeVar("T", bound="FileContentPatch")
+
+
+@_attrs_define
+class FileContentPatch:
+ """
+ Attributes:
+ old_file_name (str):
+ new_file_name (str):
+ hunks (list['FileContentPatchHunksItem']):
+ old_header (Union[Unset, str]):
+ new_header (Union[Unset, str]):
+ index (Union[Unset, str]):
+ """
+
+ old_file_name: str
+ new_file_name: str
+ hunks: list["FileContentPatchHunksItem"]
+ old_header: Union[Unset, str] = UNSET
+ new_header: Union[Unset, str] = UNSET
+ index: Union[Unset, str] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ old_file_name = self.old_file_name
+
+ new_file_name = self.new_file_name
+
+ hunks = []
+ for hunks_item_data in self.hunks:
+ hunks_item = hunks_item_data.to_dict()
+ hunks.append(hunks_item)
+
+ old_header = self.old_header
+
+ new_header = self.new_header
+
+ index = self.index
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "oldFileName": old_file_name,
+ "newFileName": new_file_name,
+ "hunks": hunks,
+ }
+ )
+ if old_header is not UNSET:
+ field_dict["oldHeader"] = old_header
+ if new_header is not UNSET:
+ field_dict["newHeader"] = new_header
+ if index is not UNSET:
+ field_dict["index"] = index
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.file_content_patch_hunks_item import FileContentPatchHunksItem
+
+ d = dict(src_dict)
+ old_file_name = d.pop("oldFileName")
+
+ new_file_name = d.pop("newFileName")
+
+ hunks = []
+ _hunks = d.pop("hunks")
+ for hunks_item_data in _hunks:
+ hunks_item = FileContentPatchHunksItem.from_dict(hunks_item_data)
+
+ hunks.append(hunks_item)
+
+ old_header = d.pop("oldHeader", UNSET)
+
+ new_header = d.pop("newHeader", UNSET)
+
+ index = d.pop("index", UNSET)
+
+ file_content_patch = cls(
+ old_file_name=old_file_name,
+ new_file_name=new_file_name,
+ hunks=hunks,
+ old_header=old_header,
+ new_header=new_header,
+ index=index,
+ )
+
+ file_content_patch.additional_properties = d
+ return file_content_patch
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/file_content_patch_hunks_item.py b/packages/sdk/python/src/opencode_ai/models/file_content_patch_hunks_item.py
new file mode 100644
index 000000000..b17688fad
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file_content_patch_hunks_item.py
@@ -0,0 +1,91 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="FileContentPatchHunksItem")
+
+
+@_attrs_define
+class FileContentPatchHunksItem:
+ """
+ Attributes:
+ old_start (float):
+ old_lines (float):
+ new_start (float):
+ new_lines (float):
+ lines (list[str]):
+ """
+
+ old_start: float
+ old_lines: float
+ new_start: float
+ new_lines: float
+ lines: list[str]
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ old_start = self.old_start
+
+ old_lines = self.old_lines
+
+ new_start = self.new_start
+
+ new_lines = self.new_lines
+
+ lines = self.lines
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "oldStart": old_start,
+ "oldLines": old_lines,
+ "newStart": new_start,
+ "newLines": new_lines,
+ "lines": lines,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ old_start = d.pop("oldStart")
+
+ old_lines = d.pop("oldLines")
+
+ new_start = d.pop("newStart")
+
+ new_lines = d.pop("newLines")
+
+ lines = cast(list[str], d.pop("lines"))
+
+ file_content_patch_hunks_item = cls(
+ old_start=old_start,
+ old_lines=old_lines,
+ new_start=new_start,
+ new_lines=new_lines,
+ lines=lines,
+ )
+
+ file_content_patch_hunks_item.additional_properties = d
+ return file_content_patch_hunks_item
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/file_node.py b/packages/sdk/python/src/opencode_ai/models/file_node.py
new file mode 100644
index 000000000..feb075f8f
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file_node.py
@@ -0,0 +1,93 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..models.file_node_type import FileNodeType
+
+T = TypeVar("T", bound="FileNode")
+
+
+@_attrs_define
+class FileNode:
+ """
+ Attributes:
+ name (str):
+ path (str):
+ absolute (str):
+ type_ (FileNodeType):
+ ignored (bool):
+ """
+
+ name: str
+ path: str
+ absolute: str
+ type_: FileNodeType
+ ignored: bool
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ name = self.name
+
+ path = self.path
+
+ absolute = self.absolute
+
+ type_ = self.type_.value
+
+ ignored = self.ignored
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "name": name,
+ "path": path,
+ "absolute": absolute,
+ "type": type_,
+ "ignored": ignored,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ name = d.pop("name")
+
+ path = d.pop("path")
+
+ absolute = d.pop("absolute")
+
+ type_ = FileNodeType(d.pop("type"))
+
+ ignored = d.pop("ignored")
+
+ file_node = cls(
+ name=name,
+ path=path,
+ absolute=absolute,
+ type_=type_,
+ ignored=ignored,
+ )
+
+ file_node.additional_properties = d
+ return file_node
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/file_node_type.py b/packages/sdk/python/src/opencode_ai/models/file_node_type.py
new file mode 100644
index 000000000..8fb88ffe1
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file_node_type.py
@@ -0,0 +1,9 @@
+from enum import Enum
+
+
+class FileNodeType(str, Enum):
+ DIRECTORY = "directory"
+ FILE = "file"
+
+ def __str__(self) -> str:
+ return str(self.value)
diff --git a/packages/sdk/python/src/opencode_ai/models/file_part.py b/packages/sdk/python/src/opencode_ai/models/file_part.py
new file mode 100644
index 000000000..aea82b97c
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file_part.py
@@ -0,0 +1,154 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.file_source import FileSource
+ from ..models.symbol_source import SymbolSource
+
+
+T = TypeVar("T", bound="FilePart")
+
+
+@_attrs_define
+class FilePart:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ message_id (str):
+ type_ (Literal['file']):
+ mime (str):
+ url (str):
+ filename (Union[Unset, str]):
+ source (Union['FileSource', 'SymbolSource', Unset]):
+ """
+
+ id: str
+ session_id: str
+ message_id: str
+ type_: Literal["file"]
+ mime: str
+ url: str
+ filename: Union[Unset, str] = UNSET
+ source: Union["FileSource", "SymbolSource", Unset] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.file_source import FileSource
+
+ id = self.id
+
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ type_ = self.type_
+
+ mime = self.mime
+
+ url = self.url
+
+ filename = self.filename
+
+ source: Union[Unset, dict[str, Any]]
+ if isinstance(self.source, Unset):
+ source = UNSET
+ elif isinstance(self.source, FileSource):
+ source = self.source.to_dict()
+ else:
+ source = self.source.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "messageID": message_id,
+ "type": type_,
+ "mime": mime,
+ "url": url,
+ }
+ )
+ if filename is not UNSET:
+ field_dict["filename"] = filename
+ if source is not UNSET:
+ field_dict["source"] = source
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.file_source import FileSource
+ from ..models.symbol_source import SymbolSource
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ type_ = cast(Literal["file"], d.pop("type"))
+ if type_ != "file":
+ raise ValueError(f"type must match const 'file', got '{type_}'")
+
+ mime = d.pop("mime")
+
+ url = d.pop("url")
+
+ filename = d.pop("filename", UNSET)
+
+ def _parse_source(data: object) -> Union["FileSource", "SymbolSource", Unset]:
+ if isinstance(data, Unset):
+ return data
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_file_part_source_type_0 = FileSource.from_dict(data)
+
+ return componentsschemas_file_part_source_type_0
+ except: # noqa: E722
+ pass
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_file_part_source_type_1 = SymbolSource.from_dict(data)
+
+ return componentsschemas_file_part_source_type_1
+
+ source = _parse_source(d.pop("source", UNSET))
+
+ file_part = cls(
+ id=id,
+ session_id=session_id,
+ message_id=message_id,
+ type_=type_,
+ mime=mime,
+ url=url,
+ filename=filename,
+ source=source,
+ )
+
+ file_part.additional_properties = d
+ return file_part
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/file_part_input.py b/packages/sdk/python/src/opencode_ai/models/file_part_input.py
new file mode 100644
index 000000000..0bebb3cb5
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file_part_input.py
@@ -0,0 +1,139 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.file_source import FileSource
+ from ..models.symbol_source import SymbolSource
+
+
+T = TypeVar("T", bound="FilePartInput")
+
+
+@_attrs_define
+class FilePartInput:
+ """
+ Attributes:
+ type_ (Literal['file']):
+ mime (str):
+ url (str):
+ id (Union[Unset, str]):
+ filename (Union[Unset, str]):
+ source (Union['FileSource', 'SymbolSource', Unset]):
+ """
+
+ type_: Literal["file"]
+ mime: str
+ url: str
+ id: Union[Unset, str] = UNSET
+ filename: Union[Unset, str] = UNSET
+ source: Union["FileSource", "SymbolSource", Unset] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.file_source import FileSource
+
+ type_ = self.type_
+
+ mime = self.mime
+
+ url = self.url
+
+ id = self.id
+
+ filename = self.filename
+
+ source: Union[Unset, dict[str, Any]]
+ if isinstance(self.source, Unset):
+ source = UNSET
+ elif isinstance(self.source, FileSource):
+ source = self.source.to_dict()
+ else:
+ source = self.source.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "mime": mime,
+ "url": url,
+ }
+ )
+ if id is not UNSET:
+ field_dict["id"] = id
+ if filename is not UNSET:
+ field_dict["filename"] = filename
+ if source is not UNSET:
+ field_dict["source"] = source
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.file_source import FileSource
+ from ..models.symbol_source import SymbolSource
+
+ d = dict(src_dict)
+ type_ = cast(Literal["file"], d.pop("type"))
+ if type_ != "file":
+ raise ValueError(f"type must match const 'file', got '{type_}'")
+
+ mime = d.pop("mime")
+
+ url = d.pop("url")
+
+ id = d.pop("id", UNSET)
+
+ filename = d.pop("filename", UNSET)
+
+ def _parse_source(data: object) -> Union["FileSource", "SymbolSource", Unset]:
+ if isinstance(data, Unset):
+ return data
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_file_part_source_type_0 = FileSource.from_dict(data)
+
+ return componentsschemas_file_part_source_type_0
+ except: # noqa: E722
+ pass
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_file_part_source_type_1 = SymbolSource.from_dict(data)
+
+ return componentsschemas_file_part_source_type_1
+
+ source = _parse_source(d.pop("source", UNSET))
+
+ file_part_input = cls(
+ type_=type_,
+ mime=mime,
+ url=url,
+ id=id,
+ filename=filename,
+ source=source,
+ )
+
+ file_part_input.additional_properties = d
+ return file_part_input
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/file_part_source_text.py b/packages/sdk/python/src/opencode_ai/models/file_part_source_text.py
new file mode 100644
index 000000000..b5a3a7f48
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file_part_source_text.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="FilePartSourceText")
+
+
+@_attrs_define
+class FilePartSourceText:
+ """
+ Attributes:
+ value (str):
+ start (int):
+ end (int):
+ """
+
+ value: str
+ start: int
+ end: int
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ value = self.value
+
+ start = self.start
+
+ end = self.end
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "value": value,
+ "start": start,
+ "end": end,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ value = d.pop("value")
+
+ start = d.pop("start")
+
+ end = d.pop("end")
+
+ file_part_source_text = cls(
+ value=value,
+ start=start,
+ end=end,
+ )
+
+ file_part_source_text.additional_properties = d
+ return file_part_source_text
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/file_source.py b/packages/sdk/python/src/opencode_ai/models/file_source.py
new file mode 100644
index 000000000..a4c64ff74
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file_source.py
@@ -0,0 +1,83 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.file_part_source_text import FilePartSourceText
+
+
+T = TypeVar("T", bound="FileSource")
+
+
+@_attrs_define
+class FileSource:
+ """
+ Attributes:
+ text (FilePartSourceText):
+ type_ (Literal['file']):
+ path (str):
+ """
+
+ text: "FilePartSourceText"
+ type_: Literal["file"]
+ path: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ text = self.text.to_dict()
+
+ type_ = self.type_
+
+ path = self.path
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "text": text,
+ "type": type_,
+ "path": path,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.file_part_source_text import FilePartSourceText
+
+ d = dict(src_dict)
+ text = FilePartSourceText.from_dict(d.pop("text"))
+
+ type_ = cast(Literal["file"], d.pop("type"))
+ if type_ != "file":
+ raise ValueError(f"type must match const 'file', got '{type_}'")
+
+ path = d.pop("path")
+
+ file_source = cls(
+ text=text,
+ type_=type_,
+ path=path,
+ )
+
+ file_source.additional_properties = d
+ return file_source
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/file_status.py b/packages/sdk/python/src/opencode_ai/models/file_status.py
new file mode 100644
index 000000000..54d84b84d
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/file_status.py
@@ -0,0 +1,10 @@
+from enum import Enum
+
+
+class FileStatus(str, Enum):
+ ADDED = "added"
+ DELETED = "deleted"
+ MODIFIED = "modified"
+
+ def __str__(self) -> str:
+ return str(self.value)
diff --git a/packages/sdk/python/src/opencode_ai/models/keybinds_config.py b/packages/sdk/python/src/opencode_ai/models/keybinds_config.py
new file mode 100644
index 000000000..05053206d
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/keybinds_config.py
@@ -0,0 +1,474 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="KeybindsConfig")
+
+
+@_attrs_define
+class KeybindsConfig:
+ """Custom keybind configurations
+
+ Attributes:
+ leader (Union[Unset, str]): Leader key for keybind combinations Default: 'ctrl+x'.
+ app_help (Union[Unset, str]): Show help dialog Default: '<leader>h'.
+ app_exit (Union[Unset, str]): Exit the application Default: 'ctrl+c,<leader>q'.
+ editor_open (Union[Unset, str]): Open external editor Default: '<leader>e'.
+ theme_list (Union[Unset, str]): List available themes Default: '<leader>t'.
+ project_init (Union[Unset, str]): Create/update AGENTS.md Default: '<leader>i'.
+ tool_details (Union[Unset, str]): Toggle tool details Default: '<leader>d'.
+ thinking_blocks (Union[Unset, str]): Toggle thinking blocks Default: '<leader>b'.
+ session_export (Union[Unset, str]): Export session to editor Default: '<leader>x'.
+ session_new (Union[Unset, str]): Create a new session Default: '<leader>n'.
+ session_list (Union[Unset, str]): List all sessions Default: '<leader>l'.
+ session_timeline (Union[Unset, str]): Show session timeline Default: '<leader>g'.
+ session_share (Union[Unset, str]): Share current session Default: '<leader>s'.
+ session_unshare (Union[Unset, str]): Unshare current session Default: 'none'.
+ session_interrupt (Union[Unset, str]): Interrupt current session Default: 'esc'.
+ session_compact (Union[Unset, str]): Compact the session Default: '<leader>c'.
+ session_child_cycle (Union[Unset, str]): Cycle to next child session Default: 'ctrl+right'.
+ session_child_cycle_reverse (Union[Unset, str]): Cycle to previous child session Default: 'ctrl+left'.
+ messages_page_up (Union[Unset, str]): Scroll messages up by one page Default: 'pgup'.
+ messages_page_down (Union[Unset, str]): Scroll messages down by one page Default: 'pgdown'.
+ messages_half_page_up (Union[Unset, str]): Scroll messages up by half page Default: 'ctrl+alt+u'.
+ messages_half_page_down (Union[Unset, str]): Scroll messages down by half page Default: 'ctrl+alt+d'.
+ messages_first (Union[Unset, str]): Navigate to first message Default: 'ctrl+g'.
+ messages_last (Union[Unset, str]): Navigate to last message Default: 'ctrl+alt+g'.
+ messages_copy (Union[Unset, str]): Copy message Default: '<leader>y'.
+ messages_undo (Union[Unset, str]): Undo message Default: '<leader>u'.
+ messages_redo (Union[Unset, str]): Redo message Default: '<leader>r'.
+ model_list (Union[Unset, str]): List available models Default: '<leader>m'.
+ model_cycle_recent (Union[Unset, str]): Next recent model Default: 'f2'.
+ model_cycle_recent_reverse (Union[Unset, str]): Previous recent model Default: 'shift+f2'.
+ agent_list (Union[Unset, str]): List agents Default: '<leader>a'.
+ agent_cycle (Union[Unset, str]): Next agent Default: 'tab'.
+ agent_cycle_reverse (Union[Unset, str]): Previous agent Default: 'shift+tab'.
+ input_clear (Union[Unset, str]): Clear input field Default: 'ctrl+c'.
+ input_paste (Union[Unset, str]): Paste from clipboard Default: 'ctrl+v'.
+ input_submit (Union[Unset, str]): Submit input Default: 'enter'.
+ input_newline (Union[Unset, str]): Insert newline in input Default: 'shift+enter,ctrl+j'.
+ switch_mode (Union[Unset, str]): @deprecated use agent_cycle. Next mode Default: 'none'.
+ switch_mode_reverse (Union[Unset, str]): @deprecated use agent_cycle_reverse. Previous mode Default: 'none'.
+ switch_agent (Union[Unset, str]): @deprecated use agent_cycle. Next agent Default: 'tab'.
+ switch_agent_reverse (Union[Unset, str]): @deprecated use agent_cycle_reverse. Previous agent Default:
+ 'shift+tab'.
+ file_list (Union[Unset, str]): @deprecated Currently not available. List files Default: 'none'.
+ file_close (Union[Unset, str]): @deprecated Close file Default: 'none'.
+ file_search (Union[Unset, str]): @deprecated Search file Default: 'none'.
+ file_diff_toggle (Union[Unset, str]): @deprecated Split/unified diff Default: 'none'.
+ messages_previous (Union[Unset, str]): @deprecated Navigate to previous message Default: 'none'.
+ messages_next (Union[Unset, str]): @deprecated Navigate to next message Default: 'none'.
+ messages_layout_toggle (Union[Unset, str]): @deprecated Toggle layout Default: 'none'.
+ messages_revert (Union[Unset, str]): @deprecated use messages_undo. Revert message Default: 'none'.
+ """
+
+ leader: Union[Unset, str] = "ctrl+x"
+ app_help: Union[Unset, str] = "<leader>h"
+ app_exit: Union[Unset, str] = "ctrl+c,<leader>q"
+ editor_open: Union[Unset, str] = "<leader>e"
+ theme_list: Union[Unset, str] = "<leader>t"
+ project_init: Union[Unset, str] = "<leader>i"
+ tool_details: Union[Unset, str] = "<leader>d"
+ thinking_blocks: Union[Unset, str] = "<leader>b"
+ session_export: Union[Unset, str] = "<leader>x"
+ session_new: Union[Unset, str] = "<leader>n"
+ session_list: Union[Unset, str] = "<leader>l"
+ session_timeline: Union[Unset, str] = "<leader>g"
+ session_share: Union[Unset, str] = "<leader>s"
+ session_unshare: Union[Unset, str] = "none"
+ session_interrupt: Union[Unset, str] = "esc"
+ session_compact: Union[Unset, str] = "<leader>c"
+ session_child_cycle: Union[Unset, str] = "ctrl+right"
+ session_child_cycle_reverse: Union[Unset, str] = "ctrl+left"
+ messages_page_up: Union[Unset, str] = "pgup"
+ messages_page_down: Union[Unset, str] = "pgdown"
+ messages_half_page_up: Union[Unset, str] = "ctrl+alt+u"
+ messages_half_page_down: Union[Unset, str] = "ctrl+alt+d"
+ messages_first: Union[Unset, str] = "ctrl+g"
+ messages_last: Union[Unset, str] = "ctrl+alt+g"
+ messages_copy: Union[Unset, str] = "<leader>y"
+ messages_undo: Union[Unset, str] = "<leader>u"
+ messages_redo: Union[Unset, str] = "<leader>r"
+ model_list: Union[Unset, str] = "<leader>m"
+ model_cycle_recent: Union[Unset, str] = "f2"
+ model_cycle_recent_reverse: Union[Unset, str] = "shift+f2"
+ agent_list: Union[Unset, str] = "<leader>a"
+ agent_cycle: Union[Unset, str] = "tab"
+ agent_cycle_reverse: Union[Unset, str] = "shift+tab"
+ input_clear: Union[Unset, str] = "ctrl+c"
+ input_paste: Union[Unset, str] = "ctrl+v"
+ input_submit: Union[Unset, str] = "enter"
+ input_newline: Union[Unset, str] = "shift+enter,ctrl+j"
+ switch_mode: Union[Unset, str] = "none"
+ switch_mode_reverse: Union[Unset, str] = "none"
+ switch_agent: Union[Unset, str] = "tab"
+ switch_agent_reverse: Union[Unset, str] = "shift+tab"
+ file_list: Union[Unset, str] = "none"
+ file_close: Union[Unset, str] = "none"
+ file_search: Union[Unset, str] = "none"
+ file_diff_toggle: Union[Unset, str] = "none"
+ messages_previous: Union[Unset, str] = "none"
+ messages_next: Union[Unset, str] = "none"
+ messages_layout_toggle: Union[Unset, str] = "none"
+ messages_revert: Union[Unset, str] = "none"
+
+ def to_dict(self) -> dict[str, Any]:
+ leader = self.leader
+
+ app_help = self.app_help
+
+ app_exit = self.app_exit
+
+ editor_open = self.editor_open
+
+ theme_list = self.theme_list
+
+ project_init = self.project_init
+
+ tool_details = self.tool_details
+
+ thinking_blocks = self.thinking_blocks
+
+ session_export = self.session_export
+
+ session_new = self.session_new
+
+ session_list = self.session_list
+
+ session_timeline = self.session_timeline
+
+ session_share = self.session_share
+
+ session_unshare = self.session_unshare
+
+ session_interrupt = self.session_interrupt
+
+ session_compact = self.session_compact
+
+ session_child_cycle = self.session_child_cycle
+
+ session_child_cycle_reverse = self.session_child_cycle_reverse
+
+ messages_page_up = self.messages_page_up
+
+ messages_page_down = self.messages_page_down
+
+ messages_half_page_up = self.messages_half_page_up
+
+ messages_half_page_down = self.messages_half_page_down
+
+ messages_first = self.messages_first
+
+ messages_last = self.messages_last
+
+ messages_copy = self.messages_copy
+
+ messages_undo = self.messages_undo
+
+ messages_redo = self.messages_redo
+
+ model_list = self.model_list
+
+ model_cycle_recent = self.model_cycle_recent
+
+ model_cycle_recent_reverse = self.model_cycle_recent_reverse
+
+ agent_list = self.agent_list
+
+ agent_cycle = self.agent_cycle
+
+ agent_cycle_reverse = self.agent_cycle_reverse
+
+ input_clear = self.input_clear
+
+ input_paste = self.input_paste
+
+ input_submit = self.input_submit
+
+ input_newline = self.input_newline
+
+ switch_mode = self.switch_mode
+
+ switch_mode_reverse = self.switch_mode_reverse
+
+ switch_agent = self.switch_agent
+
+ switch_agent_reverse = self.switch_agent_reverse
+
+ file_list = self.file_list
+
+ file_close = self.file_close
+
+ file_search = self.file_search
+
+ file_diff_toggle = self.file_diff_toggle
+
+ messages_previous = self.messages_previous
+
+ messages_next = self.messages_next
+
+ messages_layout_toggle = self.messages_layout_toggle
+
+ messages_revert = self.messages_revert
+
+ field_dict: dict[str, Any] = {}
+
+ field_dict.update({})
+ if leader is not UNSET:
+ field_dict["leader"] = leader
+ if app_help is not UNSET:
+ field_dict["app_help"] = app_help
+ if app_exit is not UNSET:
+ field_dict["app_exit"] = app_exit
+ if editor_open is not UNSET:
+ field_dict["editor_open"] = editor_open
+ if theme_list is not UNSET:
+ field_dict["theme_list"] = theme_list
+ if project_init is not UNSET:
+ field_dict["project_init"] = project_init
+ if tool_details is not UNSET:
+ field_dict["tool_details"] = tool_details
+ if thinking_blocks is not UNSET:
+ field_dict["thinking_blocks"] = thinking_blocks
+ if session_export is not UNSET:
+ field_dict["session_export"] = session_export
+ if session_new is not UNSET:
+ field_dict["session_new"] = session_new
+ if session_list is not UNSET:
+ field_dict["session_list"] = session_list
+ if session_timeline is not UNSET:
+ field_dict["session_timeline"] = session_timeline
+ if session_share is not UNSET:
+ field_dict["session_share"] = session_share
+ if session_unshare is not UNSET:
+ field_dict["session_unshare"] = session_unshare
+ if session_interrupt is not UNSET:
+ field_dict["session_interrupt"] = session_interrupt
+ if session_compact is not UNSET:
+ field_dict["session_compact"] = session_compact
+ if session_child_cycle is not UNSET:
+ field_dict["session_child_cycle"] = session_child_cycle
+ if session_child_cycle_reverse is not UNSET:
+ field_dict["session_child_cycle_reverse"] = session_child_cycle_reverse
+ if messages_page_up is not UNSET:
+ field_dict["messages_page_up"] = messages_page_up
+ if messages_page_down is not UNSET:
+ field_dict["messages_page_down"] = messages_page_down
+ if messages_half_page_up is not UNSET:
+ field_dict["messages_half_page_up"] = messages_half_page_up
+ if messages_half_page_down is not UNSET:
+ field_dict["messages_half_page_down"] = messages_half_page_down
+ if messages_first is not UNSET:
+ field_dict["messages_first"] = messages_first
+ if messages_last is not UNSET:
+ field_dict["messages_last"] = messages_last
+ if messages_copy is not UNSET:
+ field_dict["messages_copy"] = messages_copy
+ if messages_undo is not UNSET:
+ field_dict["messages_undo"] = messages_undo
+ if messages_redo is not UNSET:
+ field_dict["messages_redo"] = messages_redo
+ if model_list is not UNSET:
+ field_dict["model_list"] = model_list
+ if model_cycle_recent is not UNSET:
+ field_dict["model_cycle_recent"] = model_cycle_recent
+ if model_cycle_recent_reverse is not UNSET:
+ field_dict["model_cycle_recent_reverse"] = model_cycle_recent_reverse
+ if agent_list is not UNSET:
+ field_dict["agent_list"] = agent_list
+ if agent_cycle is not UNSET:
+ field_dict["agent_cycle"] = agent_cycle
+ if agent_cycle_reverse is not UNSET:
+ field_dict["agent_cycle_reverse"] = agent_cycle_reverse
+ if input_clear is not UNSET:
+ field_dict["input_clear"] = input_clear
+ if input_paste is not UNSET:
+ field_dict["input_paste"] = input_paste
+ if input_submit is not UNSET:
+ field_dict["input_submit"] = input_submit
+ if input_newline is not UNSET:
+ field_dict["input_newline"] = input_newline
+ if switch_mode is not UNSET:
+ field_dict["switch_mode"] = switch_mode
+ if switch_mode_reverse is not UNSET:
+ field_dict["switch_mode_reverse"] = switch_mode_reverse
+ if switch_agent is not UNSET:
+ field_dict["switch_agent"] = switch_agent
+ if switch_agent_reverse is not UNSET:
+ field_dict["switch_agent_reverse"] = switch_agent_reverse
+ if file_list is not UNSET:
+ field_dict["file_list"] = file_list
+ if file_close is not UNSET:
+ field_dict["file_close"] = file_close
+ if file_search is not UNSET:
+ field_dict["file_search"] = file_search
+ if file_diff_toggle is not UNSET:
+ field_dict["file_diff_toggle"] = file_diff_toggle
+ if messages_previous is not UNSET:
+ field_dict["messages_previous"] = messages_previous
+ if messages_next is not UNSET:
+ field_dict["messages_next"] = messages_next
+ if messages_layout_toggle is not UNSET:
+ field_dict["messages_layout_toggle"] = messages_layout_toggle
+ if messages_revert is not UNSET:
+ field_dict["messages_revert"] = messages_revert
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ leader = d.pop("leader", UNSET)
+
+ app_help = d.pop("app_help", UNSET)
+
+ app_exit = d.pop("app_exit", UNSET)
+
+ editor_open = d.pop("editor_open", UNSET)
+
+ theme_list = d.pop("theme_list", UNSET)
+
+ project_init = d.pop("project_init", UNSET)
+
+ tool_details = d.pop("tool_details", UNSET)
+
+ thinking_blocks = d.pop("thinking_blocks", UNSET)
+
+ session_export = d.pop("session_export", UNSET)
+
+ session_new = d.pop("session_new", UNSET)
+
+ session_list = d.pop("session_list", UNSET)
+
+ session_timeline = d.pop("session_timeline", UNSET)
+
+ session_share = d.pop("session_share", UNSET)
+
+ session_unshare = d.pop("session_unshare", UNSET)
+
+ session_interrupt = d.pop("session_interrupt", UNSET)
+
+ session_compact = d.pop("session_compact", UNSET)
+
+ session_child_cycle = d.pop("session_child_cycle", UNSET)
+
+ session_child_cycle_reverse = d.pop("session_child_cycle_reverse", UNSET)
+
+ messages_page_up = d.pop("messages_page_up", UNSET)
+
+ messages_page_down = d.pop("messages_page_down", UNSET)
+
+ messages_half_page_up = d.pop("messages_half_page_up", UNSET)
+
+ messages_half_page_down = d.pop("messages_half_page_down", UNSET)
+
+ messages_first = d.pop("messages_first", UNSET)
+
+ messages_last = d.pop("messages_last", UNSET)
+
+ messages_copy = d.pop("messages_copy", UNSET)
+
+ messages_undo = d.pop("messages_undo", UNSET)
+
+ messages_redo = d.pop("messages_redo", UNSET)
+
+ model_list = d.pop("model_list", UNSET)
+
+ model_cycle_recent = d.pop("model_cycle_recent", UNSET)
+
+ model_cycle_recent_reverse = d.pop("model_cycle_recent_reverse", UNSET)
+
+ agent_list = d.pop("agent_list", UNSET)
+
+ agent_cycle = d.pop("agent_cycle", UNSET)
+
+ agent_cycle_reverse = d.pop("agent_cycle_reverse", UNSET)
+
+ input_clear = d.pop("input_clear", UNSET)
+
+ input_paste = d.pop("input_paste", UNSET)
+
+ input_submit = d.pop("input_submit", UNSET)
+
+ input_newline = d.pop("input_newline", UNSET)
+
+ switch_mode = d.pop("switch_mode", UNSET)
+
+ switch_mode_reverse = d.pop("switch_mode_reverse", UNSET)
+
+ switch_agent = d.pop("switch_agent", UNSET)
+
+ switch_agent_reverse = d.pop("switch_agent_reverse", UNSET)
+
+ file_list = d.pop("file_list", UNSET)
+
+ file_close = d.pop("file_close", UNSET)
+
+ file_search = d.pop("file_search", UNSET)
+
+ file_diff_toggle = d.pop("file_diff_toggle", UNSET)
+
+ messages_previous = d.pop("messages_previous", UNSET)
+
+ messages_next = d.pop("messages_next", UNSET)
+
+ messages_layout_toggle = d.pop("messages_layout_toggle", UNSET)
+
+ messages_revert = d.pop("messages_revert", UNSET)
+
+ keybinds_config = cls(
+ leader=leader,
+ app_help=app_help,
+ app_exit=app_exit,
+ editor_open=editor_open,
+ theme_list=theme_list,
+ project_init=project_init,
+ tool_details=tool_details,
+ thinking_blocks=thinking_blocks,
+ session_export=session_export,
+ session_new=session_new,
+ session_list=session_list,
+ session_timeline=session_timeline,
+ session_share=session_share,
+ session_unshare=session_unshare,
+ session_interrupt=session_interrupt,
+ session_compact=session_compact,
+ session_child_cycle=session_child_cycle,
+ session_child_cycle_reverse=session_child_cycle_reverse,
+ messages_page_up=messages_page_up,
+ messages_page_down=messages_page_down,
+ messages_half_page_up=messages_half_page_up,
+ messages_half_page_down=messages_half_page_down,
+ messages_first=messages_first,
+ messages_last=messages_last,
+ messages_copy=messages_copy,
+ messages_undo=messages_undo,
+ messages_redo=messages_redo,
+ model_list=model_list,
+ model_cycle_recent=model_cycle_recent,
+ model_cycle_recent_reverse=model_cycle_recent_reverse,
+ agent_list=agent_list,
+ agent_cycle=agent_cycle,
+ agent_cycle_reverse=agent_cycle_reverse,
+ input_clear=input_clear,
+ input_paste=input_paste,
+ input_submit=input_submit,
+ input_newline=input_newline,
+ switch_mode=switch_mode,
+ switch_mode_reverse=switch_mode_reverse,
+ switch_agent=switch_agent,
+ switch_agent_reverse=switch_agent_reverse,
+ file_list=file_list,
+ file_close=file_close,
+ file_search=file_search,
+ file_diff_toggle=file_diff_toggle,
+ messages_previous=messages_previous,
+ messages_next=messages_next,
+ messages_layout_toggle=messages_layout_toggle,
+ messages_revert=messages_revert,
+ )
+
+ return keybinds_config
diff --git a/packages/sdk/python/src/opencode_ai/models/layout_config.py b/packages/sdk/python/src/opencode_ai/models/layout_config.py
new file mode 100644
index 000000000..51d0c0b1d
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/layout_config.py
@@ -0,0 +1,9 @@
+from enum import Enum
+
+
+class LayoutConfig(str, Enum):
+ AUTO = "auto"
+ STRETCH = "stretch"
+
+ def __str__(self) -> str:
+ return str(self.value)
diff --git a/packages/sdk/python/src/opencode_ai/models/mcp_local_config.py b/packages/sdk/python/src/opencode_ai/models/mcp_local_config.py
new file mode 100644
index 000000000..ccaf813c3
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/mcp_local_config.py
@@ -0,0 +1,83 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.mcp_local_config_environment import McpLocalConfigEnvironment
+
+
+T = TypeVar("T", bound="McpLocalConfig")
+
+
+@_attrs_define
+class McpLocalConfig:
+ """
+ Attributes:
+ type_ (Literal['local']): Type of MCP server connection
+ command (list[str]): Command and arguments to run the MCP server
+ environment (Union[Unset, McpLocalConfigEnvironment]): Environment variables to set when running the MCP server
+ enabled (Union[Unset, bool]): Enable or disable the MCP server on startup
+ """
+
+ type_: Literal["local"]
+ command: list[str]
+ environment: Union[Unset, "McpLocalConfigEnvironment"] = UNSET
+ enabled: Union[Unset, bool] = UNSET
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ command = self.command
+
+ environment: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.environment, Unset):
+ environment = self.environment.to_dict()
+
+ enabled = self.enabled
+
+ field_dict: dict[str, Any] = {}
+
+ field_dict.update(
+ {
+ "type": type_,
+ "command": command,
+ }
+ )
+ if environment is not UNSET:
+ field_dict["environment"] = environment
+ if enabled is not UNSET:
+ field_dict["enabled"] = enabled
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.mcp_local_config_environment import McpLocalConfigEnvironment
+
+ d = dict(src_dict)
+ type_ = cast(Literal["local"], d.pop("type"))
+ if type_ != "local":
+ raise ValueError(f"type must match const 'local', got '{type_}'")
+
+ command = cast(list[str], d.pop("command"))
+
+ _environment = d.pop("environment", UNSET)
+ environment: Union[Unset, McpLocalConfigEnvironment]
+ if isinstance(_environment, Unset):
+ environment = UNSET
+ else:
+ environment = McpLocalConfigEnvironment.from_dict(_environment)
+
+ enabled = d.pop("enabled", UNSET)
+
+ mcp_local_config = cls(
+ type_=type_,
+ command=command,
+ environment=environment,
+ enabled=enabled,
+ )
+
+ return mcp_local_config
diff --git a/packages/sdk/python/src/opencode_ai/models/mcp_local_config_environment.py b/packages/sdk/python/src/opencode_ai/models/mcp_local_config_environment.py
new file mode 100644
index 000000000..89c3d2254
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/mcp_local_config_environment.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="McpLocalConfigEnvironment")
+
+
+@_attrs_define
+class McpLocalConfigEnvironment:
+ """Environment variables to set when running the MCP server"""
+
+ additional_properties: dict[str, str] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ mcp_local_config_environment = cls()
+
+ mcp_local_config_environment.additional_properties = d
+ return mcp_local_config_environment
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> str:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: str) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/mcp_remote_config.py b/packages/sdk/python/src/opencode_ai/models/mcp_remote_config.py
new file mode 100644
index 000000000..182553cc2
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/mcp_remote_config.py
@@ -0,0 +1,83 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.mcp_remote_config_headers import McpRemoteConfigHeaders
+
+
+T = TypeVar("T", bound="McpRemoteConfig")
+
+
+@_attrs_define
+class McpRemoteConfig:
+ """
+ Attributes:
+ type_ (Literal['remote']): Type of MCP server connection
+ url (str): URL of the remote MCP server
+ enabled (Union[Unset, bool]): Enable or disable the MCP server on startup
+ headers (Union[Unset, McpRemoteConfigHeaders]): Headers to send with the request
+ """
+
+ type_: Literal["remote"]
+ url: str
+ enabled: Union[Unset, bool] = UNSET
+ headers: Union[Unset, "McpRemoteConfigHeaders"] = UNSET
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ url = self.url
+
+ enabled = self.enabled
+
+ headers: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.headers, Unset):
+ headers = self.headers.to_dict()
+
+ field_dict: dict[str, Any] = {}
+
+ field_dict.update(
+ {
+ "type": type_,
+ "url": url,
+ }
+ )
+ if enabled is not UNSET:
+ field_dict["enabled"] = enabled
+ if headers is not UNSET:
+ field_dict["headers"] = headers
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.mcp_remote_config_headers import McpRemoteConfigHeaders
+
+ d = dict(src_dict)
+ type_ = cast(Literal["remote"], d.pop("type"))
+ if type_ != "remote":
+ raise ValueError(f"type must match const 'remote', got '{type_}'")
+
+ url = d.pop("url")
+
+ enabled = d.pop("enabled", UNSET)
+
+ _headers = d.pop("headers", UNSET)
+ headers: Union[Unset, McpRemoteConfigHeaders]
+ if isinstance(_headers, Unset):
+ headers = UNSET
+ else:
+ headers = McpRemoteConfigHeaders.from_dict(_headers)
+
+ mcp_remote_config = cls(
+ type_=type_,
+ url=url,
+ enabled=enabled,
+ headers=headers,
+ )
+
+ return mcp_remote_config
diff --git a/packages/sdk/python/src/opencode_ai/models/mcp_remote_config_headers.py b/packages/sdk/python/src/opencode_ai/models/mcp_remote_config_headers.py
new file mode 100644
index 000000000..5f437d8ae
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/mcp_remote_config_headers.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="McpRemoteConfigHeaders")
+
+
+@_attrs_define
+class McpRemoteConfigHeaders:
+ """Headers to send with the request"""
+
+ additional_properties: dict[str, str] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ mcp_remote_config_headers = cls()
+
+ mcp_remote_config_headers.additional_properties = d
+ return mcp_remote_config_headers
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> str:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: str) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/message_aborted_error.py b/packages/sdk/python/src/opencode_ai/models/message_aborted_error.py
new file mode 100644
index 000000000..6b2d489f0
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/message_aborted_error.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.message_aborted_error_data import MessageAbortedErrorData
+
+
+T = TypeVar("T", bound="MessageAbortedError")
+
+
+@_attrs_define
+class MessageAbortedError:
+ """
+ Attributes:
+ name (Literal['MessageAbortedError']):
+ data (MessageAbortedErrorData):
+ """
+
+ name: Literal["MessageAbortedError"]
+ data: "MessageAbortedErrorData"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ name = self.name
+
+ data = self.data.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "name": name,
+ "data": data,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.message_aborted_error_data import MessageAbortedErrorData
+
+ d = dict(src_dict)
+ name = cast(Literal["MessageAbortedError"], d.pop("name"))
+ if name != "MessageAbortedError":
+ raise ValueError(f"name must match const 'MessageAbortedError', got '{name}'")
+
+ data = MessageAbortedErrorData.from_dict(d.pop("data"))
+
+ message_aborted_error = cls(
+ name=name,
+ data=data,
+ )
+
+ message_aborted_error.additional_properties = d
+ return message_aborted_error
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/message_aborted_error_data.py b/packages/sdk/python/src/opencode_ai/models/message_aborted_error_data.py
new file mode 100644
index 000000000..948ac5f61
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/message_aborted_error_data.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="MessageAbortedErrorData")
+
+
+@_attrs_define
+class MessageAbortedErrorData:
+ """
+ Attributes:
+ message (str):
+ """
+
+ message: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ message = self.message
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "message": message,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ message = d.pop("message")
+
+ message_aborted_error_data = cls(
+ message=message,
+ )
+
+ message_aborted_error_data.additional_properties = d
+ return message_aborted_error_data
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/message_output_length_error.py b/packages/sdk/python/src/opencode_ai/models/message_output_length_error.py
new file mode 100644
index 000000000..86ba76ff2
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/message_output_length_error.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.message_output_length_error_data import MessageOutputLengthErrorData
+
+
+T = TypeVar("T", bound="MessageOutputLengthError")
+
+
+@_attrs_define
+class MessageOutputLengthError:
+ """
+ Attributes:
+ name (Literal['MessageOutputLengthError']):
+ data (MessageOutputLengthErrorData):
+ """
+
+ name: Literal["MessageOutputLengthError"]
+ data: "MessageOutputLengthErrorData"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ name = self.name
+
+ data = self.data.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "name": name,
+ "data": data,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.message_output_length_error_data import MessageOutputLengthErrorData
+
+ d = dict(src_dict)
+ name = cast(Literal["MessageOutputLengthError"], d.pop("name"))
+ if name != "MessageOutputLengthError":
+ raise ValueError(f"name must match const 'MessageOutputLengthError', got '{name}'")
+
+ data = MessageOutputLengthErrorData.from_dict(d.pop("data"))
+
+ message_output_length_error = cls(
+ name=name,
+ data=data,
+ )
+
+ message_output_length_error.additional_properties = d
+ return message_output_length_error
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/message_output_length_error_data.py b/packages/sdk/python/src/opencode_ai/models/message_output_length_error_data.py
new file mode 100644
index 000000000..2541d9a93
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/message_output_length_error_data.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="MessageOutputLengthErrorData")
+
+
+@_attrs_define
+class MessageOutputLengthErrorData:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ message_output_length_error_data = cls()
+
+ message_output_length_error_data.additional_properties = d
+ return message_output_length_error_data
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/model.py b/packages/sdk/python/src/opencode_ai/models/model.py
new file mode 100644
index 000000000..bcdf1fefc
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/model.py
@@ -0,0 +1,170 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.model_cost import ModelCost
+ from ..models.model_limit import ModelLimit
+ from ..models.model_options import ModelOptions
+ from ..models.model_provider import ModelProvider
+
+
+T = TypeVar("T", bound="Model")
+
+
+@_attrs_define
+class Model:
+ """
+ Attributes:
+ id (str):
+ name (str):
+ release_date (str):
+ attachment (bool):
+ reasoning (bool):
+ temperature (bool):
+ tool_call (bool):
+ cost (ModelCost):
+ limit (ModelLimit):
+ options (ModelOptions):
+ experimental (Union[Unset, bool]):
+ provider (Union[Unset, ModelProvider]):
+ """
+
+ id: str
+ name: str
+ release_date: str
+ attachment: bool
+ reasoning: bool
+ temperature: bool
+ tool_call: bool
+ cost: "ModelCost"
+ limit: "ModelLimit"
+ options: "ModelOptions"
+ experimental: Union[Unset, bool] = UNSET
+ provider: Union[Unset, "ModelProvider"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ name = self.name
+
+ release_date = self.release_date
+
+ attachment = self.attachment
+
+ reasoning = self.reasoning
+
+ temperature = self.temperature
+
+ tool_call = self.tool_call
+
+ cost = self.cost.to_dict()
+
+ limit = self.limit.to_dict()
+
+ options = self.options.to_dict()
+
+ experimental = self.experimental
+
+ provider: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.provider, Unset):
+ provider = self.provider.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "name": name,
+ "release_date": release_date,
+ "attachment": attachment,
+ "reasoning": reasoning,
+ "temperature": temperature,
+ "tool_call": tool_call,
+ "cost": cost,
+ "limit": limit,
+ "options": options,
+ }
+ )
+ if experimental is not UNSET:
+ field_dict["experimental"] = experimental
+ if provider is not UNSET:
+ field_dict["provider"] = provider
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.model_cost import ModelCost
+ from ..models.model_limit import ModelLimit
+ from ..models.model_options import ModelOptions
+ from ..models.model_provider import ModelProvider
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ name = d.pop("name")
+
+ release_date = d.pop("release_date")
+
+ attachment = d.pop("attachment")
+
+ reasoning = d.pop("reasoning")
+
+ temperature = d.pop("temperature")
+
+ tool_call = d.pop("tool_call")
+
+ cost = ModelCost.from_dict(d.pop("cost"))
+
+ limit = ModelLimit.from_dict(d.pop("limit"))
+
+ options = ModelOptions.from_dict(d.pop("options"))
+
+ experimental = d.pop("experimental", UNSET)
+
+ _provider = d.pop("provider", UNSET)
+ provider: Union[Unset, ModelProvider]
+ if isinstance(_provider, Unset):
+ provider = UNSET
+ else:
+ provider = ModelProvider.from_dict(_provider)
+
+ model = cls(
+ id=id,
+ name=name,
+ release_date=release_date,
+ attachment=attachment,
+ reasoning=reasoning,
+ temperature=temperature,
+ tool_call=tool_call,
+ cost=cost,
+ limit=limit,
+ options=options,
+ experimental=experimental,
+ provider=provider,
+ )
+
+ model.additional_properties = d
+ return model
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/model_cost.py b/packages/sdk/python/src/opencode_ai/models/model_cost.py
new file mode 100644
index 000000000..9658e9d4f
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/model_cost.py
@@ -0,0 +1,87 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="ModelCost")
+
+
+@_attrs_define
+class ModelCost:
+ """
+ Attributes:
+ input_ (float):
+ output (float):
+ cache_read (Union[Unset, float]):
+ cache_write (Union[Unset, float]):
+ """
+
+ input_: float
+ output: float
+ cache_read: Union[Unset, float] = UNSET
+ cache_write: Union[Unset, float] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ input_ = self.input_
+
+ output = self.output
+
+ cache_read = self.cache_read
+
+ cache_write = self.cache_write
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "input": input_,
+ "output": output,
+ }
+ )
+ if cache_read is not UNSET:
+ field_dict["cache_read"] = cache_read
+ if cache_write is not UNSET:
+ field_dict["cache_write"] = cache_write
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ input_ = d.pop("input")
+
+ output = d.pop("output")
+
+ cache_read = d.pop("cache_read", UNSET)
+
+ cache_write = d.pop("cache_write", UNSET)
+
+ model_cost = cls(
+ input_=input_,
+ output=output,
+ cache_read=cache_read,
+ cache_write=cache_write,
+ )
+
+ model_cost.additional_properties = d
+ return model_cost
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/model_limit.py b/packages/sdk/python/src/opencode_ai/models/model_limit.py
new file mode 100644
index 000000000..701f53130
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/model_limit.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ModelLimit")
+
+
+@_attrs_define
+class ModelLimit:
+ """
+ Attributes:
+ context (float):
+ output (float):
+ """
+
+ context: float
+ output: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ context = self.context
+
+ output = self.output
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "context": context,
+ "output": output,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ context = d.pop("context")
+
+ output = d.pop("output")
+
+ model_limit = cls(
+ context=context,
+ output=output,
+ )
+
+ model_limit.additional_properties = d
+ return model_limit
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/model_options.py b/packages/sdk/python/src/opencode_ai/models/model_options.py
new file mode 100644
index 000000000..cd62bb644
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/model_options.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ModelOptions")
+
+
+@_attrs_define
+class ModelOptions:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ model_options = cls()
+
+ model_options.additional_properties = d
+ return model_options
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/model_provider.py b/packages/sdk/python/src/opencode_ai/models/model_provider.py
new file mode 100644
index 000000000..53eb522d7
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/model_provider.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ModelProvider")
+
+
+@_attrs_define
+class ModelProvider:
+ """
+ Attributes:
+ npm (str):
+ """
+
+ npm: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ npm = self.npm
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "npm": npm,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ npm = d.pop("npm")
+
+ model_provider = cls(
+ npm=npm,
+ )
+
+ model_provider.additional_properties = d
+ return model_provider
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/o_auth.py b/packages/sdk/python/src/opencode_ai/models/o_auth.py
new file mode 100644
index 000000000..470fe6fd0
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/o_auth.py
@@ -0,0 +1,85 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="OAuth")
+
+
+@_attrs_define
+class OAuth:
+ """
+ Attributes:
+ type_ (Literal['oauth']):
+ refresh (str):
+ access (str):
+ expires (float):
+ """
+
+ type_: Literal["oauth"]
+ refresh: str
+ access: str
+ expires: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ refresh = self.refresh
+
+ access = self.access
+
+ expires = self.expires
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "refresh": refresh,
+ "access": access,
+ "expires": expires,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ type_ = cast(Literal["oauth"], d.pop("type"))
+ if type_ != "oauth":
+ raise ValueError(f"type must match const 'oauth', got '{type_}'")
+
+ refresh = d.pop("refresh")
+
+ access = d.pop("access")
+
+ expires = d.pop("expires")
+
+ o_auth = cls(
+ type_=type_,
+ refresh=refresh,
+ access=access,
+ expires=expires,
+ )
+
+ o_auth.additional_properties = d
+ return o_auth
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/patch_part.py b/packages/sdk/python/src/opencode_ai/models/patch_part.py
new file mode 100644
index 000000000..25bbc34e8
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/patch_part.py
@@ -0,0 +1,101 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="PatchPart")
+
+
+@_attrs_define
+class PatchPart:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ message_id (str):
+ type_ (Literal['patch']):
+ hash_ (str):
+ files (list[str]):
+ """
+
+ id: str
+ session_id: str
+ message_id: str
+ type_: Literal["patch"]
+ hash_: str
+ files: list[str]
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ type_ = self.type_
+
+ hash_ = self.hash_
+
+ files = self.files
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "messageID": message_id,
+ "type": type_,
+ "hash": hash_,
+ "files": files,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ type_ = cast(Literal["patch"], d.pop("type"))
+ if type_ != "patch":
+ raise ValueError(f"type must match const 'patch', got '{type_}'")
+
+ hash_ = d.pop("hash")
+
+ files = cast(list[str], d.pop("files"))
+
+ patch_part = cls(
+ id=id,
+ session_id=session_id,
+ message_id=message_id,
+ type_=type_,
+ hash_=hash_,
+ files=files,
+ )
+
+ patch_part.additional_properties = d
+ return patch_part
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/path.py b/packages/sdk/python/src/opencode_ai/models/path.py
new file mode 100644
index 000000000..698d1a042
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/path.py
@@ -0,0 +1,83 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="Path")
+
+
+@_attrs_define
+class Path:
+ """
+ Attributes:
+ state (str):
+ config (str):
+ worktree (str):
+ directory (str):
+ """
+
+ state: str
+ config: str
+ worktree: str
+ directory: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ state = self.state
+
+ config = self.config
+
+ worktree = self.worktree
+
+ directory = self.directory
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "state": state,
+ "config": config,
+ "worktree": worktree,
+ "directory": directory,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ state = d.pop("state")
+
+ config = d.pop("config")
+
+ worktree = d.pop("worktree")
+
+ directory = d.pop("directory")
+
+ path = cls(
+ state=state,
+ config=config,
+ worktree=worktree,
+ directory=directory,
+ )
+
+ path.additional_properties = d
+ return path
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/permission.py b/packages/sdk/python/src/opencode_ai/models/permission.py
new file mode 100644
index 000000000..bd3ea30f1
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/permission.py
@@ -0,0 +1,155 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.permission_metadata import PermissionMetadata
+ from ..models.permission_time import PermissionTime
+
+
+T = TypeVar("T", bound="Permission")
+
+
+@_attrs_define
+class Permission:
+ """
+ Attributes:
+ id (str):
+ type_ (str):
+ session_id (str):
+ message_id (str):
+ title (str):
+ metadata (PermissionMetadata):
+ time (PermissionTime):
+ pattern (Union[Unset, list[str], str]):
+ call_id (Union[Unset, str]):
+ """
+
+ id: str
+ type_: str
+ session_id: str
+ message_id: str
+ title: str
+ metadata: "PermissionMetadata"
+ time: "PermissionTime"
+ pattern: Union[Unset, list[str], str] = UNSET
+ call_id: Union[Unset, str] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ type_ = self.type_
+
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ title = self.title
+
+ metadata = self.metadata.to_dict()
+
+ time = self.time.to_dict()
+
+ pattern: Union[Unset, list[str], str]
+ if isinstance(self.pattern, Unset):
+ pattern = UNSET
+ elif isinstance(self.pattern, list):
+ pattern = self.pattern
+
+ else:
+ pattern = self.pattern
+
+ call_id = self.call_id
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "type": type_,
+ "sessionID": session_id,
+ "messageID": message_id,
+ "title": title,
+ "metadata": metadata,
+ "time": time,
+ }
+ )
+ if pattern is not UNSET:
+ field_dict["pattern"] = pattern
+ if call_id is not UNSET:
+ field_dict["callID"] = call_id
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.permission_metadata import PermissionMetadata
+ from ..models.permission_time import PermissionTime
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ type_ = d.pop("type")
+
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ title = d.pop("title")
+
+ metadata = PermissionMetadata.from_dict(d.pop("metadata"))
+
+ time = PermissionTime.from_dict(d.pop("time"))
+
+ def _parse_pattern(data: object) -> Union[Unset, list[str], str]:
+ if isinstance(data, Unset):
+ return data
+ try:
+ if not isinstance(data, list):
+ raise TypeError()
+ pattern_type_1 = cast(list[str], data)
+
+ return pattern_type_1
+ except: # noqa: E722
+ pass
+ return cast(Union[Unset, list[str], str], data)
+
+ pattern = _parse_pattern(d.pop("pattern", UNSET))
+
+ call_id = d.pop("callID", UNSET)
+
+ permission = cls(
+ id=id,
+ type_=type_,
+ session_id=session_id,
+ message_id=message_id,
+ title=title,
+ metadata=metadata,
+ time=time,
+ pattern=pattern,
+ call_id=call_id,
+ )
+
+ permission.additional_properties = d
+ return permission
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/permission_metadata.py b/packages/sdk/python/src/opencode_ai/models/permission_metadata.py
new file mode 100644
index 000000000..7379eb3c1
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/permission_metadata.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="PermissionMetadata")
+
+
+@_attrs_define
+class PermissionMetadata:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ permission_metadata = cls()
+
+ permission_metadata.additional_properties = d
+ return permission_metadata
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/permission_time.py b/packages/sdk/python/src/opencode_ai/models/permission_time.py
new file mode 100644
index 000000000..d99bc2ec5
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/permission_time.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="PermissionTime")
+
+
+@_attrs_define
+class PermissionTime:
+ """
+ Attributes:
+ created (float):
+ """
+
+ created: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ created = self.created
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "created": created,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ created = d.pop("created")
+
+ permission_time = cls(
+ created=created,
+ )
+
+ permission_time.additional_properties = d
+ return permission_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/project.py b/packages/sdk/python/src/opencode_ai/models/project.py
new file mode 100644
index 000000000..d6590dbd9
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/project.py
@@ -0,0 +1,94 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.project_time import ProjectTime
+
+
+T = TypeVar("T", bound="Project")
+
+
+@_attrs_define
+class Project:
+ """
+ Attributes:
+ id (str):
+ worktree (str):
+ time (ProjectTime):
+ vcs (Union[Literal['git'], Unset]):
+ """
+
+ id: str
+ worktree: str
+ time: "ProjectTime"
+ vcs: Union[Literal["git"], Unset] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ worktree = self.worktree
+
+ time = self.time.to_dict()
+
+ vcs = self.vcs
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "worktree": worktree,
+ "time": time,
+ }
+ )
+ if vcs is not UNSET:
+ field_dict["vcs"] = vcs
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.project_time import ProjectTime
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ worktree = d.pop("worktree")
+
+ time = ProjectTime.from_dict(d.pop("time"))
+
+ vcs = cast(Union[Literal["git"], Unset], d.pop("vcs", UNSET))
+ if vcs != "git" and not isinstance(vcs, Unset):
+ raise ValueError(f"vcs must match const 'git', got '{vcs}'")
+
+ project = cls(
+ id=id,
+ worktree=worktree,
+ time=time,
+ vcs=vcs,
+ )
+
+ project.additional_properties = d
+ return project
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/project_time.py b/packages/sdk/python/src/opencode_ai/models/project_time.py
new file mode 100644
index 000000000..1d6ef989c
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/project_time.py
@@ -0,0 +1,70 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="ProjectTime")
+
+
+@_attrs_define
+class ProjectTime:
+ """
+ Attributes:
+ created (float):
+ initialized (Union[Unset, float]):
+ """
+
+ created: float
+ initialized: Union[Unset, float] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ created = self.created
+
+ initialized = self.initialized
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "created": created,
+ }
+ )
+ if initialized is not UNSET:
+ field_dict["initialized"] = initialized
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ created = d.pop("created")
+
+ initialized = d.pop("initialized", UNSET)
+
+ project_time = cls(
+ created=created,
+ initialized=initialized,
+ )
+
+ project_time.additional_properties = d
+ return project_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/provider.py b/packages/sdk/python/src/opencode_ai/models/provider.py
new file mode 100644
index 000000000..e28076ce5
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/provider.py
@@ -0,0 +1,109 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.provider_models import ProviderModels
+
+
+T = TypeVar("T", bound="Provider")
+
+
+@_attrs_define
+class Provider:
+ """
+ Attributes:
+ name (str):
+ env (list[str]):
+ id (str):
+ models (ProviderModels):
+ api (Union[Unset, str]):
+ npm (Union[Unset, str]):
+ """
+
+ name: str
+ env: list[str]
+ id: str
+ models: "ProviderModels"
+ api: Union[Unset, str] = UNSET
+ npm: Union[Unset, str] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ name = self.name
+
+ env = self.env
+
+ id = self.id
+
+ models = self.models.to_dict()
+
+ api = self.api
+
+ npm = self.npm
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "name": name,
+ "env": env,
+ "id": id,
+ "models": models,
+ }
+ )
+ if api is not UNSET:
+ field_dict["api"] = api
+ if npm is not UNSET:
+ field_dict["npm"] = npm
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.provider_models import ProviderModels
+
+ d = dict(src_dict)
+ name = d.pop("name")
+
+ env = cast(list[str], d.pop("env"))
+
+ id = d.pop("id")
+
+ models = ProviderModels.from_dict(d.pop("models"))
+
+ api = d.pop("api", UNSET)
+
+ npm = d.pop("npm", UNSET)
+
+ provider = cls(
+ name=name,
+ env=env,
+ id=id,
+ models=models,
+ api=api,
+ npm=npm,
+ )
+
+ provider.additional_properties = d
+ return provider
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/provider_auth_error.py b/packages/sdk/python/src/opencode_ai/models/provider_auth_error.py
new file mode 100644
index 000000000..c1b9dd6cc
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/provider_auth_error.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.provider_auth_error_data import ProviderAuthErrorData
+
+
+T = TypeVar("T", bound="ProviderAuthError")
+
+
+@_attrs_define
+class ProviderAuthError:
+ """
+ Attributes:
+ name (Literal['ProviderAuthError']):
+ data (ProviderAuthErrorData):
+ """
+
+ name: Literal["ProviderAuthError"]
+ data: "ProviderAuthErrorData"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ name = self.name
+
+ data = self.data.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "name": name,
+ "data": data,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.provider_auth_error_data import ProviderAuthErrorData
+
+ d = dict(src_dict)
+ name = cast(Literal["ProviderAuthError"], d.pop("name"))
+ if name != "ProviderAuthError":
+ raise ValueError(f"name must match const 'ProviderAuthError', got '{name}'")
+
+ data = ProviderAuthErrorData.from_dict(d.pop("data"))
+
+ provider_auth_error = cls(
+ name=name,
+ data=data,
+ )
+
+ provider_auth_error.additional_properties = d
+ return provider_auth_error
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/provider_auth_error_data.py b/packages/sdk/python/src/opencode_ai/models/provider_auth_error_data.py
new file mode 100644
index 000000000..d958b0b5f
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/provider_auth_error_data.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ProviderAuthErrorData")
+
+
+@_attrs_define
+class ProviderAuthErrorData:
+ """
+ Attributes:
+ provider_id (str):
+ message (str):
+ """
+
+ provider_id: str
+ message: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ provider_id = self.provider_id
+
+ message = self.message
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "providerID": provider_id,
+ "message": message,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ provider_id = d.pop("providerID")
+
+ message = d.pop("message")
+
+ provider_auth_error_data = cls(
+ provider_id=provider_id,
+ message=message,
+ )
+
+ provider_auth_error_data.additional_properties = d
+ return provider_auth_error_data
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/provider_models.py b/packages/sdk/python/src/opencode_ai/models/provider_models.py
new file mode 100644
index 000000000..461a63418
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/provider_models.py
@@ -0,0 +1,57 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.model import Model
+
+
+T = TypeVar("T", bound="ProviderModels")
+
+
+@_attrs_define
+class ProviderModels:
+ """ """
+
+ additional_properties: dict[str, "Model"] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ for prop_name, prop in self.additional_properties.items():
+ field_dict[prop_name] = prop.to_dict()
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.model import Model
+
+ d = dict(src_dict)
+ provider_models = cls()
+
+ additional_properties = {}
+ for prop_name, prop_dict in d.items():
+ additional_property = Model.from_dict(prop_dict)
+
+ additional_properties[prop_name] = additional_property
+
+ provider_models.additional_properties = additional_properties
+ return provider_models
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> "Model":
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: "Model") -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/range_.py b/packages/sdk/python/src/opencode_ai/models/range_.py
new file mode 100644
index 000000000..1321aeb66
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/range_.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.range_end import RangeEnd
+ from ..models.range_start import RangeStart
+
+
+T = TypeVar("T", bound="Range")
+
+
+@_attrs_define
+class Range:
+ """
+ Attributes:
+ start (RangeStart):
+ end (RangeEnd):
+ """
+
+ start: "RangeStart"
+ end: "RangeEnd"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ start = self.start.to_dict()
+
+ end = self.end.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "start": start,
+ "end": end,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.range_end import RangeEnd
+ from ..models.range_start import RangeStart
+
+ d = dict(src_dict)
+ start = RangeStart.from_dict(d.pop("start"))
+
+ end = RangeEnd.from_dict(d.pop("end"))
+
+ range_ = cls(
+ start=start,
+ end=end,
+ )
+
+ range_.additional_properties = d
+ return range_
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/range_end.py b/packages/sdk/python/src/opencode_ai/models/range_end.py
new file mode 100644
index 000000000..3629c3ae9
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/range_end.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="RangeEnd")
+
+
+@_attrs_define
+class RangeEnd:
+ """
+ Attributes:
+ line (float):
+ character (float):
+ """
+
+ line: float
+ character: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ line = self.line
+
+ character = self.character
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "line": line,
+ "character": character,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ line = d.pop("line")
+
+ character = d.pop("character")
+
+ range_end = cls(
+ line=line,
+ character=character,
+ )
+
+ range_end.additional_properties = d
+ return range_end
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/range_start.py b/packages/sdk/python/src/opencode_ai/models/range_start.py
new file mode 100644
index 000000000..c53c95f95
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/range_start.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="RangeStart")
+
+
+@_attrs_define
+class RangeStart:
+ """
+ Attributes:
+ line (float):
+ character (float):
+ """
+
+ line: float
+ character: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ line = self.line
+
+ character = self.character
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "line": line,
+ "character": character,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ line = d.pop("line")
+
+ character = d.pop("character")
+
+ range_start = cls(
+ line=line,
+ character=character,
+ )
+
+ range_start.additional_properties = d
+ return range_start
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/reasoning_part.py b/packages/sdk/python/src/opencode_ai/models/reasoning_part.py
new file mode 100644
index 000000000..a91df274b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/reasoning_part.py
@@ -0,0 +1,127 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.reasoning_part_metadata import ReasoningPartMetadata
+ from ..models.reasoning_part_time import ReasoningPartTime
+
+
+T = TypeVar("T", bound="ReasoningPart")
+
+
+@_attrs_define
+class ReasoningPart:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ message_id (str):
+ type_ (Literal['reasoning']):
+ text (str):
+ time (ReasoningPartTime):
+ metadata (Union[Unset, ReasoningPartMetadata]):
+ """
+
+ id: str
+ session_id: str
+ message_id: str
+ type_: Literal["reasoning"]
+ text: str
+ time: "ReasoningPartTime"
+ metadata: Union[Unset, "ReasoningPartMetadata"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ type_ = self.type_
+
+ text = self.text
+
+ time = self.time.to_dict()
+
+ metadata: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.metadata, Unset):
+ metadata = self.metadata.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "messageID": message_id,
+ "type": type_,
+ "text": text,
+ "time": time,
+ }
+ )
+ if metadata is not UNSET:
+ field_dict["metadata"] = metadata
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.reasoning_part_metadata import ReasoningPartMetadata
+ from ..models.reasoning_part_time import ReasoningPartTime
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ type_ = cast(Literal["reasoning"], d.pop("type"))
+ if type_ != "reasoning":
+ raise ValueError(f"type must match const 'reasoning', got '{type_}'")
+
+ text = d.pop("text")
+
+ time = ReasoningPartTime.from_dict(d.pop("time"))
+
+ _metadata = d.pop("metadata", UNSET)
+ metadata: Union[Unset, ReasoningPartMetadata]
+ if isinstance(_metadata, Unset):
+ metadata = UNSET
+ else:
+ metadata = ReasoningPartMetadata.from_dict(_metadata)
+
+ reasoning_part = cls(
+ id=id,
+ session_id=session_id,
+ message_id=message_id,
+ type_=type_,
+ text=text,
+ time=time,
+ metadata=metadata,
+ )
+
+ reasoning_part.additional_properties = d
+ return reasoning_part
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/reasoning_part_metadata.py b/packages/sdk/python/src/opencode_ai/models/reasoning_part_metadata.py
new file mode 100644
index 000000000..04a75c6f5
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/reasoning_part_metadata.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ReasoningPartMetadata")
+
+
+@_attrs_define
+class ReasoningPartMetadata:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ reasoning_part_metadata = cls()
+
+ reasoning_part_metadata.additional_properties = d
+ return reasoning_part_metadata
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/reasoning_part_time.py b/packages/sdk/python/src/opencode_ai/models/reasoning_part_time.py
new file mode 100644
index 000000000..603ead6e5
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/reasoning_part_time.py
@@ -0,0 +1,70 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="ReasoningPartTime")
+
+
+@_attrs_define
+class ReasoningPartTime:
+ """
+ Attributes:
+ start (float):
+ end (Union[Unset, float]):
+ """
+
+ start: float
+ end: Union[Unset, float] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ start = self.start
+
+ end = self.end
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "start": start,
+ }
+ )
+ if end is not UNSET:
+ field_dict["end"] = end
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ start = d.pop("start")
+
+ end = d.pop("end", UNSET)
+
+ reasoning_part_time = cls(
+ start=start,
+ end=end,
+ )
+
+ reasoning_part_time.additional_properties = d
+ return reasoning_part_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/session.py b/packages/sdk/python/src/opencode_ai/models/session.py
new file mode 100644
index 000000000..81bf0dbcc
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/session.py
@@ -0,0 +1,152 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.session_revert import SessionRevert
+ from ..models.session_share import SessionShare
+ from ..models.session_time import SessionTime
+
+
+T = TypeVar("T", bound="Session")
+
+
+@_attrs_define
+class Session:
+ """
+ Attributes:
+ id (str):
+ project_id (str):
+ directory (str):
+ title (str):
+ version (str):
+ time (SessionTime):
+ parent_id (Union[Unset, str]):
+ share (Union[Unset, SessionShare]):
+ revert (Union[Unset, SessionRevert]):
+ """
+
+ id: str
+ project_id: str
+ directory: str
+ title: str
+ version: str
+ time: "SessionTime"
+ parent_id: Union[Unset, str] = UNSET
+ share: Union[Unset, "SessionShare"] = UNSET
+ revert: Union[Unset, "SessionRevert"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ project_id = self.project_id
+
+ directory = self.directory
+
+ title = self.title
+
+ version = self.version
+
+ time = self.time.to_dict()
+
+ parent_id = self.parent_id
+
+ share: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.share, Unset):
+ share = self.share.to_dict()
+
+ revert: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.revert, Unset):
+ revert = self.revert.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "projectID": project_id,
+ "directory": directory,
+ "title": title,
+ "version": version,
+ "time": time,
+ }
+ )
+ if parent_id is not UNSET:
+ field_dict["parentID"] = parent_id
+ if share is not UNSET:
+ field_dict["share"] = share
+ if revert is not UNSET:
+ field_dict["revert"] = revert
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.session_revert import SessionRevert
+ from ..models.session_share import SessionShare
+ from ..models.session_time import SessionTime
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ project_id = d.pop("projectID")
+
+ directory = d.pop("directory")
+
+ title = d.pop("title")
+
+ version = d.pop("version")
+
+ time = SessionTime.from_dict(d.pop("time"))
+
+ parent_id = d.pop("parentID", UNSET)
+
+ _share = d.pop("share", UNSET)
+ share: Union[Unset, SessionShare]
+ if isinstance(_share, Unset):
+ share = UNSET
+ else:
+ share = SessionShare.from_dict(_share)
+
+ _revert = d.pop("revert", UNSET)
+ revert: Union[Unset, SessionRevert]
+ if isinstance(_revert, Unset):
+ revert = UNSET
+ else:
+ revert = SessionRevert.from_dict(_revert)
+
+ session = cls(
+ id=id,
+ project_id=project_id,
+ directory=directory,
+ title=title,
+ version=version,
+ time=time,
+ parent_id=parent_id,
+ share=share,
+ revert=revert,
+ )
+
+ session.additional_properties = d
+ return session
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/session_revert.py b/packages/sdk/python/src/opencode_ai/models/session_revert.py
new file mode 100644
index 000000000..97397b9d8
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/session_revert.py
@@ -0,0 +1,88 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="SessionRevert")
+
+
+@_attrs_define
+class SessionRevert:
+ """
+ Attributes:
+ message_id (str):
+ part_id (Union[Unset, str]):
+ snapshot (Union[Unset, str]):
+ diff (Union[Unset, str]):
+ """
+
+ message_id: str
+ part_id: Union[Unset, str] = UNSET
+ snapshot: Union[Unset, str] = UNSET
+ diff: Union[Unset, str] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ message_id = self.message_id
+
+ part_id = self.part_id
+
+ snapshot = self.snapshot
+
+ diff = self.diff
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "messageID": message_id,
+ }
+ )
+ if part_id is not UNSET:
+ field_dict["partID"] = part_id
+ if snapshot is not UNSET:
+ field_dict["snapshot"] = snapshot
+ if diff is not UNSET:
+ field_dict["diff"] = diff
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ message_id = d.pop("messageID")
+
+ part_id = d.pop("partID", UNSET)
+
+ snapshot = d.pop("snapshot", UNSET)
+
+ diff = d.pop("diff", UNSET)
+
+ session_revert = cls(
+ message_id=message_id,
+ part_id=part_id,
+ snapshot=snapshot,
+ diff=diff,
+ )
+
+ session_revert.additional_properties = d
+ return session_revert
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/session_share.py b/packages/sdk/python/src/opencode_ai/models/session_share.py
new file mode 100644
index 000000000..c77f7d388
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/session_share.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="SessionShare")
+
+
+@_attrs_define
+class SessionShare:
+ """
+ Attributes:
+ url (str):
+ """
+
+ url: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ url = self.url
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "url": url,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ url = d.pop("url")
+
+ session_share = cls(
+ url=url,
+ )
+
+ session_share.additional_properties = d
+ return session_share
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/session_time.py b/packages/sdk/python/src/opencode_ai/models/session_time.py
new file mode 100644
index 000000000..682c3af2b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/session_time.py
@@ -0,0 +1,78 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="SessionTime")
+
+
+@_attrs_define
+class SessionTime:
+ """
+ Attributes:
+ created (float):
+ updated (float):
+ compacting (Union[Unset, float]):
+ """
+
+ created: float
+ updated: float
+ compacting: Union[Unset, float] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ created = self.created
+
+ updated = self.updated
+
+ compacting = self.compacting
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "created": created,
+ "updated": updated,
+ }
+ )
+ if compacting is not UNSET:
+ field_dict["compacting"] = compacting
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ created = d.pop("created")
+
+ updated = d.pop("updated")
+
+ compacting = d.pop("compacting", UNSET)
+
+ session_time = cls(
+ created=created,
+ updated=updated,
+ compacting=compacting,
+ )
+
+ session_time.additional_properties = d
+ return session_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/snapshot_part.py b/packages/sdk/python/src/opencode_ai/models/snapshot_part.py
new file mode 100644
index 000000000..9f6f69c2b
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/snapshot_part.py
@@ -0,0 +1,93 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="SnapshotPart")
+
+
+@_attrs_define
+class SnapshotPart:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ message_id (str):
+ type_ (Literal['snapshot']):
+ snapshot (str):
+ """
+
+ id: str
+ session_id: str
+ message_id: str
+ type_: Literal["snapshot"]
+ snapshot: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ type_ = self.type_
+
+ snapshot = self.snapshot
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "messageID": message_id,
+ "type": type_,
+ "snapshot": snapshot,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ type_ = cast(Literal["snapshot"], d.pop("type"))
+ if type_ != "snapshot":
+ raise ValueError(f"type must match const 'snapshot', got '{type_}'")
+
+ snapshot = d.pop("snapshot")
+
+ snapshot_part = cls(
+ id=id,
+ session_id=session_id,
+ message_id=message_id,
+ type_=type_,
+ snapshot=snapshot,
+ )
+
+ snapshot_part.additional_properties = d
+ return snapshot_part
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/step_finish_part.py b/packages/sdk/python/src/opencode_ai/models/step_finish_part.py
new file mode 100644
index 000000000..6d611e7b4
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/step_finish_part.py
@@ -0,0 +1,107 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.step_finish_part_tokens import StepFinishPartTokens
+
+
+T = TypeVar("T", bound="StepFinishPart")
+
+
+@_attrs_define
+class StepFinishPart:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ message_id (str):
+ type_ (Literal['step-finish']):
+ cost (float):
+ tokens (StepFinishPartTokens):
+ """
+
+ id: str
+ session_id: str
+ message_id: str
+ type_: Literal["step-finish"]
+ cost: float
+ tokens: "StepFinishPartTokens"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ type_ = self.type_
+
+ cost = self.cost
+
+ tokens = self.tokens.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "messageID": message_id,
+ "type": type_,
+ "cost": cost,
+ "tokens": tokens,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.step_finish_part_tokens import StepFinishPartTokens
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ type_ = cast(Literal["step-finish"], d.pop("type"))
+ if type_ != "step-finish":
+ raise ValueError(f"type must match const 'step-finish', got '{type_}'")
+
+ cost = d.pop("cost")
+
+ tokens = StepFinishPartTokens.from_dict(d.pop("tokens"))
+
+ step_finish_part = cls(
+ id=id,
+ session_id=session_id,
+ message_id=message_id,
+ type_=type_,
+ cost=cost,
+ tokens=tokens,
+ )
+
+ step_finish_part.additional_properties = d
+ return step_finish_part
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/step_finish_part_tokens.py b/packages/sdk/python/src/opencode_ai/models/step_finish_part_tokens.py
new file mode 100644
index 000000000..de14a4494
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/step_finish_part_tokens.py
@@ -0,0 +1,89 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.step_finish_part_tokens_cache import StepFinishPartTokensCache
+
+
+T = TypeVar("T", bound="StepFinishPartTokens")
+
+
+@_attrs_define
+class StepFinishPartTokens:
+ """
+ Attributes:
+ input_ (float):
+ output (float):
+ reasoning (float):
+ cache (StepFinishPartTokensCache):
+ """
+
+ input_: float
+ output: float
+ reasoning: float
+ cache: "StepFinishPartTokensCache"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ input_ = self.input_
+
+ output = self.output
+
+ reasoning = self.reasoning
+
+ cache = self.cache.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "input": input_,
+ "output": output,
+ "reasoning": reasoning,
+ "cache": cache,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.step_finish_part_tokens_cache import StepFinishPartTokensCache
+
+ d = dict(src_dict)
+ input_ = d.pop("input")
+
+ output = d.pop("output")
+
+ reasoning = d.pop("reasoning")
+
+ cache = StepFinishPartTokensCache.from_dict(d.pop("cache"))
+
+ step_finish_part_tokens = cls(
+ input_=input_,
+ output=output,
+ reasoning=reasoning,
+ cache=cache,
+ )
+
+ step_finish_part_tokens.additional_properties = d
+ return step_finish_part_tokens
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/step_finish_part_tokens_cache.py b/packages/sdk/python/src/opencode_ai/models/step_finish_part_tokens_cache.py
new file mode 100644
index 000000000..2677d810c
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/step_finish_part_tokens_cache.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="StepFinishPartTokensCache")
+
+
+@_attrs_define
+class StepFinishPartTokensCache:
+ """
+ Attributes:
+ read (float):
+ write (float):
+ """
+
+ read: float
+ write: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ read = self.read
+
+ write = self.write
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "read": read,
+ "write": write,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ read = d.pop("read")
+
+ write = d.pop("write")
+
+ step_finish_part_tokens_cache = cls(
+ read=read,
+ write=write,
+ )
+
+ step_finish_part_tokens_cache.additional_properties = d
+ return step_finish_part_tokens_cache
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/step_start_part.py b/packages/sdk/python/src/opencode_ai/models/step_start_part.py
new file mode 100644
index 000000000..bc3bb2862
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/step_start_part.py
@@ -0,0 +1,85 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="StepStartPart")
+
+
+@_attrs_define
+class StepStartPart:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ message_id (str):
+ type_ (Literal['step-start']):
+ """
+
+ id: str
+ session_id: str
+ message_id: str
+ type_: Literal["step-start"]
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ type_ = self.type_
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "messageID": message_id,
+ "type": type_,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ type_ = cast(Literal["step-start"], d.pop("type"))
+ if type_ != "step-start":
+ raise ValueError(f"type must match const 'step-start', got '{type_}'")
+
+ step_start_part = cls(
+ id=id,
+ session_id=session_id,
+ message_id=message_id,
+ type_=type_,
+ )
+
+ step_start_part.additional_properties = d
+ return step_start_part
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/symbol.py b/packages/sdk/python/src/opencode_ai/models/symbol.py
new file mode 100644
index 000000000..f57088931
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/symbol.py
@@ -0,0 +1,81 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.symbol_location import SymbolLocation
+
+
+T = TypeVar("T", bound="Symbol")
+
+
+@_attrs_define
+class Symbol:
+ """
+ Attributes:
+ name (str):
+ kind (float):
+ location (SymbolLocation):
+ """
+
+ name: str
+ kind: float
+ location: "SymbolLocation"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ name = self.name
+
+ kind = self.kind
+
+ location = self.location.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "name": name,
+ "kind": kind,
+ "location": location,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.symbol_location import SymbolLocation
+
+ d = dict(src_dict)
+ name = d.pop("name")
+
+ kind = d.pop("kind")
+
+ location = SymbolLocation.from_dict(d.pop("location"))
+
+ symbol = cls(
+ name=name,
+ kind=kind,
+ location=location,
+ )
+
+ symbol.additional_properties = d
+ return symbol
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/symbol_location.py b/packages/sdk/python/src/opencode_ai/models/symbol_location.py
new file mode 100644
index 000000000..683772762
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/symbol_location.py
@@ -0,0 +1,73 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.range_ import Range
+
+
+T = TypeVar("T", bound="SymbolLocation")
+
+
+@_attrs_define
+class SymbolLocation:
+ """
+ Attributes:
+ uri (str):
+ range_ (Range):
+ """
+
+ uri: str
+ range_: "Range"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ uri = self.uri
+
+ range_ = self.range_.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "uri": uri,
+ "range": range_,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.range_ import Range
+
+ d = dict(src_dict)
+ uri = d.pop("uri")
+
+ range_ = Range.from_dict(d.pop("range"))
+
+ symbol_location = cls(
+ uri=uri,
+ range_=range_,
+ )
+
+ symbol_location.additional_properties = d
+ return symbol_location
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/symbol_source.py b/packages/sdk/python/src/opencode_ai/models/symbol_source.py
new file mode 100644
index 000000000..6cec91d5e
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/symbol_source.py
@@ -0,0 +1,109 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.file_part_source_text import FilePartSourceText
+ from ..models.range_ import Range
+
+
+T = TypeVar("T", bound="SymbolSource")
+
+
+@_attrs_define
+class SymbolSource:
+ """
+ Attributes:
+ text (FilePartSourceText):
+ type_ (Literal['symbol']):
+ path (str):
+ range_ (Range):
+ name (str):
+ kind (int):
+ """
+
+ text: "FilePartSourceText"
+ type_: Literal["symbol"]
+ path: str
+ range_: "Range"
+ name: str
+ kind: int
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ text = self.text.to_dict()
+
+ type_ = self.type_
+
+ path = self.path
+
+ range_ = self.range_.to_dict()
+
+ name = self.name
+
+ kind = self.kind
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "text": text,
+ "type": type_,
+ "path": path,
+ "range": range_,
+ "name": name,
+ "kind": kind,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.file_part_source_text import FilePartSourceText
+ from ..models.range_ import Range
+
+ d = dict(src_dict)
+ text = FilePartSourceText.from_dict(d.pop("text"))
+
+ type_ = cast(Literal["symbol"], d.pop("type"))
+ if type_ != "symbol":
+ raise ValueError(f"type must match const 'symbol', got '{type_}'")
+
+ path = d.pop("path")
+
+ range_ = Range.from_dict(d.pop("range"))
+
+ name = d.pop("name")
+
+ kind = d.pop("kind")
+
+ symbol_source = cls(
+ text=text,
+ type_=type_,
+ path=path,
+ range_=range_,
+ name=name,
+ kind=kind,
+ )
+
+ symbol_source.additional_properties = d
+ return symbol_source
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/text_part.py b/packages/sdk/python/src/opencode_ai/models/text_part.py
new file mode 100644
index 000000000..7c58dcfad
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/text_part.py
@@ -0,0 +1,126 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.text_part_time import TextPartTime
+
+
+T = TypeVar("T", bound="TextPart")
+
+
+@_attrs_define
+class TextPart:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ message_id (str):
+ type_ (Literal['text']):
+ text (str):
+ synthetic (Union[Unset, bool]):
+ time (Union[Unset, TextPartTime]):
+ """
+
+ id: str
+ session_id: str
+ message_id: str
+ type_: Literal["text"]
+ text: str
+ synthetic: Union[Unset, bool] = UNSET
+ time: Union[Unset, "TextPartTime"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ type_ = self.type_
+
+ text = self.text
+
+ synthetic = self.synthetic
+
+ time: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.time, Unset):
+ time = self.time.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "messageID": message_id,
+ "type": type_,
+ "text": text,
+ }
+ )
+ if synthetic is not UNSET:
+ field_dict["synthetic"] = synthetic
+ if time is not UNSET:
+ field_dict["time"] = time
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.text_part_time import TextPartTime
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ type_ = cast(Literal["text"], d.pop("type"))
+ if type_ != "text":
+ raise ValueError(f"type must match const 'text', got '{type_}'")
+
+ text = d.pop("text")
+
+ synthetic = d.pop("synthetic", UNSET)
+
+ _time = d.pop("time", UNSET)
+ time: Union[Unset, TextPartTime]
+ if isinstance(_time, Unset):
+ time = UNSET
+ else:
+ time = TextPartTime.from_dict(_time)
+
+ text_part = cls(
+ id=id,
+ session_id=session_id,
+ message_id=message_id,
+ type_=type_,
+ text=text,
+ synthetic=synthetic,
+ time=time,
+ )
+
+ text_part.additional_properties = d
+ return text_part
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/text_part_input.py b/packages/sdk/python/src/opencode_ai/models/text_part_input.py
new file mode 100644
index 000000000..b664bc740
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/text_part_input.py
@@ -0,0 +1,111 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.text_part_input_time import TextPartInputTime
+
+
+T = TypeVar("T", bound="TextPartInput")
+
+
+@_attrs_define
+class TextPartInput:
+ """
+ Attributes:
+ type_ (Literal['text']):
+ text (str):
+ id (Union[Unset, str]):
+ synthetic (Union[Unset, bool]):
+ time (Union[Unset, TextPartInputTime]):
+ """
+
+ type_: Literal["text"]
+ text: str
+ id: Union[Unset, str] = UNSET
+ synthetic: Union[Unset, bool] = UNSET
+ time: Union[Unset, "TextPartInputTime"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ text = self.text
+
+ id = self.id
+
+ synthetic = self.synthetic
+
+ time: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.time, Unset):
+ time = self.time.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "text": text,
+ }
+ )
+ if id is not UNSET:
+ field_dict["id"] = id
+ if synthetic is not UNSET:
+ field_dict["synthetic"] = synthetic
+ if time is not UNSET:
+ field_dict["time"] = time
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.text_part_input_time import TextPartInputTime
+
+ d = dict(src_dict)
+ type_ = cast(Literal["text"], d.pop("type"))
+ if type_ != "text":
+ raise ValueError(f"type must match const 'text', got '{type_}'")
+
+ text = d.pop("text")
+
+ id = d.pop("id", UNSET)
+
+ synthetic = d.pop("synthetic", UNSET)
+
+ _time = d.pop("time", UNSET)
+ time: Union[Unset, TextPartInputTime]
+ if isinstance(_time, Unset):
+ time = UNSET
+ else:
+ time = TextPartInputTime.from_dict(_time)
+
+ text_part_input = cls(
+ type_=type_,
+ text=text,
+ id=id,
+ synthetic=synthetic,
+ time=time,
+ )
+
+ text_part_input.additional_properties = d
+ return text_part_input
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/text_part_input_time.py b/packages/sdk/python/src/opencode_ai/models/text_part_input_time.py
new file mode 100644
index 000000000..e325a99ae
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/text_part_input_time.py
@@ -0,0 +1,70 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="TextPartInputTime")
+
+
+@_attrs_define
+class TextPartInputTime:
+ """
+ Attributes:
+ start (float):
+ end (Union[Unset, float]):
+ """
+
+ start: float
+ end: Union[Unset, float] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ start = self.start
+
+ end = self.end
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "start": start,
+ }
+ )
+ if end is not UNSET:
+ field_dict["end"] = end
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ start = d.pop("start")
+
+ end = d.pop("end", UNSET)
+
+ text_part_input_time = cls(
+ start=start,
+ end=end,
+ )
+
+ text_part_input_time.additional_properties = d
+ return text_part_input_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/text_part_time.py b/packages/sdk/python/src/opencode_ai/models/text_part_time.py
new file mode 100644
index 000000000..ca36c1eb3
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/text_part_time.py
@@ -0,0 +1,70 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="TextPartTime")
+
+
+@_attrs_define
+class TextPartTime:
+ """
+ Attributes:
+ start (float):
+ end (Union[Unset, float]):
+ """
+
+ start: float
+ end: Union[Unset, float] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ start = self.start
+
+ end = self.end
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "start": start,
+ }
+ )
+ if end is not UNSET:
+ field_dict["end"] = end
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ start = d.pop("start")
+
+ end = d.pop("end", UNSET)
+
+ text_part_time = cls(
+ start=start,
+ end=end,
+ )
+
+ text_part_time.additional_properties = d
+ return text_part_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_list_item.py b/packages/sdk/python/src/opencode_ai/models/tool_list_item.py
new file mode 100644
index 000000000..77c9bf2ca
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_list_item.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ToolListItem")
+
+
+@_attrs_define
+class ToolListItem:
+ """
+ Attributes:
+ id (str):
+ description (str):
+ parameters (Any):
+ """
+
+ id: str
+ description: str
+ parameters: Any
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ description = self.description
+
+ parameters = self.parameters
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "description": description,
+ "parameters": parameters,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ description = d.pop("description")
+
+ parameters = d.pop("parameters")
+
+ tool_list_item = cls(
+ id=id,
+ description=description,
+ parameters=parameters,
+ )
+
+ tool_list_item.additional_properties = d
+ return tool_list_item
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_part.py b/packages/sdk/python/src/opencode_ai/models/tool_part.py
new file mode 100644
index 000000000..a48a5d795
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_part.py
@@ -0,0 +1,166 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.tool_state_completed import ToolStateCompleted
+ from ..models.tool_state_error import ToolStateError
+ from ..models.tool_state_pending import ToolStatePending
+ from ..models.tool_state_running import ToolStateRunning
+
+
+T = TypeVar("T", bound="ToolPart")
+
+
+@_attrs_define
+class ToolPart:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ message_id (str):
+ type_ (Literal['tool']):
+ call_id (str):
+ tool (str):
+ state (Union['ToolStateCompleted', 'ToolStateError', 'ToolStatePending', 'ToolStateRunning']):
+ """
+
+ id: str
+ session_id: str
+ message_id: str
+ type_: Literal["tool"]
+ call_id: str
+ tool: str
+ state: Union["ToolStateCompleted", "ToolStateError", "ToolStatePending", "ToolStateRunning"]
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ from ..models.tool_state_completed import ToolStateCompleted
+ from ..models.tool_state_pending import ToolStatePending
+ from ..models.tool_state_running import ToolStateRunning
+
+ id = self.id
+
+ session_id = self.session_id
+
+ message_id = self.message_id
+
+ type_ = self.type_
+
+ call_id = self.call_id
+
+ tool = self.tool
+
+ state: dict[str, Any]
+ if isinstance(self.state, ToolStatePending):
+ state = self.state.to_dict()
+ elif isinstance(self.state, ToolStateRunning):
+ state = self.state.to_dict()
+ elif isinstance(self.state, ToolStateCompleted):
+ state = self.state.to_dict()
+ else:
+ state = self.state.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "messageID": message_id,
+ "type": type_,
+ "callID": call_id,
+ "tool": tool,
+ "state": state,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.tool_state_completed import ToolStateCompleted
+ from ..models.tool_state_error import ToolStateError
+ from ..models.tool_state_pending import ToolStatePending
+ from ..models.tool_state_running import ToolStateRunning
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ message_id = d.pop("messageID")
+
+ type_ = cast(Literal["tool"], d.pop("type"))
+ if type_ != "tool":
+ raise ValueError(f"type must match const 'tool', got '{type_}'")
+
+ call_id = d.pop("callID")
+
+ tool = d.pop("tool")
+
+ def _parse_state(
+ data: object,
+ ) -> Union["ToolStateCompleted", "ToolStateError", "ToolStatePending", "ToolStateRunning"]:
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_tool_state_type_0 = ToolStatePending.from_dict(data)
+
+ return componentsschemas_tool_state_type_0
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_tool_state_type_1 = ToolStateRunning.from_dict(data)
+
+ return componentsschemas_tool_state_type_1
+ except: # noqa: E722
+ pass
+ try:
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_tool_state_type_2 = ToolStateCompleted.from_dict(data)
+
+ return componentsschemas_tool_state_type_2
+ except: # noqa: E722
+ pass
+ if not isinstance(data, dict):
+ raise TypeError()
+ componentsschemas_tool_state_type_3 = ToolStateError.from_dict(data)
+
+ return componentsschemas_tool_state_type_3
+
+ state = _parse_state(d.pop("state"))
+
+ tool_part = cls(
+ id=id,
+ session_id=session_id,
+ message_id=message_id,
+ type_=type_,
+ call_id=call_id,
+ tool=tool,
+ state=state,
+ )
+
+ tool_part.additional_properties = d
+ return tool_part
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_completed.py b/packages/sdk/python/src/opencode_ai/models/tool_state_completed.py
new file mode 100644
index 000000000..43155ebdb
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_completed.py
@@ -0,0 +1,111 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.tool_state_completed_input import ToolStateCompletedInput
+ from ..models.tool_state_completed_metadata import ToolStateCompletedMetadata
+ from ..models.tool_state_completed_time import ToolStateCompletedTime
+
+
+T = TypeVar("T", bound="ToolStateCompleted")
+
+
+@_attrs_define
+class ToolStateCompleted:
+ """
+ Attributes:
+ status (Literal['completed']):
+ input_ (ToolStateCompletedInput):
+ output (str):
+ title (str):
+ metadata (ToolStateCompletedMetadata):
+ time (ToolStateCompletedTime):
+ """
+
+ status: Literal["completed"]
+ input_: "ToolStateCompletedInput"
+ output: str
+ title: str
+ metadata: "ToolStateCompletedMetadata"
+ time: "ToolStateCompletedTime"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ status = self.status
+
+ input_ = self.input_.to_dict()
+
+ output = self.output
+
+ title = self.title
+
+ metadata = self.metadata.to_dict()
+
+ time = self.time.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "status": status,
+ "input": input_,
+ "output": output,
+ "title": title,
+ "metadata": metadata,
+ "time": time,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.tool_state_completed_input import ToolStateCompletedInput
+ from ..models.tool_state_completed_metadata import ToolStateCompletedMetadata
+ from ..models.tool_state_completed_time import ToolStateCompletedTime
+
+ d = dict(src_dict)
+ status = cast(Literal["completed"], d.pop("status"))
+ if status != "completed":
+ raise ValueError(f"status must match const 'completed', got '{status}'")
+
+ input_ = ToolStateCompletedInput.from_dict(d.pop("input"))
+
+ output = d.pop("output")
+
+ title = d.pop("title")
+
+ metadata = ToolStateCompletedMetadata.from_dict(d.pop("metadata"))
+
+ time = ToolStateCompletedTime.from_dict(d.pop("time"))
+
+ tool_state_completed = cls(
+ status=status,
+ input_=input_,
+ output=output,
+ title=title,
+ metadata=metadata,
+ time=time,
+ )
+
+ tool_state_completed.additional_properties = d
+ return tool_state_completed
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_completed_input.py b/packages/sdk/python/src/opencode_ai/models/tool_state_completed_input.py
new file mode 100644
index 000000000..346aba2e5
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_completed_input.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ToolStateCompletedInput")
+
+
+@_attrs_define
+class ToolStateCompletedInput:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ tool_state_completed_input = cls()
+
+ tool_state_completed_input.additional_properties = d
+ return tool_state_completed_input
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_completed_metadata.py b/packages/sdk/python/src/opencode_ai/models/tool_state_completed_metadata.py
new file mode 100644
index 000000000..22377cf1a
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_completed_metadata.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ToolStateCompletedMetadata")
+
+
+@_attrs_define
+class ToolStateCompletedMetadata:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ tool_state_completed_metadata = cls()
+
+ tool_state_completed_metadata.additional_properties = d
+ return tool_state_completed_metadata
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_completed_time.py b/packages/sdk/python/src/opencode_ai/models/tool_state_completed_time.py
new file mode 100644
index 000000000..131c460d0
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_completed_time.py
@@ -0,0 +1,78 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar, Union
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+T = TypeVar("T", bound="ToolStateCompletedTime")
+
+
+@_attrs_define
+class ToolStateCompletedTime:
+ """
+ Attributes:
+ start (float):
+ end (float):
+ compacted (Union[Unset, float]):
+ """
+
+ start: float
+ end: float
+ compacted: Union[Unset, float] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ start = self.start
+
+ end = self.end
+
+ compacted = self.compacted
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "start": start,
+ "end": end,
+ }
+ )
+ if compacted is not UNSET:
+ field_dict["compacted"] = compacted
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ start = d.pop("start")
+
+ end = d.pop("end")
+
+ compacted = d.pop("compacted", UNSET)
+
+ tool_state_completed_time = cls(
+ start=start,
+ end=end,
+ compacted=compacted,
+ )
+
+ tool_state_completed_time.additional_properties = d
+ return tool_state_completed_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_error.py b/packages/sdk/python/src/opencode_ai/models/tool_state_error.py
new file mode 100644
index 000000000..dcd0e8651
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_error.py
@@ -0,0 +1,113 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.tool_state_error_input import ToolStateErrorInput
+ from ..models.tool_state_error_metadata import ToolStateErrorMetadata
+ from ..models.tool_state_error_time import ToolStateErrorTime
+
+
+T = TypeVar("T", bound="ToolStateError")
+
+
+@_attrs_define
+class ToolStateError:
+ """
+ Attributes:
+ status (Literal['error']):
+ input_ (ToolStateErrorInput):
+ error (str):
+ time (ToolStateErrorTime):
+ metadata (Union[Unset, ToolStateErrorMetadata]):
+ """
+
+ status: Literal["error"]
+ input_: "ToolStateErrorInput"
+ error: str
+ time: "ToolStateErrorTime"
+ metadata: Union[Unset, "ToolStateErrorMetadata"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ status = self.status
+
+ input_ = self.input_.to_dict()
+
+ error = self.error
+
+ time = self.time.to_dict()
+
+ metadata: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.metadata, Unset):
+ metadata = self.metadata.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "status": status,
+ "input": input_,
+ "error": error,
+ "time": time,
+ }
+ )
+ if metadata is not UNSET:
+ field_dict["metadata"] = metadata
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.tool_state_error_input import ToolStateErrorInput
+ from ..models.tool_state_error_metadata import ToolStateErrorMetadata
+ from ..models.tool_state_error_time import ToolStateErrorTime
+
+ d = dict(src_dict)
+ status = cast(Literal["error"], d.pop("status"))
+ if status != "error":
+ raise ValueError(f"status must match const 'error', got '{status}'")
+
+ input_ = ToolStateErrorInput.from_dict(d.pop("input"))
+
+ error = d.pop("error")
+
+ time = ToolStateErrorTime.from_dict(d.pop("time"))
+
+ _metadata = d.pop("metadata", UNSET)
+ metadata: Union[Unset, ToolStateErrorMetadata]
+ if isinstance(_metadata, Unset):
+ metadata = UNSET
+ else:
+ metadata = ToolStateErrorMetadata.from_dict(_metadata)
+
+ tool_state_error = cls(
+ status=status,
+ input_=input_,
+ error=error,
+ time=time,
+ metadata=metadata,
+ )
+
+ tool_state_error.additional_properties = d
+ return tool_state_error
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_error_input.py b/packages/sdk/python/src/opencode_ai/models/tool_state_error_input.py
new file mode 100644
index 000000000..33cb12a3a
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_error_input.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ToolStateErrorInput")
+
+
+@_attrs_define
+class ToolStateErrorInput:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ tool_state_error_input = cls()
+
+ tool_state_error_input.additional_properties = d
+ return tool_state_error_input
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_error_metadata.py b/packages/sdk/python/src/opencode_ai/models/tool_state_error_metadata.py
new file mode 100644
index 000000000..435567852
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_error_metadata.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ToolStateErrorMetadata")
+
+
+@_attrs_define
+class ToolStateErrorMetadata:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ tool_state_error_metadata = cls()
+
+ tool_state_error_metadata.additional_properties = d
+ return tool_state_error_metadata
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_error_time.py b/packages/sdk/python/src/opencode_ai/models/tool_state_error_time.py
new file mode 100644
index 000000000..50a4bbd7d
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_error_time.py
@@ -0,0 +1,67 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ToolStateErrorTime")
+
+
+@_attrs_define
+class ToolStateErrorTime:
+ """
+ Attributes:
+ start (float):
+ end (float):
+ """
+
+ start: float
+ end: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ start = self.start
+
+ end = self.end
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "start": start,
+ "end": end,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ start = d.pop("start")
+
+ end = d.pop("end")
+
+ tool_state_error_time = cls(
+ start=start,
+ end=end,
+ )
+
+ tool_state_error_time.additional_properties = d
+ return tool_state_error_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_pending.py b/packages/sdk/python/src/opencode_ai/models/tool_state_pending.py
new file mode 100644
index 000000000..3e5efcca2
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_pending.py
@@ -0,0 +1,61 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ToolStatePending")
+
+
+@_attrs_define
+class ToolStatePending:
+ """
+ Attributes:
+ status (Literal['pending']):
+ """
+
+ status: Literal["pending"]
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ status = self.status
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "status": status,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ status = cast(Literal["pending"], d.pop("status"))
+ if status != "pending":
+ raise ValueError(f"status must match const 'pending', got '{status}'")
+
+ tool_state_pending = cls(
+ status=status,
+ )
+
+ tool_state_pending.additional_properties = d
+ return tool_state_pending
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_running.py b/packages/sdk/python/src/opencode_ai/models/tool_state_running.py
new file mode 100644
index 000000000..ad6bf204e
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_running.py
@@ -0,0 +1,112 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+from ..types import UNSET, Unset
+
+if TYPE_CHECKING:
+ from ..models.tool_state_running_metadata import ToolStateRunningMetadata
+ from ..models.tool_state_running_time import ToolStateRunningTime
+
+
+T = TypeVar("T", bound="ToolStateRunning")
+
+
+@_attrs_define
+class ToolStateRunning:
+ """
+ Attributes:
+ status (Literal['running']):
+ input_ (Any):
+ time (ToolStateRunningTime):
+ title (Union[Unset, str]):
+ metadata (Union[Unset, ToolStateRunningMetadata]):
+ """
+
+ status: Literal["running"]
+ input_: Any
+ time: "ToolStateRunningTime"
+ title: Union[Unset, str] = UNSET
+ metadata: Union[Unset, "ToolStateRunningMetadata"] = UNSET
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ status = self.status
+
+ input_ = self.input_
+
+ time = self.time.to_dict()
+
+ title = self.title
+
+ metadata: Union[Unset, dict[str, Any]] = UNSET
+ if not isinstance(self.metadata, Unset):
+ metadata = self.metadata.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "status": status,
+ "input": input_,
+ "time": time,
+ }
+ )
+ if title is not UNSET:
+ field_dict["title"] = title
+ if metadata is not UNSET:
+ field_dict["metadata"] = metadata
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.tool_state_running_metadata import ToolStateRunningMetadata
+ from ..models.tool_state_running_time import ToolStateRunningTime
+
+ d = dict(src_dict)
+ status = cast(Literal["running"], d.pop("status"))
+ if status != "running":
+ raise ValueError(f"status must match const 'running', got '{status}'")
+
+ input_ = d.pop("input")
+
+ time = ToolStateRunningTime.from_dict(d.pop("time"))
+
+ title = d.pop("title", UNSET)
+
+ _metadata = d.pop("metadata", UNSET)
+ metadata: Union[Unset, ToolStateRunningMetadata]
+ if isinstance(_metadata, Unset):
+ metadata = UNSET
+ else:
+ metadata = ToolStateRunningMetadata.from_dict(_metadata)
+
+ tool_state_running = cls(
+ status=status,
+ input_=input_,
+ time=time,
+ title=title,
+ metadata=metadata,
+ )
+
+ tool_state_running.additional_properties = d
+ return tool_state_running
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_running_metadata.py b/packages/sdk/python/src/opencode_ai/models/tool_state_running_metadata.py
new file mode 100644
index 000000000..5de4c8a2c
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_running_metadata.py
@@ -0,0 +1,44 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ToolStateRunningMetadata")
+
+
+@_attrs_define
+class ToolStateRunningMetadata:
+ """ """
+
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ tool_state_running_metadata = cls()
+
+ tool_state_running_metadata.additional_properties = d
+ return tool_state_running_metadata
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/tool_state_running_time.py b/packages/sdk/python/src/opencode_ai/models/tool_state_running_time.py
new file mode 100644
index 000000000..49b783782
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/tool_state_running_time.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="ToolStateRunningTime")
+
+
+@_attrs_define
+class ToolStateRunningTime:
+ """
+ Attributes:
+ start (float):
+ """
+
+ start: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ start = self.start
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "start": start,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ start = d.pop("start")
+
+ tool_state_running_time = cls(
+ start=start,
+ )
+
+ tool_state_running_time.additional_properties = d
+ return tool_state_running_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/unknown_error.py b/packages/sdk/python/src/opencode_ai/models/unknown_error.py
new file mode 100644
index 000000000..30d4dd9fb
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/unknown_error.py
@@ -0,0 +1,75 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.unknown_error_data import UnknownErrorData
+
+
+T = TypeVar("T", bound="UnknownError")
+
+
+@_attrs_define
+class UnknownError:
+ """
+ Attributes:
+ name (Literal['UnknownError']):
+ data (UnknownErrorData):
+ """
+
+ name: Literal["UnknownError"]
+ data: "UnknownErrorData"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ name = self.name
+
+ data = self.data.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "name": name,
+ "data": data,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.unknown_error_data import UnknownErrorData
+
+ d = dict(src_dict)
+ name = cast(Literal["UnknownError"], d.pop("name"))
+ if name != "UnknownError":
+ raise ValueError(f"name must match const 'UnknownError', got '{name}'")
+
+ data = UnknownErrorData.from_dict(d.pop("data"))
+
+ unknown_error = cls(
+ name=name,
+ data=data,
+ )
+
+ unknown_error.additional_properties = d
+ return unknown_error
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/unknown_error_data.py b/packages/sdk/python/src/opencode_ai/models/unknown_error_data.py
new file mode 100644
index 000000000..97139f278
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/unknown_error_data.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="UnknownErrorData")
+
+
+@_attrs_define
+class UnknownErrorData:
+ """
+ Attributes:
+ message (str):
+ """
+
+ message: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ message = self.message
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "message": message,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ message = d.pop("message")
+
+ unknown_error_data = cls(
+ message=message,
+ )
+
+ unknown_error_data.additional_properties = d
+ return unknown_error_data
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/user_message.py b/packages/sdk/python/src/opencode_ai/models/user_message.py
new file mode 100644
index 000000000..cd81dafc0
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/user_message.py
@@ -0,0 +1,91 @@
+from collections.abc import Mapping
+from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+if TYPE_CHECKING:
+ from ..models.user_message_time import UserMessageTime
+
+
+T = TypeVar("T", bound="UserMessage")
+
+
+@_attrs_define
+class UserMessage:
+ """
+ Attributes:
+ id (str):
+ session_id (str):
+ role (Literal['user']):
+ time (UserMessageTime):
+ """
+
+ id: str
+ session_id: str
+ role: Literal["user"]
+ time: "UserMessageTime"
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ id = self.id
+
+ session_id = self.session_id
+
+ role = self.role
+
+ time = self.time.to_dict()
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "id": id,
+ "sessionID": session_id,
+ "role": role,
+ "time": time,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ from ..models.user_message_time import UserMessageTime
+
+ d = dict(src_dict)
+ id = d.pop("id")
+
+ session_id = d.pop("sessionID")
+
+ role = cast(Literal["user"], d.pop("role"))
+ if role != "user":
+ raise ValueError(f"role must match const 'user', got '{role}'")
+
+ time = UserMessageTime.from_dict(d.pop("time"))
+
+ user_message = cls(
+ id=id,
+ session_id=session_id,
+ role=role,
+ time=time,
+ )
+
+ user_message.additional_properties = d
+ return user_message
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/user_message_time.py b/packages/sdk/python/src/opencode_ai/models/user_message_time.py
new file mode 100644
index 000000000..f5ef79175
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/user_message_time.py
@@ -0,0 +1,59 @@
+from collections.abc import Mapping
+from typing import Any, TypeVar
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="UserMessageTime")
+
+
+@_attrs_define
+class UserMessageTime:
+ """
+ Attributes:
+ created (float):
+ """
+
+ created: float
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ created = self.created
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "created": created,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ created = d.pop("created")
+
+ user_message_time = cls(
+ created=created,
+ )
+
+ user_message_time.additional_properties = d
+ return user_message_time
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/models/well_known_auth.py b/packages/sdk/python/src/opencode_ai/models/well_known_auth.py
new file mode 100644
index 000000000..a52936f31
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/models/well_known_auth.py
@@ -0,0 +1,77 @@
+from collections.abc import Mapping
+from typing import Any, Literal, TypeVar, cast
+
+from attrs import define as _attrs_define
+from attrs import field as _attrs_field
+
+T = TypeVar("T", bound="WellKnownAuth")
+
+
+@_attrs_define
+class WellKnownAuth:
+ """
+ Attributes:
+ type_ (Literal['wellknown']):
+ key (str):
+ token (str):
+ """
+
+ type_: Literal["wellknown"]
+ key: str
+ token: str
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
+
+ def to_dict(self) -> dict[str, Any]:
+ type_ = self.type_
+
+ key = self.key
+
+ token = self.token
+
+ field_dict: dict[str, Any] = {}
+ field_dict.update(self.additional_properties)
+ field_dict.update(
+ {
+ "type": type_,
+ "key": key,
+ "token": token,
+ }
+ )
+
+ return field_dict
+
+ @classmethod
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
+ d = dict(src_dict)
+ type_ = cast(Literal["wellknown"], d.pop("type"))
+ if type_ != "wellknown":
+ raise ValueError(f"type must match const 'wellknown', got '{type_}'")
+
+ key = d.pop("key")
+
+ token = d.pop("token")
+
+ well_known_auth = cls(
+ type_=type_,
+ key=key,
+ token=token,
+ )
+
+ well_known_auth.additional_properties = d
+ return well_known_auth
+
+ @property
+ def additional_keys(self) -> list[str]:
+ return list(self.additional_properties.keys())
+
+ def __getitem__(self, key: str) -> Any:
+ return self.additional_properties[key]
+
+ def __setitem__(self, key: str, value: Any) -> None:
+ self.additional_properties[key] = value
+
+ def __delitem__(self, key: str) -> None:
+ del self.additional_properties[key]
+
+ def __contains__(self, key: str) -> bool:
+ return key in self.additional_properties
diff --git a/packages/sdk/python/src/opencode_ai/py.typed b/packages/sdk/python/src/opencode_ai/py.typed
new file mode 100644
index 000000000..1aad32711
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/py.typed
@@ -0,0 +1 @@
+# Marker file for PEP 561 \ No newline at end of file
diff --git a/packages/sdk/python/src/opencode_ai/types.py b/packages/sdk/python/src/opencode_ai/types.py
new file mode 100644
index 000000000..1b96ca408
--- /dev/null
+++ b/packages/sdk/python/src/opencode_ai/types.py
@@ -0,0 +1,54 @@
+"""Contains some shared types for properties"""
+
+from collections.abc import Mapping, MutableMapping
+from http import HTTPStatus
+from typing import IO, BinaryIO, Generic, Literal, Optional, TypeVar, Union
+
+from attrs import define
+
+
+class Unset:
+ def __bool__(self) -> Literal[False]:
+ return False
+
+
+UNSET: Unset = Unset()
+
+# The types that `httpx.Client(files=)` can accept, copied from that library.
+FileContent = Union[IO[bytes], bytes, str]
+FileTypes = Union[
+ # (filename, file (or bytes), content_type)
+ tuple[Optional[str], FileContent, Optional[str]],
+ # (filename, file (or bytes), content_type, headers)
+ tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]],
+]
+RequestFiles = list[tuple[str, FileTypes]]
+
+
+@define
+class File:
+ """Contains information for file uploads"""
+
+ payload: BinaryIO
+ file_name: Optional[str] = None
+ mime_type: Optional[str] = None
+
+ def to_tuple(self) -> FileTypes:
+ """Return a tuple representation that httpx will accept for multipart/form-data"""
+ return self.file_name, self.payload, self.mime_type
+
+
+T = TypeVar("T")
+
+
+@define
+class Response(Generic[T]):
+ """A response from an endpoint"""
+
+ status_code: HTTPStatus
+ content: bytes
+ headers: MutableMapping[str, str]
+ parsed: Optional[T]
+
+
+__all__ = ["UNSET", "File", "FileTypes", "RequestFiles", "Response", "Unset"]