From 38ba876ea973415620e3a1b132f3ad7f78772233 Mon Sep 17 00:00:00 2001 From: Steve Coffey Date: Tue, 21 Apr 2026 10:23:27 -0700 Subject: [PATCH] Refresh generated Python app-server SDK types (#18862) This is the first step in splitting the Python SDK PyPI publish work into reviewable layers: land the generated SDK refresh by itself before changing packaging mechanics. The next PRs will make the runtime wheel publishable, then wire the SDK package/version pinning to that runtime. ## Summary - Refresh generated Python app-server v2 models and notification registry from the current schema. - Update the public API signature expectations for the newly generated kwargs. ## Stack - PR 1 of 3 for the Python SDK PyPI publishing split. - Follow-up PRs will handle runtime wheel publishing mechanics, then SDK/package version pinning. ## Tests - `uv run --extra dev pytest` in `sdk/python` -> 51 passed, 37 skipped. --- sdk/python/src/codex_app_server/api.py | 28 +- .../generated/notification_registry.py | 14 +- .../src/codex_app_server/generated/v2_all.py | 1765 +++++++++++++---- .../tests/test_public_api_signatures.py | 16 +- 4 files changed, 1467 insertions(+), 356 deletions(-) diff --git a/sdk/python/src/codex_app_server/api.py b/sdk/python/src/codex_app_server/api.py index 5009d9bbf..c330e3f74 100644 --- a/sdk/python/src/codex_app_server/api.py +++ b/sdk/python/src/codex_app_server/api.py @@ -105,7 +105,11 @@ class Codex: normalized_server_name = (server_name or "").strip() normalized_server_version = (server_version or "").strip() - if not user_agent or not normalized_server_name or not normalized_server_version: + if ( + not user_agent + or not normalized_server_name + or not normalized_server_version + ): raise RuntimeError( "initialize response missing required metadata " f"(user_agent={user_agent!r}, server_name={normalized_server_name!r}, server_version={normalized_server_version!r})" @@ -146,6 +150,7 @@ class Codex: sandbox: SandboxMode | None = None, service_name: str | None = None, service_tier: ServiceTier | None = None, + session_start_source: ThreadStartSource | None = None, ) -> Thread: params = ThreadStartParams( approval_policy=approval_policy, @@ -161,6 +166,7 @@ class Codex: sandbox=sandbox, service_name=service_name, service_tier=service_tier, + session_start_source=session_start_source, ) started = self._client.thread_start(params) return Thread(self._client, started.thread.id) @@ -174,6 +180,7 @@ class Codex: limit: int | None = None, model_providers: list[str] | None = None, search_term: str | None = None, + sort_direction: SortDirection | None = None, sort_key: ThreadSortKey | None = None, source_kinds: list[ThreadSourceKind] | None = None, ) -> ThreadListResponse: @@ -184,6 +191,7 @@ class Codex: limit=limit, model_providers=model_providers, search_term=search_term, + sort_direction=sort_direction, sort_key=sort_key, source_kinds=source_kinds, ) @@ -336,6 +344,7 @@ class AsyncCodex: sandbox: SandboxMode | None = None, service_name: str | None = None, service_tier: ServiceTier | None = None, + session_start_source: ThreadStartSource | None = None, ) -> AsyncThread: await self._ensure_initialized() params = ThreadStartParams( @@ -352,6 +361,7 @@ class AsyncCodex: sandbox=sandbox, service_name=service_name, service_tier=service_tier, + session_start_source=session_start_source, ) started = await self._client.thread_start(params) return AsyncThread(self, started.thread.id) @@ -365,6 +375,7 @@ class AsyncCodex: limit: int | None = None, model_providers: list[str] | None = None, search_term: str | None = None, + sort_direction: SortDirection | None = None, sort_key: ThreadSortKey | None = None, source_kinds: list[ThreadSourceKind] | None = None, ) -> ThreadListResponse: @@ -376,6 +387,7 @@ class AsyncCodex: limit=limit, model_providers=model_providers, search_term=search_term, + sort_direction=sort_direction, sort_key=sort_key, source_kinds=source_kinds, ) @@ -629,7 +641,9 @@ class AsyncThread: async def read(self, *, include_turns: bool = False) -> ThreadReadResponse: await self._codex._ensure_initialized() - return await self._codex._client.thread_read(self.id, include_turns=include_turns) + return await self._codex._client.thread_read( + self.id, include_turns=include_turns + ) async def set_name(self, name: str) -> ThreadSetNameResponse: await self._codex._ensure_initialized() @@ -674,7 +688,10 @@ class TurnHandle: try: for event in stream: payload = event.payload - if isinstance(payload, TurnCompletedNotification) and payload.turn.id == self.id: + if ( + isinstance(payload, TurnCompletedNotification) + and payload.turn.id == self.id + ): completed = payload finally: stream.close() @@ -725,7 +742,10 @@ class AsyncTurnHandle: try: async for event in stream: payload = event.payload - if isinstance(payload, TurnCompletedNotification) and payload.turn.id == self.id: + if ( + isinstance(payload, TurnCompletedNotification) + and payload.turn.id == self.id + ): completed = payload finally: await stream.aclose() diff --git a/sdk/python/src/codex_app_server/generated/notification_registry.py b/sdk/python/src/codex_app_server/generated/notification_registry.py index ca885d92d..ab6f87f11 100644 --- a/sdk/python/src/codex_app_server/generated/notification_registry.py +++ b/sdk/python/src/codex_app_server/generated/notification_registry.py @@ -16,7 +16,9 @@ from .v2_all import ConfigWarningNotification from .v2_all import ContextCompactedNotification from .v2_all import DeprecationNoticeNotification from .v2_all import ErrorNotification +from .v2_all import ExternalAgentConfigImportCompletedNotification from .v2_all import FileChangeOutputDeltaNotification +from .v2_all import FileChangePatchUpdatedNotification from .v2_all import FsChangedNotification from .v2_all import FuzzyFileSearchSessionCompletedNotification from .v2_all import FuzzyFileSearchSessionUpdatedNotification @@ -44,8 +46,10 @@ from .v2_all import ThreadRealtimeClosedNotification from .v2_all import ThreadRealtimeErrorNotification from .v2_all import ThreadRealtimeItemAddedNotification from .v2_all import ThreadRealtimeOutputAudioDeltaNotification +from .v2_all import ThreadRealtimeSdpNotification from .v2_all import ThreadRealtimeStartedNotification -from .v2_all import ThreadRealtimeTranscriptUpdatedNotification +from .v2_all import ThreadRealtimeTranscriptDeltaNotification +from .v2_all import ThreadRealtimeTranscriptDoneNotification from .v2_all import ThreadStartedNotification from .v2_all import ThreadStatusChangedNotification from .v2_all import ThreadTokenUsageUpdatedNotification @@ -54,6 +58,7 @@ from .v2_all import TurnCompletedNotification from .v2_all import TurnDiffUpdatedNotification from .v2_all import TurnPlanUpdatedNotification from .v2_all import TurnStartedNotification +from .v2_all import WarningNotification from .v2_all import WindowsSandboxSetupCompletedNotification from .v2_all import WindowsWorldWritableWarningNotification @@ -66,6 +71,7 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = { "configWarning": ConfigWarningNotification, "deprecationNotice": DeprecationNoticeNotification, "error": ErrorNotification, + "externalAgentConfig/import/completed": ExternalAgentConfigImportCompletedNotification, "fs/changed": FsChangedNotification, "fuzzyFileSearch/sessionCompleted": FuzzyFileSearchSessionCompletedNotification, "fuzzyFileSearch/sessionUpdated": FuzzyFileSearchSessionUpdatedNotification, @@ -78,6 +84,7 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = { "item/commandExecution/terminalInteraction": TerminalInteractionNotification, "item/completed": ItemCompletedNotification, "item/fileChange/outputDelta": FileChangeOutputDeltaNotification, + "item/fileChange/patchUpdated": FileChangePatchUpdatedNotification, "item/mcpToolCall/progress": McpToolCallProgressNotification, "item/plan/delta": PlanDeltaNotification, "item/reasoning/summaryPartAdded": ReasoningSummaryPartAddedNotification, @@ -97,8 +104,10 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = { "thread/realtime/error": ThreadRealtimeErrorNotification, "thread/realtime/itemAdded": ThreadRealtimeItemAddedNotification, "thread/realtime/outputAudio/delta": ThreadRealtimeOutputAudioDeltaNotification, + "thread/realtime/sdp": ThreadRealtimeSdpNotification, "thread/realtime/started": ThreadRealtimeStartedNotification, - "thread/realtime/transcriptUpdated": ThreadRealtimeTranscriptUpdatedNotification, + "thread/realtime/transcript/delta": ThreadRealtimeTranscriptDeltaNotification, + "thread/realtime/transcript/done": ThreadRealtimeTranscriptDoneNotification, "thread/started": ThreadStartedNotification, "thread/status/changed": ThreadStatusChangedNotification, "thread/tokenUsage/updated": ThreadTokenUsageUpdatedNotification, @@ -107,6 +116,7 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = { "turn/diff/updated": TurnDiffUpdatedNotification, "turn/plan/updated": TurnPlanUpdatedNotification, "turn/started": TurnStartedNotification, + "warning": WarningNotification, "windows/worldWritableWarning": WindowsWorldWritableWarningNotification, "windowsSandbox/setupCompleted": WindowsSandboxSetupCompletedNotification, } diff --git a/sdk/python/src/codex_app_server/generated/v2_all.py b/sdk/python/src/codex_app_server/generated/v2_all.py index 21d4968c3..c75b3e89a 100644 --- a/sdk/python/src/codex_app_server/generated/v2_all.py +++ b/sdk/python/src/codex_app_server/generated/v2_all.py @@ -42,6 +42,23 @@ class AccountLoginCompletedNotification(BaseModel): success: bool +class AddCreditsNudgeCreditType(Enum): + credits = "credits" + usage_limit = "usage_limit" + + +class AddCreditsNudgeEmailStatus(Enum): + sent = "sent" + cooldown_active = "cooldown_active" + + +class AdditionalNetworkPermissions(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + enabled: bool | None = None + + class AgentMessageDeltaNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -211,6 +228,18 @@ class AuthMode(Enum): chatgpt_auth_tokens = "chatgptAuthTokens" +class AutoReviewDecisionSource(RootModel[Literal["agent"]]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: Annotated[ + Literal["agent"], + Field( + description="[UNSTABLE] Source that produced a terminal approval auto-review decision." + ), + ] + + class ByteRange(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -350,7 +379,7 @@ class ReadCommandAction(BaseModel): ) command: str name: str - path: str + path: AbsolutePathBuf type: Annotated[Literal["read"], Field(title="ReadCommandActionType")] @@ -636,14 +665,6 @@ class InputTextContentItem(BaseModel): type: Annotated[Literal["input_text"], Field(title="InputTextContentItemType")] -class InputImageContentItem(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - image_url: str - type: Annotated[Literal["input_image"], Field(title="InputImageContentItemType")] - - class OutputTextContentItem(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -652,15 +673,6 @@ class OutputTextContentItem(BaseModel): type: Annotated[Literal["output_text"], Field(title="OutputTextContentItemType")] -class ContentItem( - RootModel[InputTextContentItem | InputImageContentItem | OutputTextContentItem] -): - model_config = ConfigDict( - populate_by_name=True, - ) - root: InputTextContentItem | InputImageContentItem | OutputTextContentItem - - class ContextCompactedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -742,6 +754,7 @@ class DynamicToolSpec(BaseModel): description: str input_schema: Annotated[Any, Field(alias="inputSchema")] name: str + namespace: str | None = None class ExperimentalFeatureEnablementSetParams(BaseModel): @@ -810,6 +823,13 @@ class ExternalAgentConfigDetectParams(BaseModel): ] = None +class ExternalAgentConfigImportCompletedNotification(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) + + class ExternalAgentConfigImportResponse(BaseModel): pass model_config = ConfigDict( @@ -821,6 +841,7 @@ class ExternalAgentConfigMigrationItemType(Enum): agents_md = "AGENTS_MD" config = "CONFIG" skills = "SKILLS" + plugins = "PLUGINS" mcp_server_config = "MCP_SERVER_CONFIG" @@ -832,6 +853,7 @@ class FeedbackUploadParams(BaseModel): extra_log_files: Annotated[list[str] | None, Field(alias="extraLogFiles")] = None include_logs: Annotated[bool, Field(alias="includeLogs")] reason: str | None = None + tags: dict[str, Any] | None = None thread_id: Annotated[str | None, Field(alias="threadId")] = None @@ -852,6 +874,107 @@ class FileChangeOutputDeltaNotification(BaseModel): turn_id: Annotated[str, Field(alias="turnId")] +class FileSystemAccessMode(Enum): + read = "read" + write = "write" + none = "none" + + +class PathFileSystemPath(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + path: AbsolutePathBuf + type: Annotated[Literal["path"], Field(title="PathFileSystemPathType")] + + +class GlobPatternFileSystemPath(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + pattern: str + type: Annotated[ + Literal["glob_pattern"], Field(title="GlobPatternFileSystemPathType") + ] + + +class RootFileSystemSpecialPath(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + kind: Literal["root"] + + +class MinimalFileSystemSpecialPath(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + kind: Literal["minimal"] + + +class CurrentWorkingDirectoryFileSystemSpecialPath(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + kind: Literal["current_working_directory"] + + +class KindFileSystemSpecialPath(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + kind: Literal["project_roots"] + subpath: str | None = None + + +class TmpdirFileSystemSpecialPath(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + kind: Literal["tmpdir"] + + +class SlashTmpFileSystemSpecialPath(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + kind: Literal["slash_tmp"] + + +class FileSystemSpecialPath1(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + kind: Literal["unknown"] + path: str + subpath: str | None = None + + +class FileSystemSpecialPath( + RootModel[ + RootFileSystemSpecialPath + | MinimalFileSystemSpecialPath + | CurrentWorkingDirectoryFileSystemSpecialPath + | KindFileSystemSpecialPath + | TmpdirFileSystemSpecialPath + | SlashTmpFileSystemSpecialPath + | FileSystemSpecialPath1 + ] +): + model_config = ConfigDict( + populate_by_name=True, + ) + root: ( + RootFileSystemSpecialPath + | MinimalFileSystemSpecialPath + | CurrentWorkingDirectoryFileSystemSpecialPath + | KindFileSystemSpecialPath + | TmpdirFileSystemSpecialPath + | SlashTmpFileSystemSpecialPath + | FileSystemSpecialPath1 + ) + + class ForcedLoginMethod(Enum): chatgpt = "chatgpt" api = "api" @@ -870,7 +993,10 @@ class FsChangedNotification(BaseModel): ] watch_id: Annotated[ str, - Field(alias="watchId", description="Watch identifier returned by `fs/watch`."), + Field( + alias="watchId", + description="Watch identifier previously provided to `fs/watch`.", + ), ] @@ -941,15 +1067,19 @@ class FsGetMetadataResponse(BaseModel): is_directory: Annotated[ bool, Field( - alias="isDirectory", - description="Whether the path currently resolves to a directory.", + alias="isDirectory", description="Whether the path resolves to a directory." ), ] is_file: Annotated[ bool, Field( - alias="isFile", - description="Whether the path currently resolves to a regular file.", + alias="isFile", description="Whether the path resolves to a regular file." + ), + ] + is_symlink: Annotated[ + bool, + Field( + alias="isSymlink", description="Whether the path itself is a symbolic link." ), ] modified_at_ms: Annotated[ @@ -1054,7 +1184,10 @@ class FsUnwatchParams(BaseModel): ) watch_id: Annotated[ str, - Field(alias="watchId", description="Watch identifier returned by `fs/watch`."), + Field( + alias="watchId", + description="Watch identifier previously provided to `fs/watch`.", + ), ] @@ -1072,6 +1205,13 @@ class FsWatchParams(BaseModel): path: Annotated[ AbsolutePathBuf, Field(description="Absolute file or directory path to watch.") ] + watch_id: Annotated[ + str, + Field( + alias="watchId", + description="Connection-scoped watch identifier used for `fs/unwatch` and `fs/changed`.", + ), + ] class FsWatchResponse(BaseModel): @@ -1082,13 +1222,6 @@ class FsWatchResponse(BaseModel): AbsolutePathBuf, Field(description="Canonicalized path associated with the watch."), ] - watch_id: Annotated[ - str, - Field( - alias="watchId", - description="Connection-scoped watch identifier used for `fs/unwatch` and `fs/changed`.", - ), - ] class FsWriteFileParams(BaseModel): @@ -1199,21 +1332,62 @@ class GitInfo(BaseModel): sha: str | None = None +class ApplyPatchGuardianApprovalReviewAction(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + cwd: AbsolutePathBuf + files: list[AbsolutePathBuf] + type: Annotated[ + Literal["applyPatch"], Field(title="ApplyPatchGuardianApprovalReviewActionType") + ] + + +class McpToolCallGuardianApprovalReviewAction(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + connector_id: Annotated[str | None, Field(alias="connectorId")] = None + connector_name: Annotated[str | None, Field(alias="connectorName")] = None + server: str + tool_name: Annotated[str, Field(alias="toolName")] + tool_title: Annotated[str | None, Field(alias="toolTitle")] = None + type: Annotated[ + Literal["mcpToolCall"], + Field(title="McpToolCallGuardianApprovalReviewActionType"), + ] + + class GuardianApprovalReviewStatus(Enum): in_progress = "inProgress" approved = "approved" denied = "denied" + timed_out = "timedOut" aborted = "aborted" +class GuardianCommandSource(Enum): + shell = "shell" + unified_exec = "unifiedExec" + + class GuardianRiskLevel(Enum): low = "low" medium = "medium" high = "high" + critical = "critical" + + +class GuardianUserAuthorization(Enum): + unknown = "unknown" + low = "low" + medium = "medium" + high = "high" class HookEventName(Enum): pre_tool_use = "preToolUse" + permission_request = "permissionRequest" post_tool_use = "postToolUse" session_start = "sessionStart" user_prompt_submit = "userPromptSubmit" @@ -1260,6 +1434,17 @@ class HookScope(Enum): turn = "turn" +class HookSource(Enum): + system = "system" + user = "user" + project = "project" + mdm = "mdm" + session_flags = "sessionFlags" + legacy_managed_config_file = "legacyManagedConfigFile" + legacy_managed_config_mdm = "legacyManagedConfigMdm" + unknown = "unknown" + + class ImageDetail(Enum): auto = "auto" low = "low" @@ -1300,22 +1485,6 @@ class InputModality(Enum): image = "image" -class ListMcpServerStatusParams(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - cursor: Annotated[ - str | None, - Field(description="Opaque pagination cursor returned by a previous call."), - ] = None - limit: Annotated[ - int | None, - Field( - description="Optional page size; defaults to a server-defined value.", ge=0 - ), - ] = None - - class ExecLocalShellAction(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -1358,6 +1527,16 @@ class ChatgptLoginAccountParams(BaseModel): ] +class ChatgptDeviceCodeLoginAccountParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + type: Annotated[ + Literal["chatgptDeviceCode"], + Field(title="ChatgptDeviceCodev2::LoginAccountParamsType"), + ] + + class ChatgptAuthTokensLoginAccountParams(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -1393,6 +1572,7 @@ class LoginAccountParams( RootModel[ ApiKeyLoginAccountParams | ChatgptLoginAccountParams + | ChatgptDeviceCodeLoginAccountParams | ChatgptAuthTokensLoginAccountParams ] ): @@ -1402,6 +1582,7 @@ class LoginAccountParams( root: Annotated[ ApiKeyLoginAccountParams | ChatgptLoginAccountParams + | ChatgptDeviceCodeLoginAccountParams | ChatgptAuthTokensLoginAccountParams, Field(title="LoginAccountParams"), ] @@ -1433,6 +1614,31 @@ class ChatgptLoginAccountResponse(BaseModel): ] +class ChatgptDeviceCodeLoginAccountResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + login_id: Annotated[str, Field(alias="loginId")] + type: Annotated[ + Literal["chatgptDeviceCode"], + Field(title="ChatgptDeviceCodev2::LoginAccountResponseType"), + ] + user_code: Annotated[ + str, + Field( + alias="userCode", + description="One-time code the user must enter after signing in.", + ), + ] + verification_url: Annotated[ + str, + Field( + alias="verificationUrl", + description="URL the client should open in a browser to complete device code authorization.", + ), + ] + + class ChatgptAuthTokensLoginAccountResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -1447,6 +1653,7 @@ class LoginAccountResponse( RootModel[ ApiKeyLoginAccountResponse | ChatgptLoginAccountResponse + | ChatgptDeviceCodeLoginAccountResponse | ChatgptAuthTokensLoginAccountResponse ] ): @@ -1456,6 +1663,7 @@ class LoginAccountResponse( root: Annotated[ ApiKeyLoginAccountResponse | ChatgptLoginAccountResponse + | ChatgptDeviceCodeLoginAccountResponse | ChatgptAuthTokensLoginAccountResponse, Field(title="LoginAccountResponse"), ] @@ -1468,6 +1676,24 @@ class LogoutAccountResponse(BaseModel): ) +class MarketplaceAddParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + ref_name: Annotated[str | None, Field(alias="refName")] = None + source: str + sparse_paths: Annotated[list[str] | None, Field(alias="sparsePaths")] = None + + +class MarketplaceAddResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + already_added: Annotated[bool, Field(alias="alreadyAdded")] + installed_root: Annotated[AbsolutePathBuf, Field(alias="installedRoot")] + marketplace_name: Annotated[str, Field(alias="marketplaceName")] + + class MarketplaceInterface(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -1483,6 +1709,23 @@ class MarketplaceLoadErrorInfo(BaseModel): message: str +class MarketplaceRemoveParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + marketplace_name: Annotated[str, Field(alias="marketplaceName")] + + +class MarketplaceRemoveResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + installed_root: Annotated[AbsolutePathBuf | None, Field(alias="installedRoot")] = ( + None + ) + marketplace_name: Annotated[str, Field(alias="marketplaceName")] + + class McpAuthStatus(Enum): unsupported = "unsupported" not_logged_in = "notLoggedIn" @@ -1490,6 +1733,15 @@ class McpAuthStatus(Enum): o_auth = "oAuth" +class McpResourceReadParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + server: str + thread_id: Annotated[str | None, Field(alias="threadId")] = None + uri: str + + class McpServerOauthLoginCompletedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -1529,6 +1781,11 @@ class McpServerStartupState(Enum): cancelled = "cancelled" +class McpServerStatusDetail(Enum): + full = "full" + tools_and_auth_only = "toolsAndAuthOnly" + + class McpServerStatusUpdatedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -1538,6 +1795,27 @@ class McpServerStatusUpdatedNotification(BaseModel): status: McpServerStartupState +class McpServerToolCallParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + field_meta: Annotated[Any | None, Field(alias="_meta")] = None + arguments: Any | None = None + server: str + thread_id: Annotated[str, Field(alias="threadId")] + tool: str + + +class McpServerToolCallResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + field_meta: Annotated[Any | None, Field(alias="_meta")] = None + content: list + is_error: Annotated[bool | None, Field(alias="isError")] = None + structured_content: Annotated[Any | None, Field(alias="structuredContent")] = None + + class McpToolCallError(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -1559,6 +1837,7 @@ class McpToolCallResult(BaseModel): model_config = ConfigDict( populate_by_name=True, ) + field_meta: Annotated[Any | None, Field(alias="_meta")] = None content: list structured_content: Annotated[Any | None, Field(alias="structuredContent")] = None @@ -1658,28 +1937,81 @@ class NetworkAccess(Enum): enabled = "enabled" +class NetworkApprovalProtocol(Enum): + http = "http" + https = "https" + socks5_tcp = "socks5Tcp" + socks5_udp = "socks5Udp" + + +class NetworkDomainPermission(Enum): + allow = "allow" + deny = "deny" + + class NetworkRequirements(BaseModel): model_config = ConfigDict( populate_by_name=True, ) allow_local_binding: Annotated[bool | None, Field(alias="allowLocalBinding")] = None - allow_unix_sockets: Annotated[list[str] | None, Field(alias="allowUnixSockets")] = ( - None - ) + allow_unix_sockets: Annotated[ + list[str] | None, + Field( + alias="allowUnixSockets", + description="Legacy compatibility view derived from `unix_sockets`.", + ), + ] = None allow_upstream_proxy: Annotated[bool | None, Field(alias="allowUpstreamProxy")] = ( None ) - allowed_domains: Annotated[list[str] | None, Field(alias="allowedDomains")] = None + allowed_domains: Annotated[ + list[str] | None, + Field( + alias="allowedDomains", + description="Legacy compatibility view derived from `domains`.", + ), + ] = None dangerously_allow_all_unix_sockets: Annotated[ bool | None, Field(alias="dangerouslyAllowAllUnixSockets") ] = None dangerously_allow_non_loopback_proxy: Annotated[ bool | None, Field(alias="dangerouslyAllowNonLoopbackProxy") ] = None - denied_domains: Annotated[list[str] | None, Field(alias="deniedDomains")] = None + denied_domains: Annotated[ + list[str] | None, + Field( + alias="deniedDomains", + description="Legacy compatibility view derived from `domains`.", + ), + ] = None + domains: Annotated[ + dict[str, Any] | None, + Field( + description="Canonical network permission map for `experimental_network`." + ), + ] = None enabled: bool | None = None http_port: Annotated[int | None, Field(alias="httpPort", ge=0)] = None + managed_allowed_domains_only: Annotated[ + bool | None, + Field( + alias="managedAllowedDomainsOnly", + description="When true, only managed allowlist entries are respected while managed network enforcement is active.", + ), + ] = None socks_port: Annotated[int | None, Field(alias="socksPort", ge=0)] = None + unix_sockets: Annotated[ + dict[str, Any] | None, + Field( + alias="unixSockets", + description="Canonical unix socket permission map for `experimental_network`.", + ), + ] = None + + +class NetworkUnixSocketPermission(Enum): + allow = "allow" + none = "none" class NonSteerableTurnKind(Enum): @@ -1746,6 +2078,7 @@ class PlanType(Enum): go = "go" plus = "plus" pro = "pro" + prolite = "prolite" team = "team" self_serve_business_usage_based = "self_serve_business_usage_based" business = "business" @@ -1764,15 +2097,13 @@ class PluginInstallParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - force_remote_sync: Annotated[ - bool | None, - Field( - alias="forceRemoteSync", - description="When true, apply the remote plugin change before the local install flow.", - ), + marketplace_path: Annotated[ + AbsolutePathBuf | None, Field(alias="marketplacePath") ] = None - marketplace_path: Annotated[AbsolutePathBuf, Field(alias="marketplacePath")] plugin_name: Annotated[str, Field(alias="pluginName")] + remote_marketplace_name: Annotated[ + str | None, Field(alias="remoteMarketplaceName") + ] = None class PluginInstallPolicy(Enum): @@ -1796,7 +2127,20 @@ class PluginInterface(BaseModel): brand_color: Annotated[str | None, Field(alias="brandColor")] = None capabilities: list[str] category: str | None = None - composer_icon: Annotated[AbsolutePathBuf | None, Field(alias="composerIcon")] = None + composer_icon: Annotated[ + AbsolutePathBuf | None, + Field( + alias="composerIcon", + description="Local composer icon path, resolved from the installed plugin package.", + ), + ] = None + composer_icon_url: Annotated[ + str | None, + Field( + alias="composerIconUrl", + description="Remote composer icon URL from the plugin catalog.", + ), + ] = None default_prompt: Annotated[ list[str] | None, Field( @@ -1806,10 +2150,31 @@ class PluginInterface(BaseModel): ] = None developer_name: Annotated[str | None, Field(alias="developerName")] = None display_name: Annotated[str | None, Field(alias="displayName")] = None - logo: AbsolutePathBuf | None = None + logo: Annotated[ + AbsolutePathBuf | None, + Field( + description="Local logo path, resolved from the installed plugin package." + ), + ] = None + logo_url: Annotated[ + str | None, + Field(alias="logoUrl", description="Remote logo URL from the plugin catalog."), + ] = None long_description: Annotated[str | None, Field(alias="longDescription")] = None privacy_policy_url: Annotated[str | None, Field(alias="privacyPolicyUrl")] = None - screenshots: list[AbsolutePathBuf] + screenshot_urls: Annotated[ + list[str], + Field( + alias="screenshotUrls", + description="Remote screenshot URLs from the plugin catalog.", + ), + ] + screenshots: Annotated[ + list[AbsolutePathBuf], + Field( + description="Local screenshot paths, resolved from the installed plugin package." + ), + ] short_description: Annotated[str | None, Field(alias="shortDescription")] = None terms_of_service_url: Annotated[str | None, Field(alias="termsOfServiceUrl")] = None website_url: Annotated[str | None, Field(alias="websiteUrl")] = None @@ -1825,21 +2190,19 @@ class PluginListParams(BaseModel): description="Optional working directories used to discover repo marketplaces. When omitted, only home-scoped marketplaces and the official curated marketplace are considered." ), ] = None - force_remote_sync: Annotated[ - bool | None, - Field( - alias="forceRemoteSync", - description="When true, reconcile the official curated marketplace against the remote plugin state before listing marketplaces.", - ), - ] = None class PluginReadParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - marketplace_path: Annotated[AbsolutePathBuf, Field(alias="marketplacePath")] + marketplace_path: Annotated[ + AbsolutePathBuf | None, Field(alias="marketplacePath") + ] = None plugin_name: Annotated[str, Field(alias="pluginName")] + remote_marketplace_name: Annotated[ + str | None, Field(alias="remoteMarketplaceName") + ] = None class LocalPluginSource(BaseModel): @@ -1850,11 +2213,29 @@ class LocalPluginSource(BaseModel): type: Annotated[Literal["local"], Field(title="LocalPluginSourceType")] -class PluginSource(RootModel[LocalPluginSource]): +class GitPluginSource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - root: LocalPluginSource + path: str | None = None + ref_name: Annotated[str | None, Field(alias="refName")] = None + sha: str | None = None + type: Annotated[Literal["git"], Field(title="GitPluginSourceType")] + url: str + + +class RemotePluginSource(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + type: Annotated[Literal["remote"], Field(title="RemotePluginSourceType")] + + +class PluginSource(RootModel[LocalPluginSource | GitPluginSource | RemotePluginSource]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: LocalPluginSource | GitPluginSource | RemotePluginSource class PluginSummary(BaseModel): @@ -1875,13 +2256,6 @@ class PluginUninstallParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - force_remote_sync: Annotated[ - bool | None, - Field( - alias="forceRemoteSync", - description="When true, apply the remote plugin change before the local uninstall flow.", - ), - ] = None plugin_id: Annotated[str, Field(alias="pluginId")] @@ -1892,6 +2266,22 @@ class PluginUninstallResponse(BaseModel): ) +class PluginsMigration(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + marketplace_name: Annotated[str, Field(alias="marketplaceName")] + plugin_names: Annotated[list[str], Field(alias="pluginNames")] + + +class RateLimitReachedType(Enum): + rate_limit_reached = "rate_limit_reached" + workspace_owner_credits_depleted = "workspace_owner_credits_depleted" + workspace_member_credits_depleted = "workspace_member_credits_depleted" + workspace_owner_usage_limit_reached = "workspace_owner_usage_limit_reached" + workspace_member_usage_limit_reached = "workspace_member_usage_limit_reached" + + class RateLimitWindow(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -1935,6 +2325,43 @@ class RealtimeConversationVersion(Enum): v2 = "v2" +class RealtimeOutputModality(Enum): + text = "text" + audio = "audio" + + +class RealtimeVoice(Enum): + alloy = "alloy" + arbor = "arbor" + ash = "ash" + ballad = "ballad" + breeze = "breeze" + cedar = "cedar" + coral = "coral" + cove = "cove" + echo = "echo" + ember = "ember" + juniper = "juniper" + maple = "maple" + marin = "marin" + sage = "sage" + shimmer = "shimmer" + sol = "sol" + spruce = "spruce" + vale = "vale" + verse = "verse" + + +class RealtimeVoicesList(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + default_v1: Annotated[RealtimeVoice, Field(alias="defaultV1")] + default_v2: Annotated[RealtimeVoice, Field(alias="defaultV2")] + v1: list[RealtimeVoice] + v2: list[RealtimeVoice] + + class ReasoningEffort(Enum): none = "none" minimal = "minimal" @@ -2078,6 +2505,38 @@ class Resource(BaseModel): uri: str +class ResourceContent1(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + field_meta: Annotated[Any | None, Field(alias="_meta")] = None + mime_type: Annotated[str | None, Field(alias="mimeType")] = None + text: str + uri: Annotated[str, Field(description="The URI of this resource.")] + + +class ResourceContent2(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + field_meta: Annotated[Any | None, Field(alias="_meta")] = None + blob: str + mime_type: Annotated[str | None, Field(alias="mimeType")] = None + uri: Annotated[str, Field(description="The URI of this resource.")] + + +class ResourceContent(RootModel[ResourceContent1 | ResourceContent2]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: Annotated[ + ResourceContent1 | ResourceContent2, + Field( + description="Contents returned when reading a resource from an MCP server." + ), + ] + + class ResourceTemplate(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -2090,18 +2549,6 @@ class ResourceTemplate(BaseModel): uri_template: Annotated[str, Field(alias="uriTemplate")] -class MessageResponseItem(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - content: list[ContentItem] - end_turn: bool | None = None - id: str | None = None - phase: MessagePhase | None = None - role: str - type: Annotated[Literal["message"], Field(title="MessageResponseItemType")] - - class ReasoningResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -2435,6 +2882,20 @@ class SandboxWorkspaceWrite(BaseModel): writable_roots: list[str] | None = [] +class SendAddCreditsNudgeEmailParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + credit_type: Annotated[AddCreditsNudgeCreditType, Field(alias="creditType")] + + +class SendAddCreditsNudgeEmailResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + status: AddCreditsNudgeEmailStatus + + class ItemAgentMessageDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -2511,6 +2972,17 @@ class McpServerStartupStatusUpdatedServerNotification(BaseModel): params: McpServerStatusUpdatedNotification +class ExternalAgentConfigImportCompletedServerNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + method: Annotated[ + Literal["externalAgentConfig/import/completed"], + Field(title="ExternalAgentConfig/import/completedNotificationMethod"), + ] + params: ExternalAgentConfigImportCompletedNotification + + class FsChangedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -2670,8 +3142,8 @@ class SkillInterface(BaseModel): brand_color: Annotated[str | None, Field(alias="brandColor")] = None default_prompt: Annotated[str | None, Field(alias="defaultPrompt")] = None display_name: Annotated[str | None, Field(alias="displayName")] = None - icon_large: Annotated[str | None, Field(alias="iconLarge")] = None - icon_small: Annotated[str | None, Field(alias="iconSmall")] = None + icon_large: Annotated[AbsolutePathBuf | None, Field(alias="iconLarge")] = None + icon_small: Annotated[AbsolutePathBuf | None, Field(alias="iconSmall")] = None short_description: Annotated[str | None, Field(alias="shortDescription")] = None @@ -2690,7 +3162,7 @@ class SkillSummary(BaseModel): enabled: bool interface: SkillInterface | None = None name: str - path: str + path: AbsolutePathBuf short_description: Annotated[str | None, Field(alias="shortDescription")] = None @@ -2765,6 +3237,11 @@ class SkillsListParams(BaseModel): ] = None +class SortDirection(Enum): + asc = "asc" + desc = "desc" + + class SubAgentSourceValue(Enum): review = "review" compact = "compact" @@ -2913,6 +3390,26 @@ class ThreadId(RootModel[str]): root: str +class ThreadInjectItemsParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + items: Annotated[ + list, + Field( + description="Raw Responses API items to append to the thread's model-visible history." + ), + ] + thread_id: Annotated[str, Field(alias="threadId")] + + +class ThreadInjectItemsResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) + + class HookPromptThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -2960,7 +3457,9 @@ class CommandExecutionThreadItem(BaseModel): description="A best-effort parsing of the command to understand the action(s) it will perform. This returns a list of CommandAction objects because a single shell command may be composed of many commands piped together.", ), ] - cwd: Annotated[str, Field(description="The command's working directory.")] + cwd: Annotated[ + AbsolutePathBuf, Field(description="The command's working directory.") + ] duration_ms: Annotated[ int | None, Field( @@ -3000,6 +3499,7 @@ class McpToolCallThreadItem(BaseModel): ] = None error: McpToolCallError | None = None id: str + mcp_app_resource_uri: Annotated[str | None, Field(alias="mcpAppResourceUri")] = None result: McpToolCallResult | None = None server: str status: McpToolCallStatus @@ -3023,6 +3523,7 @@ class DynamicToolCallThreadItem(BaseModel): ), ] = None id: str + namespace: str | None = None status: DynamicToolCallStatus success: bool | None = None tool: str @@ -3036,7 +3537,7 @@ class ImageViewThreadItem(BaseModel): populate_by_name=True, ) id: str - path: str + path: AbsolutePathBuf type: Annotated[Literal["imageView"], Field(title="ImageViewThreadItemType")] @@ -3047,7 +3548,7 @@ class ImageGenerationThreadItem(BaseModel): id: str result: str revised_prompt: Annotated[str | None, Field(alias="revisedPrompt")] = None - saved_path: Annotated[str | None, Field(alias="savedPath")] = None + saved_path: Annotated[AbsolutePathBuf | None, Field(alias="savedPath")] = None status: str type: Annotated[ Literal["imageGeneration"], Field(title="ImageGenerationThreadItemType") @@ -3116,6 +3617,11 @@ class ThreadLoadedListResponse(BaseModel): ] = None +class ThreadMemoryMode(Enum): + enabled = "enabled" + disabled = "disabled" + + class ThreadMetadataGitInfoUpdateParams(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -3222,6 +3728,52 @@ class ThreadRealtimeOutputAudioDeltaNotification(BaseModel): thread_id: Annotated[str, Field(alias="threadId")] +class ThreadRealtimeSdpNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + sdp: str + thread_id: Annotated[str, Field(alias="threadId")] + + +class WebsocketThreadRealtimeStartTransport(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + type: Annotated[ + Literal["websocket"], Field(title="WebsocketThreadRealtimeStartTransportType") + ] + + +class WebrtcThreadRealtimeStartTransport(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + sdp: Annotated[ + str, + Field( + description="SDP offer generated by a WebRTC RTCPeerConnection after configuring audio and the realtime events data channel." + ), + ] + type: Annotated[ + Literal["webrtc"], Field(title="WebrtcThreadRealtimeStartTransportType") + ] + + +class ThreadRealtimeStartTransport( + RootModel[ + WebsocketThreadRealtimeStartTransport | WebrtcThreadRealtimeStartTransport + ] +): + model_config = ConfigDict( + populate_by_name=True, + ) + root: Annotated[ + WebsocketThreadRealtimeStartTransport | WebrtcThreadRealtimeStartTransport, + Field(description="EXPERIMENTAL - transport used by thread realtime."), + ] + + class ThreadRealtimeStartedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -3231,12 +3783,25 @@ class ThreadRealtimeStartedNotification(BaseModel): version: RealtimeConversationVersion -class ThreadRealtimeTranscriptUpdatedNotification(BaseModel): +class ThreadRealtimeTranscriptDeltaNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + delta: Annotated[ + str, Field(description="Live transcript delta from the realtime event.") + ] + role: str + thread_id: Annotated[str, Field(alias="threadId")] + + +class ThreadRealtimeTranscriptDoneNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) role: str - text: str + text: Annotated[ + str, Field(description="Final complete text for the transcript part.") + ] thread_id: Annotated[str, Field(alias="threadId")] @@ -3339,33 +3904,9 @@ class ThreadSourceKind(Enum): unknown = "unknown" -class ThreadStartParams(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = ( - None - ) - approvals_reviewer: Annotated[ - ApprovalsReviewer | None, - Field( - alias="approvalsReviewer", - description="Override where approval requests are routed for review on this thread and subsequent turns.", - ), - ] = None - base_instructions: Annotated[str | None, Field(alias="baseInstructions")] = None - config: dict[str, Any] | None = None - cwd: str | None = None - developer_instructions: Annotated[ - str | None, Field(alias="developerInstructions") - ] = None - ephemeral: bool | None = None - model: str | None = None - model_provider: Annotated[str | None, Field(alias="modelProvider")] = None - personality: Personality | None = None - sandbox: SandboxMode | None = None - service_name: Annotated[str | None, Field(alias="serviceName")] = None - service_tier: Annotated[ServiceTier | None, Field(alias="serviceTier")] = None +class ThreadStartSource(Enum): + startup = "startup" + clear = "clear" class NotLoadedThreadStatus(BaseModel): @@ -3424,6 +3965,29 @@ class ThreadStatusChangedNotification(BaseModel): thread_id: Annotated[str, Field(alias="threadId")] +class ThreadTurnsListParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + cursor: Annotated[ + str | None, + Field( + description="Opaque cursor to pass to the next call to continue after the last turn." + ), + ] = None + limit: Annotated[ + int | None, Field(description="Optional turn page size.", ge=0) + ] = None + sort_direction: Annotated[ + SortDirection | None, + Field( + alias="sortDirection", + description="Optional turn pagination direction; defaults to descending.", + ), + ] = None + thread_id: Annotated[str, Field(alias="threadId")] + + class ThreadUnarchiveParams(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -3595,6 +4159,20 @@ class Verbosity(Enum): high = "high" +class WarningNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + message: Annotated[str, Field(description="Concise warning message for the user.")] + thread_id: Annotated[ + str | None, + Field( + alias="threadId", + description="Optional thread target when the warning applies to a specific thread.", + ), + ] = None + + class SearchWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -3795,15 +4373,6 @@ class InitializeRequest(BaseModel): params: InitializeParams -class ThreadStartRequest(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - id: RequestId - method: Annotated[Literal["thread/start"], Field(title="Thread/startRequestMethod")] - params: ThreadStartParams - - class ThreadResumeRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -3934,6 +4503,28 @@ class ThreadReadRequest(BaseModel): params: ThreadReadParams +class ThreadTurnsListRequest(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + id: RequestId + method: Annotated[ + Literal["thread/turns/list"], Field(title="Thread/turns/listRequestMethod") + ] + params: ThreadTurnsListParams + + +class ThreadInjectItemsRequest(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + id: RequestId + method: Annotated[ + Literal["thread/inject_items"], Field(title="Thread/injectItemsRequestMethod") + ] + params: ThreadInjectItemsParams + + class SkillsListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -3943,6 +4534,28 @@ class SkillsListRequest(BaseModel): params: SkillsListParams +class MarketplaceAddRequest(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + id: RequestId + method: Annotated[ + Literal["marketplace/add"], Field(title="Marketplace/addRequestMethod") + ] + params: MarketplaceAddParams + + +class MarketplaceRemoveRequest(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + id: RequestId + method: Annotated[ + Literal["marketplace/remove"], Field(title="Marketplace/removeRequestMethod") + ] + params: MarketplaceRemoveParams + + class PluginListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -4158,16 +4771,27 @@ class ConfigMcpServerReloadRequest(BaseModel): params: None = None -class McpServerStatusListRequest(BaseModel): +class McpServerResourceReadRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId method: Annotated[ - Literal["mcpServerStatus/list"], - Field(title="McpServerStatus/listRequestMethod"), + Literal["mcpServer/resource/read"], + Field(title="McpServer/resource/readRequestMethod"), ] - params: ListMcpServerStatusParams + params: McpResourceReadParams + + +class McpServerToolCallRequest(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + id: RequestId + method: Annotated[ + Literal["mcpServer/tool/call"], Field(title="McpServer/tool/callRequestMethod") + ] + params: McpServerToolCallParams class WindowsSandboxSetupStartRequest(BaseModel): @@ -4228,6 +4852,18 @@ class AccountRateLimitsReadRequest(BaseModel): params: None = None +class AccountSendAddCreditsNudgeEmailRequest(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + id: RequestId + method: Annotated[ + Literal["account/sendAddCreditsNudgeEmail"], + Field(title="Account/sendAddCreditsNudgeEmailRequestMethod"), + ] + params: SendAddCreditsNudgeEmailParams + + class FeedbackUploadRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -4613,6 +5249,24 @@ class ConfigWarningNotification(BaseModel): summary: Annotated[str, Field(description="Concise summary of the warning.")] +class InputImageContentItem(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + detail: ImageDetail | None = None + image_url: str + type: Annotated[Literal["input_image"], Field(title="InputImageContentItemType")] + + +class ContentItem( + RootModel[InputTextContentItem | InputImageContentItem | OutputTextContentItem] +): + model_config = ConfigDict( + populate_by_name=True, + ) + root: InputTextContentItem | InputImageContentItem | OutputTextContentItem + + class ExperimentalFeature(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -4672,18 +5326,29 @@ class ExperimentalFeatureListResponse(BaseModel): ] = None -class ExternalAgentConfigMigrationItem(BaseModel): +class SpecialFileSystemPath(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cwd: Annotated[ - str | None, - Field( - description="Null or empty means home-scoped migration; non-empty means repo-scoped migration." - ), - ] = None - description: str - item_type: Annotated[ExternalAgentConfigMigrationItemType, Field(alias="itemType")] + type: Annotated[Literal["special"], Field(title="SpecialFileSystemPathType")] + value: FileSystemSpecialPath + + +class FileSystemPath( + RootModel[PathFileSystemPath | GlobPatternFileSystemPath | SpecialFileSystemPath] +): + model_config = ConfigDict( + populate_by_name=True, + ) + root: PathFileSystemPath | GlobPatternFileSystemPath | SpecialFileSystemPath + + +class FileSystemSandboxEntry(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + access: FileSystemAccessMode + path: FileSystemPath class FileUpdateChange(BaseModel): @@ -4738,8 +5403,49 @@ class GuardianApprovalReview(BaseModel): ) rationale: str | None = None risk_level: Annotated[GuardianRiskLevel | None, Field(alias="riskLevel")] = None - risk_score: Annotated[int | None, Field(alias="riskScore", ge=0)] = None status: GuardianApprovalReviewStatus + user_authorization: Annotated[ + GuardianUserAuthorization | None, Field(alias="userAuthorization") + ] = None + + +class CommandGuardianApprovalReviewAction(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + command: str + cwd: AbsolutePathBuf + source: GuardianCommandSource + type: Annotated[ + Literal["command"], Field(title="CommandGuardianApprovalReviewActionType") + ] + + +class ExecveGuardianApprovalReviewAction(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + argv: list[str] + cwd: AbsolutePathBuf + program: str + source: GuardianCommandSource + type: Annotated[ + Literal["execve"], Field(title="ExecveGuardianApprovalReviewActionType") + ] + + +class NetworkAccessGuardianApprovalReviewAction(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + host: str + port: Annotated[int, Field(ge=0)] + protocol: NetworkApprovalProtocol + target: str + type: Annotated[ + Literal["networkAccess"], + Field(title="NetworkAccessGuardianApprovalReviewActionType"), + ] class HookOutputEntry(BaseModel): @@ -4763,7 +5469,8 @@ class HookRunSummary(BaseModel): handler_type: Annotated[HookHandlerType, Field(alias="handlerType")] id: str scope: HookScope - source_path: Annotated[str, Field(alias="sourcePath")] + source: HookSource | None = "unknown" + source_path: Annotated[AbsolutePathBuf, Field(alias="sourcePath")] started_at: Annotated[int, Field(alias="startedAt")] status: HookRunStatus status_message: Annotated[str | None, Field(alias="statusMessage")] = None @@ -4778,26 +5485,33 @@ class HookStartedNotification(BaseModel): turn_id: Annotated[str | None, Field(alias="turnId")] = None -class ItemGuardianApprovalReviewCompletedNotification(BaseModel): +class ListMcpServerStatusParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - action: Any | None = None - review: GuardianApprovalReview - target_item_id: Annotated[str, Field(alias="targetItemId")] - thread_id: Annotated[str, Field(alias="threadId")] - turn_id: Annotated[str, Field(alias="turnId")] + cursor: Annotated[ + str | None, + Field(description="Opaque pagination cursor returned by a previous call."), + ] = None + detail: Annotated[ + McpServerStatusDetail | None, + Field( + description="Controls how much MCP inventory data to fetch for each server. Defaults to `Full` when omitted." + ), + ] = None + limit: Annotated[ + int | None, + Field( + description="Optional page size; defaults to a server-defined value.", ge=0 + ), + ] = None -class ItemGuardianApprovalReviewStartedNotification(BaseModel): +class McpResourceReadResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - action: Any | None = None - review: GuardianApprovalReview - target_item_id: Annotated[str, Field(alias="targetItemId")] - thread_id: Annotated[str, Field(alias="threadId")] - turn_id: Annotated[str, Field(alias="turnId")] + contents: list[ResourceContent] class McpServerStatus(BaseModel): @@ -4821,10 +5535,20 @@ class MemoryCitation(BaseModel): thread_ids: Annotated[list[str], Field(alias="threadIds")] +class MigrationDetails(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + plugins: list[PluginsMigration] + + class Model(BaseModel): model_config = ConfigDict( populate_by_name=True, ) + additional_speed_tiers: Annotated[ + list[str] | None, Field(alias="additionalSpeedTiers") + ] = [] availability_nux: Annotated[ ModelAvailabilityNux | None, Field(alias="availabilityNux") ] = None @@ -4892,7 +5616,12 @@ class PluginMarketplaceEntry(BaseModel): ) interface: MarketplaceInterface | None = None name: str - path: AbsolutePathBuf + path: Annotated[ + AbsolutePathBuf | None, + Field( + description="Local marketplace file path when the marketplace is backed by a local file. Remote-only catalog marketplaces do not have a local path." + ), + ] = None plugins: list[PluginSummary] @@ -4912,9 +5641,24 @@ class RateLimitSnapshot(BaseModel): limit_name: Annotated[str | None, Field(alias="limitName")] = None plan_type: Annotated[PlanType | None, Field(alias="planType")] = None primary: RateLimitWindow | None = None + rate_limit_reached_type: Annotated[ + RateLimitReachedType | None, Field(alias="rateLimitReachedType") + ] = None secondary: RateLimitWindow | None = None +class MessageResponseItem(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + content: list[ContentItem] + end_turn: bool | None = None + id: str | None = None + phase: MessagePhase | None = None + role: str + type: Annotated[Literal["message"], Field(title="MessageResponseItemType")] + + class WebSearchCallResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -5023,28 +5767,6 @@ class TurnDiffUpdatedServerNotification(BaseModel): params: TurnDiffUpdatedNotification -class ItemAutoApprovalReviewStartedServerNotification(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - method: Annotated[ - Literal["item/autoApprovalReview/started"], - Field(title="Item/autoApprovalReview/startedNotificationMethod"), - ] - params: ItemGuardianApprovalReviewStartedNotification - - -class ItemAutoApprovalReviewCompletedServerNotification(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - method: Annotated[ - Literal["item/autoApprovalReview/completed"], - Field(title="Item/autoApprovalReview/completedNotificationMethod"), - ] - params: ItemGuardianApprovalReviewCompletedNotification - - class CommandExecOutputDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -5088,6 +5810,14 @@ class AccountUpdatedServerNotification(BaseModel): params: AccountUpdatedNotification +class WarningServerNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + method: Annotated[Literal["warning"], Field(title="WarningNotificationMethod")] + params: WarningNotification + + class ConfigWarningServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -5120,15 +5850,26 @@ class ThreadRealtimeItemAddedServerNotification(BaseModel): params: ThreadRealtimeItemAddedNotification -class ThreadRealtimeTranscriptUpdatedServerNotification(BaseModel): +class ThreadRealtimeTranscriptDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) method: Annotated[ - Literal["thread/realtime/transcriptUpdated"], - Field(title="Thread/realtime/transcriptUpdatedNotificationMethod"), + Literal["thread/realtime/transcript/delta"], + Field(title="Thread/realtime/transcript/deltaNotificationMethod"), ] - params: ThreadRealtimeTranscriptUpdatedNotification + params: ThreadRealtimeTranscriptDeltaNotification + + +class ThreadRealtimeTranscriptDoneServerNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + method: Annotated[ + Literal["thread/realtime/transcript/done"], + Field(title="Thread/realtime/transcript/doneNotificationMethod"), + ] + params: ThreadRealtimeTranscriptDoneNotification class ThreadRealtimeOutputAudioDeltaServerNotification(BaseModel): @@ -5142,6 +5883,17 @@ class ThreadRealtimeOutputAudioDeltaServerNotification(BaseModel): params: ThreadRealtimeOutputAudioDeltaNotification +class ThreadRealtimeSdpServerNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + method: Annotated[ + Literal["thread/realtime/sdp"], + Field(title="Thread/realtime/sdpNotificationMethod"), + ] + params: ThreadRealtimeSdpNotification + + class ThreadRealtimeErrorServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -5191,7 +5943,7 @@ class SkillMetadata(BaseModel): enabled: bool interface: SkillInterface | None = None name: str - path: str + path: AbsolutePathBuf scope: SkillScope short_description: Annotated[ str | None, @@ -5429,6 +6181,13 @@ class ThreadListParams(BaseModel): description="Optional substring filter for the extracted thread title.", ), ] = None + sort_direction: Annotated[ + SortDirection | None, + Field( + alias="sortDirection", + description="Optional sort direction; defaults to descending (newest first).", + ), + ] = None sort_key: Annotated[ ThreadSortKey | None, Field( @@ -5444,6 +6203,38 @@ class ThreadListParams(BaseModel): ] = None +class ThreadStartParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = ( + None + ) + approvals_reviewer: Annotated[ + ApprovalsReviewer | None, + Field( + alias="approvalsReviewer", + description="Override where approval requests are routed for review on this thread and subsequent turns.", + ), + ] = None + base_instructions: Annotated[str | None, Field(alias="baseInstructions")] = None + config: dict[str, Any] | None = None + cwd: str | None = None + developer_instructions: Annotated[ + str | None, Field(alias="developerInstructions") + ] = None + ephemeral: bool | None = None + model: str | None = None + model_provider: Annotated[str | None, Field(alias="modelProvider")] = None + personality: Personality | None = None + sandbox: SandboxMode | None = None + service_name: Annotated[str | None, Field(alias="serviceName")] = None + service_tier: Annotated[ServiceTier | None, Field(alias="serviceTier")] = None + session_start_source: Annotated[ + ThreadStartSource | None, Field(alias="sessionStartSource") + ] = None + + class ThreadTokenUsage(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -5610,6 +6401,18 @@ class AccountRateLimitsUpdatedNotification(BaseModel): rate_limits: Annotated[RateLimitSnapshot, Field(alias="rateLimits")] +class AdditionalFileSystemPermissions(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + entries: list[FileSystemSandboxEntry] | None = None + glob_scan_max_depth: Annotated[ + int | None, Field(alias="globScanMaxDepth", ge=1) + ] = None + read: list[AbsolutePathBuf] | None = None + write: list[AbsolutePathBuf] | None = None + + class AppInfo(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -5660,6 +6463,15 @@ class AppsListResponse(BaseModel): ] = None +class ThreadStartRequest(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + id: RequestId + method: Annotated[Literal["thread/start"], Field(title="Thread/startRequestMethod")] + params: ThreadStartParams + + class ThreadListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -5696,6 +6508,18 @@ class ReviewStartRequest(BaseModel): params: ReviewStartParams +class McpServerStatusListRequest(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + id: RequestId + method: Annotated[ + Literal["mcpServerStatus/list"], + Field(title="McpServerStatus/listRequestMethod"), + ] + params: ListMcpServerStatusParams + + class CommandExecRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -5777,20 +6601,29 @@ class ErrorNotification(BaseModel): will_retry: Annotated[bool, Field(alias="willRetry")] -class ExternalAgentConfigDetectResponse(BaseModel): +class ExternalAgentConfigMigrationItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - items: list[ExternalAgentConfigMigrationItem] + cwd: Annotated[ + str | None, + Field( + description="Null or empty means home-scoped migration; non-empty means repo-scoped migration." + ), + ] = None + description: str + details: MigrationDetails | None = None + item_type: Annotated[ExternalAgentConfigMigrationItemType, Field(alias="itemType")] -class ExternalAgentConfigImportParams(BaseModel): +class FileChangePatchUpdatedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - migration_items: Annotated[ - list[ExternalAgentConfigMigrationItem], Field(alias="migrationItems") - ] + changes: list[FileUpdateChange] + item_id: Annotated[str, Field(alias="itemId")] + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class FunctionCallOutputBody(RootModel[str | list[FunctionCallOutputContentItem]]): @@ -5872,7 +6705,6 @@ class PluginListResponse(BaseModel): list[MarketplaceLoadErrorInfo] | None, Field(alias="marketplaceLoadErrors") ] = [] marketplaces: list[PluginMarketplaceEntry] - remote_sync_error: Annotated[str | None, Field(alias="remoteSyncError")] = None class ProfileV2(BaseModel): @@ -5898,6 +6730,17 @@ class ProfileV2(BaseModel): web_search: WebSearchMode | None = None +class RequestPermissionProfile(BaseModel): + model_config = ConfigDict( + extra="forbid", + populate_by_name=True, + ) + file_system: Annotated[ + AdditionalFileSystemPermissions | None, Field(alias="fileSystem") + ] = None + network: AdditionalNetworkPermissions | None = None + + class FunctionCallOutputResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -6021,6 +6864,17 @@ class ItemCompletedServerNotification(BaseModel): params: ItemCompletedNotification +class ItemFileChangePatchUpdatedServerNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + method: Annotated[ + Literal["item/fileChange/patchUpdated"], + Field(title="Item/fileChange/patchUpdatedNotificationMethod"), + ] + params: FileChangePatchUpdatedNotification + + class AccountRateLimitsUpdatedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -6074,6 +6928,20 @@ class Turn(BaseModel): model_config = ConfigDict( populate_by_name=True, ) + completed_at: Annotated[ + int | None, + Field( + alias="completedAt", + description="Unix timestamp (in seconds) when the turn completed.", + ), + ] = None + duration_ms: Annotated[ + int | None, + Field( + alias="durationMs", + description="Duration between turn start and completion in milliseconds, if known.", + ), + ] = None error: Annotated[ TurnError | None, Field(description="Only populated when the Turn's status is failed."), @@ -6085,6 +6953,13 @@ class Turn(BaseModel): description="Only populated on a `thread/resume` or `thread/fork` response. For all other responses and notifications returning a Turn, the items field will be an empty list." ), ] + started_at: Annotated[ + int | None, + Field( + alias="startedAt", + description="Unix timestamp (in seconds) when the turn started.", + ), + ] = None status: TurnStatus @@ -6111,18 +6986,6 @@ class TurnStartedNotification(BaseModel): turn: Turn -class ExternalAgentConfigImportRequest(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - id: RequestId - method: Annotated[ - Literal["externalAgentConfig/import"], - Field(title="ExternalAgentConfig/importRequestMethod"), - ] - params: ExternalAgentConfigImportParams - - class ConfigBatchWriteRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -6134,138 +6997,6 @@ class ConfigBatchWriteRequest(BaseModel): params: ConfigBatchWriteParams -class ClientRequest( - RootModel[ - InitializeRequest - | ThreadStartRequest - | ThreadResumeRequest - | ThreadForkRequest - | ThreadArchiveRequest - | ThreadUnsubscribeRequest - | ThreadNameSetRequest - | ThreadMetadataUpdateRequest - | ThreadUnarchiveRequest - | ThreadCompactStartRequest - | ThreadShellCommandRequest - | ThreadRollbackRequest - | ThreadListRequest - | ThreadLoadedListRequest - | ThreadReadRequest - | SkillsListRequest - | PluginListRequest - | PluginReadRequest - | AppListRequest - | FsReadFileRequest - | FsWriteFileRequest - | FsCreateDirectoryRequest - | FsGetMetadataRequest - | FsReadDirectoryRequest - | FsRemoveRequest - | FsCopyRequest - | FsWatchRequest - | FsUnwatchRequest - | SkillsConfigWriteRequest - | PluginInstallRequest - | PluginUninstallRequest - | TurnStartRequest - | TurnSteerRequest - | TurnInterruptRequest - | ReviewStartRequest - | ModelListRequest - | ExperimentalFeatureListRequest - | ExperimentalFeatureEnablementSetRequest - | McpServerOauthLoginRequest - | ConfigMcpServerReloadRequest - | McpServerStatusListRequest - | WindowsSandboxSetupStartRequest - | AccountLoginStartRequest - | AccountLoginCancelRequest - | AccountLogoutRequest - | AccountRateLimitsReadRequest - | FeedbackUploadRequest - | CommandExecRequest - | CommandExecWriteRequest - | CommandExecTerminateRequest - | CommandExecResizeRequest - | ConfigReadRequest - | ExternalAgentConfigDetectRequest - | ExternalAgentConfigImportRequest - | ConfigValueWriteRequest - | ConfigBatchWriteRequest - | ConfigRequirementsReadRequest - | AccountReadRequest - | FuzzyFileSearchRequest - ] -): - model_config = ConfigDict( - populate_by_name=True, - ) - root: Annotated[ - InitializeRequest - | ThreadStartRequest - | ThreadResumeRequest - | ThreadForkRequest - | ThreadArchiveRequest - | ThreadUnsubscribeRequest - | ThreadNameSetRequest - | ThreadMetadataUpdateRequest - | ThreadUnarchiveRequest - | ThreadCompactStartRequest - | ThreadShellCommandRequest - | ThreadRollbackRequest - | ThreadListRequest - | ThreadLoadedListRequest - | ThreadReadRequest - | SkillsListRequest - | PluginListRequest - | PluginReadRequest - | AppListRequest - | FsReadFileRequest - | FsWriteFileRequest - | FsCreateDirectoryRequest - | FsGetMetadataRequest - | FsReadDirectoryRequest - | FsRemoveRequest - | FsCopyRequest - | FsWatchRequest - | FsUnwatchRequest - | SkillsConfigWriteRequest - | PluginInstallRequest - | PluginUninstallRequest - | TurnStartRequest - | TurnSteerRequest - | TurnInterruptRequest - | ReviewStartRequest - | ModelListRequest - | ExperimentalFeatureListRequest - | ExperimentalFeatureEnablementSetRequest - | McpServerOauthLoginRequest - | ConfigMcpServerReloadRequest - | McpServerStatusListRequest - | WindowsSandboxSetupStartRequest - | AccountLoginStartRequest - | AccountLoginCancelRequest - | AccountLogoutRequest - | AccountRateLimitsReadRequest - | FeedbackUploadRequest - | CommandExecRequest - | CommandExecWriteRequest - | CommandExecTerminateRequest - | CommandExecResizeRequest - | ConfigReadRequest - | ExternalAgentConfigDetectRequest - | ExternalAgentConfigImportRequest - | ConfigValueWriteRequest - | ConfigBatchWriteRequest - | ConfigRequirementsReadRequest - | AccountReadRequest - | FuzzyFileSearchRequest, - Field( - description="Request from the client to the server.", title="ClientRequest" - ), - ] - - class Config(BaseModel): model_config = ConfigDict( extra="allow", @@ -6310,6 +7041,98 @@ class ConfigReadResponse(BaseModel): origins: dict[str, ConfigLayerMetadata] +class ExternalAgentConfigDetectResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + items: list[ExternalAgentConfigMigrationItem] + + +class ExternalAgentConfigImportParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + migration_items: Annotated[ + list[ExternalAgentConfigMigrationItem], Field(alias="migrationItems") + ] + + +class RequestPermissionsGuardianApprovalReviewAction(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + permissions: RequestPermissionProfile + reason: str | None = None + type: Annotated[ + Literal["requestPermissions"], + Field(title="RequestPermissionsGuardianApprovalReviewActionType"), + ] + + +class GuardianApprovalReviewAction( + RootModel[ + CommandGuardianApprovalReviewAction + | ExecveGuardianApprovalReviewAction + | ApplyPatchGuardianApprovalReviewAction + | NetworkAccessGuardianApprovalReviewAction + | McpToolCallGuardianApprovalReviewAction + | RequestPermissionsGuardianApprovalReviewAction + ] +): + model_config = ConfigDict( + populate_by_name=True, + ) + root: ( + CommandGuardianApprovalReviewAction + | ExecveGuardianApprovalReviewAction + | ApplyPatchGuardianApprovalReviewAction + | NetworkAccessGuardianApprovalReviewAction + | McpToolCallGuardianApprovalReviewAction + | RequestPermissionsGuardianApprovalReviewAction + ) + + +class ItemGuardianApprovalReviewCompletedNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + action: GuardianApprovalReviewAction + decision_source: Annotated[AutoReviewDecisionSource, Field(alias="decisionSource")] + review: GuardianApprovalReview + review_id: Annotated[ + str, Field(alias="reviewId", description="Stable identifier for this review.") + ] + target_item_id: Annotated[ + str | None, + Field( + alias="targetItemId", + description="Identifier for the reviewed item or tool call when one exists.\n\nIn most cases, one review maps to one target item. The exceptions are - execve reviews, where a single command may contain multiple execve calls to review (only possible when using the shell_zsh_fork feature) - network policy reviews, where there is no target item\n\nA network call is triggered by a CommandExecution item, so having a target_item_id set to the CommandExecution item would be misleading because the review is about the network call, not the command execution. Therefore, target_item_id is set to None for network policy reviews.", + ), + ] = None + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] + + +class ItemGuardianApprovalReviewStartedNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + action: GuardianApprovalReviewAction + review: GuardianApprovalReview + review_id: Annotated[ + str, Field(alias="reviewId", description="Stable identifier for this review.") + ] + target_item_id: Annotated[ + str | None, + Field( + alias="targetItemId", + description="Identifier for the reviewed item or tool call when one exists.\n\nIn most cases, one review maps to one target item. The exceptions are - execve reviews, where a single command may contain multiple execve calls to review (only possible when using the shell_zsh_fork feature) - network policy reviews, where there is no target item\n\nA network call is triggered by a CommandExecution item, so having a target_item_id set to the CommandExecution item would be misleading because the review is about the network call, not the command execution. Therefore, target_item_id is set to None for network policy reviews.", + ), + ] = None + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] + + class RawResponseItemCompletedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -6353,6 +7176,28 @@ class TurnCompletedServerNotification(BaseModel): params: TurnCompletedNotification +class ItemAutoApprovalReviewStartedServerNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + method: Annotated[ + Literal["item/autoApprovalReview/started"], + Field(title="Item/autoApprovalReview/startedNotificationMethod"), + ] + params: ItemGuardianApprovalReviewStartedNotification + + +class ItemAutoApprovalReviewCompletedServerNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + method: Annotated[ + Literal["item/autoApprovalReview/completed"], + Field(title="Item/autoApprovalReview/completedNotificationMethod"), + ] + params: ItemGuardianApprovalReviewCompletedNotification + + class Thread(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -6385,13 +7230,22 @@ class Thread(BaseModel): description="Unix timestamp (in seconds) when the thread was created.", ), ] - cwd: Annotated[str, Field(description="Working directory captured for the thread.")] + cwd: Annotated[ + AbsolutePathBuf, Field(description="Working directory captured for the thread.") + ] ephemeral: Annotated[ bool, Field( description="Whether the thread is ephemeral and should not be materialized on disk." ), ] + forked_from_id: Annotated[ + str | None, + Field( + alias="forkedFromId", + description="Source thread id when this thread was created by forking another thread.", + ), + ] = None git_info: Annotated[ GitInfo | None, Field( @@ -6455,7 +7309,14 @@ class ThreadForkResponse(BaseModel): description="Reviewer currently used for approval requests on this thread.", ), ] - cwd: str + cwd: AbsolutePathBuf + instruction_sources: Annotated[ + list[AbsolutePathBuf] | None, + Field( + alias="instructionSources", + description="Instruction source files currently loaded for this thread.", + ), + ] = [] model: str model_provider: Annotated[str, Field(alias="modelProvider")] reasoning_effort: Annotated[ @@ -6470,6 +7331,13 @@ class ThreadListResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) + backwards_cursor: Annotated[ + str | None, + Field( + alias="backwardsCursor", + description="Opaque cursor to pass as `cursor` when reversing `sortDirection`. This is only populated when the page contains at least one thread. Use it with the opposite `sortDirection`; for timestamp sorts it anchors at the start of the page timestamp so same-second updates are not skipped.", + ), + ] = None data: list[Thread] next_cursor: Annotated[ str | None, @@ -6506,7 +7374,14 @@ class ThreadResumeResponse(BaseModel): description="Reviewer currently used for approval requests on this thread.", ), ] - cwd: str + cwd: AbsolutePathBuf + instruction_sources: Annotated[ + list[AbsolutePathBuf] | None, + Field( + alias="instructionSources", + description="Instruction source files currently loaded for this thread.", + ), + ] = [] model: str model_provider: Annotated[str, Field(alias="modelProvider")] reasoning_effort: Annotated[ @@ -6541,7 +7416,14 @@ class ThreadStartResponse(BaseModel): description="Reviewer currently used for approval requests on this thread.", ), ] - cwd: str + cwd: AbsolutePathBuf + instruction_sources: Annotated[ + list[AbsolutePathBuf] | None, + Field( + alias="instructionSources", + description="Instruction source files currently loaded for this thread.", + ), + ] = [] model: str model_provider: Annotated[str, Field(alias="modelProvider")] reasoning_effort: Annotated[ @@ -6559,6 +7441,27 @@ class ThreadStartedNotification(BaseModel): thread: Thread +class ThreadTurnsListResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + backwards_cursor: Annotated[ + str | None, + Field( + alias="backwardsCursor", + description="Opaque cursor to pass as `cursor` when reversing `sortDirection`. This is only populated when the page contains at least one turn. Use it with the opposite `sortDirection` to include the anchor turn again and catch updates to that turn.", + ), + ] = None + data: list[Turn] + next_cursor: Annotated[ + str | None, + Field( + alias="nextCursor", + description="Opaque cursor to pass to the next call to continue after the last turn. if None, there are no more turns to return.", + ), + ] = None + + class ThreadUnarchiveResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -6566,6 +7469,164 @@ class ThreadUnarchiveResponse(BaseModel): thread: Thread +class ExternalAgentConfigImportRequest(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + id: RequestId + method: Annotated[ + Literal["externalAgentConfig/import"], + Field(title="ExternalAgentConfig/importRequestMethod"), + ] + params: ExternalAgentConfigImportParams + + +class ClientRequest( + RootModel[ + InitializeRequest + | ThreadStartRequest + | ThreadResumeRequest + | ThreadForkRequest + | ThreadArchiveRequest + | ThreadUnsubscribeRequest + | ThreadNameSetRequest + | ThreadMetadataUpdateRequest + | ThreadUnarchiveRequest + | ThreadCompactStartRequest + | ThreadShellCommandRequest + | ThreadRollbackRequest + | ThreadListRequest + | ThreadLoadedListRequest + | ThreadReadRequest + | ThreadTurnsListRequest + | ThreadInjectItemsRequest + | SkillsListRequest + | MarketplaceAddRequest + | MarketplaceRemoveRequest + | PluginListRequest + | PluginReadRequest + | AppListRequest + | FsReadFileRequest + | FsWriteFileRequest + | FsCreateDirectoryRequest + | FsGetMetadataRequest + | FsReadDirectoryRequest + | FsRemoveRequest + | FsCopyRequest + | FsWatchRequest + | FsUnwatchRequest + | SkillsConfigWriteRequest + | PluginInstallRequest + | PluginUninstallRequest + | TurnStartRequest + | TurnSteerRequest + | TurnInterruptRequest + | ReviewStartRequest + | ModelListRequest + | ExperimentalFeatureListRequest + | ExperimentalFeatureEnablementSetRequest + | McpServerOauthLoginRequest + | ConfigMcpServerReloadRequest + | McpServerStatusListRequest + | McpServerResourceReadRequest + | McpServerToolCallRequest + | WindowsSandboxSetupStartRequest + | AccountLoginStartRequest + | AccountLoginCancelRequest + | AccountLogoutRequest + | AccountRateLimitsReadRequest + | AccountSendAddCreditsNudgeEmailRequest + | FeedbackUploadRequest + | CommandExecRequest + | CommandExecWriteRequest + | CommandExecTerminateRequest + | CommandExecResizeRequest + | ConfigReadRequest + | ExternalAgentConfigDetectRequest + | ExternalAgentConfigImportRequest + | ConfigValueWriteRequest + | ConfigBatchWriteRequest + | ConfigRequirementsReadRequest + | AccountReadRequest + | FuzzyFileSearchRequest + ] +): + model_config = ConfigDict( + populate_by_name=True, + ) + root: Annotated[ + InitializeRequest + | ThreadStartRequest + | ThreadResumeRequest + | ThreadForkRequest + | ThreadArchiveRequest + | ThreadUnsubscribeRequest + | ThreadNameSetRequest + | ThreadMetadataUpdateRequest + | ThreadUnarchiveRequest + | ThreadCompactStartRequest + | ThreadShellCommandRequest + | ThreadRollbackRequest + | ThreadListRequest + | ThreadLoadedListRequest + | ThreadReadRequest + | ThreadTurnsListRequest + | ThreadInjectItemsRequest + | SkillsListRequest + | MarketplaceAddRequest + | MarketplaceRemoveRequest + | PluginListRequest + | PluginReadRequest + | AppListRequest + | FsReadFileRequest + | FsWriteFileRequest + | FsCreateDirectoryRequest + | FsGetMetadataRequest + | FsReadDirectoryRequest + | FsRemoveRequest + | FsCopyRequest + | FsWatchRequest + | FsUnwatchRequest + | SkillsConfigWriteRequest + | PluginInstallRequest + | PluginUninstallRequest + | TurnStartRequest + | TurnSteerRequest + | TurnInterruptRequest + | ReviewStartRequest + | ModelListRequest + | ExperimentalFeatureListRequest + | ExperimentalFeatureEnablementSetRequest + | McpServerOauthLoginRequest + | ConfigMcpServerReloadRequest + | McpServerStatusListRequest + | McpServerResourceReadRequest + | McpServerToolCallRequest + | WindowsSandboxSetupStartRequest + | AccountLoginStartRequest + | AccountLoginCancelRequest + | AccountLogoutRequest + | AccountRateLimitsReadRequest + | AccountSendAddCreditsNudgeEmailRequest + | FeedbackUploadRequest + | CommandExecRequest + | CommandExecWriteRequest + | CommandExecTerminateRequest + | CommandExecResizeRequest + | ConfigReadRequest + | ExternalAgentConfigDetectRequest + | ExternalAgentConfigImportRequest + | ConfigValueWriteRequest + | ConfigBatchWriteRequest + | ConfigRequirementsReadRequest + | AccountReadRequest + | FuzzyFileSearchRequest, + Field( + description="Request from the client to the server.", title="ClientRequest" + ), + ] + + class ThreadStartedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, @@ -6603,6 +7664,7 @@ class ServerNotification( | ItemCommandExecutionOutputDeltaServerNotification | ItemCommandExecutionTerminalInteractionServerNotification | ItemFileChangeOutputDeltaServerNotification + | ItemFileChangePatchUpdatedServerNotification | ServerRequestResolvedServerNotification | ItemMcpToolCallProgressServerNotification | McpServerOauthLoginCompletedServerNotification @@ -6610,20 +7672,24 @@ class ServerNotification( | AccountUpdatedServerNotification | AccountRateLimitsUpdatedServerNotification | AppListUpdatedServerNotification + | ExternalAgentConfigImportCompletedServerNotification | FsChangedServerNotification | ItemReasoningSummaryTextDeltaServerNotification | ItemReasoningSummaryPartAddedServerNotification | ItemReasoningTextDeltaServerNotification | ThreadCompactedServerNotification | ModelReroutedServerNotification + | WarningServerNotification | DeprecationNoticeServerNotification | ConfigWarningServerNotification | FuzzyFileSearchSessionUpdatedServerNotification | FuzzyFileSearchSessionCompletedServerNotification | ThreadRealtimeStartedServerNotification | ThreadRealtimeItemAddedServerNotification - | ThreadRealtimeTranscriptUpdatedServerNotification + | ThreadRealtimeTranscriptDeltaServerNotification + | ThreadRealtimeTranscriptDoneServerNotification | ThreadRealtimeOutputAudioDeltaServerNotification + | ThreadRealtimeSdpServerNotification | ThreadRealtimeErrorServerNotification | ThreadRealtimeClosedServerNotification | WindowsWorldWritableWarningServerNotification @@ -6660,6 +7726,7 @@ class ServerNotification( | ItemCommandExecutionOutputDeltaServerNotification | ItemCommandExecutionTerminalInteractionServerNotification | ItemFileChangeOutputDeltaServerNotification + | ItemFileChangePatchUpdatedServerNotification | ServerRequestResolvedServerNotification | ItemMcpToolCallProgressServerNotification | McpServerOauthLoginCompletedServerNotification @@ -6667,20 +7734,24 @@ class ServerNotification( | AccountUpdatedServerNotification | AccountRateLimitsUpdatedServerNotification | AppListUpdatedServerNotification + | ExternalAgentConfigImportCompletedServerNotification | FsChangedServerNotification | ItemReasoningSummaryTextDeltaServerNotification | ItemReasoningSummaryPartAddedServerNotification | ItemReasoningTextDeltaServerNotification | ThreadCompactedServerNotification | ModelReroutedServerNotification + | WarningServerNotification | DeprecationNoticeServerNotification | ConfigWarningServerNotification | FuzzyFileSearchSessionUpdatedServerNotification | FuzzyFileSearchSessionCompletedServerNotification | ThreadRealtimeStartedServerNotification | ThreadRealtimeItemAddedServerNotification - | ThreadRealtimeTranscriptUpdatedServerNotification + | ThreadRealtimeTranscriptDeltaServerNotification + | ThreadRealtimeTranscriptDoneServerNotification | ThreadRealtimeOutputAudioDeltaServerNotification + | ThreadRealtimeSdpServerNotification | ThreadRealtimeErrorServerNotification | ThreadRealtimeClosedServerNotification | WindowsWorldWritableWarningServerNotification diff --git a/sdk/python/tests/test_public_api_signatures.py b/sdk/python/tests/test_public_api_signatures.py index ce1b84725..68097d4bc 100644 --- a/sdk/python/tests/test_public_api_signatures.py +++ b/sdk/python/tests/test_public_api_signatures.py @@ -22,7 +22,9 @@ def _assert_no_any_annotations(fn: object) -> None: signature = inspect.signature(fn) for param in signature.parameters.values(): if param.annotation is Any: - raise AssertionError(f"{fn} has public parameter typed as Any: {param.name}") + raise AssertionError( + f"{fn} has public parameter typed as Any: {param.name}" + ) if signature.return_annotation is Any: raise AssertionError(f"{fn} has public return annotation typed as Any") @@ -56,6 +58,7 @@ def test_generated_public_signatures_are_snake_case_and_typed() -> None: "sandbox", "service_name", "service_tier", + "session_start_source", ], Codex.thread_list: [ "archived", @@ -64,6 +67,7 @@ def test_generated_public_signatures_are_snake_case_and_typed() -> None: "limit", "model_providers", "search_term", + "sort_direction", "sort_key", "source_kinds", ], @@ -131,6 +135,7 @@ def test_generated_public_signatures_are_snake_case_and_typed() -> None: "sandbox", "service_name", "service_tier", + "session_start_source", ], AsyncCodex.thread_list: [ "archived", @@ -139,6 +144,7 @@ def test_generated_public_signatures_are_snake_case_and_typed() -> None: "limit", "model_providers", "search_term", + "sort_direction", "sort_key", "source_kinds", ], @@ -197,7 +203,9 @@ def test_generated_public_signatures_are_snake_case_and_typed() -> None: for fn, expected_kwargs in expected.items(): actual = _keyword_only_names(fn) assert actual == expected_kwargs, f"unexpected kwargs for {fn}: {actual}" - assert all(name == name.lower() for name in actual), f"non snake_case kwargs in {fn}: {actual}" + assert all(name == name.lower() for name in actual), ( + f"non snake_case kwargs in {fn}: {actual}" + ) _assert_no_any_annotations(fn) @@ -247,4 +255,6 @@ def test_initialize_metadata_requires_non_empty_information() -> None: except RuntimeError as exc: assert "missing required metadata" in str(exc) else: - raise AssertionError("expected RuntimeError when initialize metadata is missing") + raise AssertionError( + "expected RuntimeError when initialize metadata is missing" + )