diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 819ecdd75..9fdb5b791 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.11.8"
+ ".": "0.11.9"
}
diff --git a/.stats.yml b/.stats.yml
index 5e5e990c0..b713c571e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 63
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp/agentex-sdk-4d4bf80af19e6a2ef6b890d5d978316b86e9939d8d5116e94b90117525c61325.yml
-openapi_spec_hash: 133afeacb42000ed4f9e076abf4b50fd
-config_hash: ba5183ca635940fd202d05a2a9fcb630
+configured_endpoints: 64
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp/agentex-sdk-9185c7bad4328824f8790e963c5a9f20b70f5c15fc148c348947efc1bd9a946c.yml
+openapi_spec_hash: 9115c9f283257e0636aba67fadfeda0a
+config_hash: 713b2e04b6e0aa109ab9d5a3375a5021
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 28b4b9eeb..41ac9d580 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,14 @@
* **tracing:** emit OTel metrics for async span queue depth, batch drain, and SGP export success/failure (HTTP status labels). Disable SDK-side recording with ``AGENTEX_TRACING_METRICS=0``.
+## 0.11.9 (2026-06-02)
+
+Full Changelog: [v0.11.8...v0.11.9](https://github.com/scaleapi/scale-agentex-python/compare/v0.11.8...v0.11.9)
+
+### Features
+
+* **api:** add register build api endpoint ([30c5da4](https://github.com/scaleapi/scale-agentex-python/commit/30c5da47d84ce2bfbfbb798c2f62b9552881db7d))
+
## 0.11.8 (2026-06-01)
Full Changelog: [v0.11.7...v0.11.8](https://github.com/scaleapi/scale-agentex-python/compare/v0.11.7...v0.11.8)
diff --git a/api.md b/api.md
index 9fbe95277..4c0d9b9c1 100644
--- a/api.md
+++ b/api.md
@@ -34,6 +34,7 @@ Methods:
- client.agents.list(\*\*params) -> AgentListResponse
- client.agents.delete(agent_id) -> DeleteResponse
- client.agents.delete_by_name(agent_name) -> DeleteResponse
+- client.agents.register_build(\*\*params) -> Agent
- client.agents.retrieve_by_name(agent_name) -> Agent
- client.agents.rpc(agent_id, \*\*params) -> AgentRpcResponse
- client.agents.rpc_by_name(agent_name, \*\*params) -> AgentRpcResponse
diff --git a/pyproject.toml b/pyproject.toml
index f0572a941..80c889d12 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "agentex-sdk"
-version = "0.11.8"
+version = "0.11.9"
description = "The official Python library for the agentex API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/agentex/_version.py b/src/agentex/_version.py
index f06fd51b0..0eb8e17fb 100644
--- a/src/agentex/_version.py
+++ b/src/agentex/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "agentex"
-__version__ = "0.11.8" # x-release-please-version
+__version__ = "0.11.9" # x-release-please-version
diff --git a/src/agentex/resources/agents/agents.py b/src/agentex/resources/agents/agents.py
index 3dd0c770d..d3442e01c 100644
--- a/src/agentex/resources/agents/agents.py
+++ b/src/agentex/resources/agents/agents.py
@@ -3,13 +3,13 @@
from __future__ import annotations
import json
-from typing import Any, Union, Optional, Generator, AsyncGenerator
+from typing import Any, Dict, Union, Optional, Generator, AsyncGenerator
from typing_extensions import Literal
import httpx
from pydantic import ValidationError
-from ...types import agent_rpc_params, agent_list_params, agent_rpc_by_name_params
+from ...types import agent_rpc_params, agent_list_params, agent_rpc_by_name_params, agent_register_build_params
from ..._types import NOT_GIVEN, Body, Omit, Query, Headers, NotGiven, omit, not_given
from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
@@ -237,6 +237,62 @@ def delete_by_name(
cast_to=DeleteResponse,
)
+ def register_build(
+ self,
+ *,
+ description: str,
+ name: str,
+ agent_input_type: Optional[Literal["text", "json"]] | Omit = omit,
+ principal_context: object | Omit = omit,
+ registration_metadata: Optional[Dict[str, object]] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Agent:
+ """
+ Register an agent at build time, before it is deployed, so it can be
+ permissioned and shared prior to deploy. Idempotent by name.
+
+ Args:
+ description: The description of the agent.
+
+ name: The unique name of the agent.
+
+ agent_input_type: The type of input the agent expects.
+
+ principal_context: Principal used for authorization
+
+ registration_metadata: The metadata for the agent's build registration.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/agents/register-build",
+ body=maybe_transform(
+ {
+ "description": description,
+ "name": name,
+ "agent_input_type": agent_input_type,
+ "principal_context": principal_context,
+ "registration_metadata": registration_metadata,
+ },
+ agent_register_build_params.AgentRegisterBuildParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Agent,
+ )
+
def retrieve_by_name(
self,
agent_name: str,
@@ -846,6 +902,62 @@ async def delete_by_name(
cast_to=DeleteResponse,
)
+ async def register_build(
+ self,
+ *,
+ description: str,
+ name: str,
+ agent_input_type: Optional[Literal["text", "json"]] | Omit = omit,
+ principal_context: object | Omit = omit,
+ registration_metadata: Optional[Dict[str, object]] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Agent:
+ """
+ Register an agent at build time, before it is deployed, so it can be
+ permissioned and shared prior to deploy. Idempotent by name.
+
+ Args:
+ description: The description of the agent.
+
+ name: The unique name of the agent.
+
+ agent_input_type: The type of input the agent expects.
+
+ principal_context: Principal used for authorization
+
+ registration_metadata: The metadata for the agent's build registration.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/agents/register-build",
+ body=await async_maybe_transform(
+ {
+ "description": description,
+ "name": name,
+ "agent_input_type": agent_input_type,
+ "principal_context": principal_context,
+ "registration_metadata": registration_metadata,
+ },
+ agent_register_build_params.AgentRegisterBuildParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Agent,
+ )
+
async def retrieve_by_name(
self,
agent_name: str,
@@ -1287,6 +1399,9 @@ def __init__(self, agents: AgentsResource) -> None:
self.delete_by_name = to_raw_response_wrapper(
agents.delete_by_name,
)
+ self.register_build = to_raw_response_wrapper(
+ agents.register_build,
+ )
self.retrieve_by_name = to_raw_response_wrapper(
agents.retrieve_by_name,
)
@@ -1322,6 +1437,9 @@ def __init__(self, agents: AsyncAgentsResource) -> None:
self.delete_by_name = async_to_raw_response_wrapper(
agents.delete_by_name,
)
+ self.register_build = async_to_raw_response_wrapper(
+ agents.register_build,
+ )
self.retrieve_by_name = async_to_raw_response_wrapper(
agents.retrieve_by_name,
)
@@ -1357,6 +1475,9 @@ def __init__(self, agents: AgentsResource) -> None:
self.delete_by_name = to_streamed_response_wrapper(
agents.delete_by_name,
)
+ self.register_build = to_streamed_response_wrapper(
+ agents.register_build,
+ )
self.retrieve_by_name = to_streamed_response_wrapper(
agents.retrieve_by_name,
)
@@ -1392,6 +1513,9 @@ def __init__(self, agents: AsyncAgentsResource) -> None:
self.delete_by_name = async_to_streamed_response_wrapper(
agents.delete_by_name,
)
+ self.register_build = async_to_streamed_response_wrapper(
+ agents.register_build,
+ )
self.retrieve_by_name = async_to_streamed_response_wrapper(
agents.retrieve_by_name,
)
diff --git a/src/agentex/types/__init__.py b/src/agentex/types/__init__.py
index 8dc75de60..f04daeb3b 100644
--- a/src/agentex/types/__init__.py
+++ b/src/agentex/types/__init__.py
@@ -72,6 +72,7 @@
from .task_message_content_param import TaskMessageContentParam as TaskMessageContentParam
from .task_update_by_name_params import TaskUpdateByNameParams as TaskUpdateByNameParams
from .tool_request_content_param import ToolRequestContentParam as ToolRequestContentParam
+from .agent_register_build_params import AgentRegisterBuildParams as AgentRegisterBuildParams
from .checkpoint_get_tuple_params import CheckpointGetTupleParams as CheckpointGetTupleParams
from .tool_response_content_param import ToolResponseContentParam as ToolResponseContentParam
from .checkpoint_put_writes_params import CheckpointPutWritesParams as CheckpointPutWritesParams
diff --git a/src/agentex/types/agent.py b/src/agentex/types/agent.py
index 5ed7588b1..e9daa58d5 100644
--- a/src/agentex/types/agent.py
+++ b/src/agentex/types/agent.py
@@ -41,7 +41,7 @@ class Agent(BaseModel):
registration_metadata: Optional[Dict[str, object]] = None
"""The metadata for the agent's registration."""
- status: Optional[Literal["Ready", "Failed", "Unknown", "Deleted", "Unhealthy"]] = None
+ status: Optional[Literal["Ready", "Failed", "Unknown", "Deleted", "Unhealthy", "BuildOnly"]] = None
"""The status of the action, indicating if it's building, ready, failed, etc."""
status_reason: Optional[str] = None
diff --git a/src/agentex/types/agent_register_build_params.py b/src/agentex/types/agent_register_build_params.py
new file mode 100644
index 000000000..18c249165
--- /dev/null
+++ b/src/agentex/types/agent_register_build_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Optional
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["AgentRegisterBuildParams"]
+
+
+class AgentRegisterBuildParams(TypedDict, total=False):
+ description: Required[str]
+ """The description of the agent."""
+
+ name: Required[str]
+ """The unique name of the agent."""
+
+ agent_input_type: Optional[Literal["text", "json"]]
+ """The type of input the agent expects."""
+
+ principal_context: object
+ """Principal used for authorization"""
+
+ registration_metadata: Optional[Dict[str, object]]
+ """The metadata for the agent's build registration."""
diff --git a/tests/api_resources/test_agents.py b/tests/api_resources/test_agents.py
index 6e8f24839..472317864 100644
--- a/tests/api_resources/test_agents.py
+++ b/tests/api_resources/test_agents.py
@@ -189,6 +189,55 @@ def test_path_params_delete_by_name(self, client: Agentex) -> None:
"",
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_register_build(self, client: Agentex) -> None:
+ agent = client.agents.register_build(
+ description="description",
+ name="name",
+ )
+ assert_matches_type(Agent, agent, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_register_build_with_all_params(self, client: Agentex) -> None:
+ agent = client.agents.register_build(
+ description="description",
+ name="name",
+ agent_input_type="text",
+ principal_context={},
+ registration_metadata={"foo": "bar"},
+ )
+ assert_matches_type(Agent, agent, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_register_build(self, client: Agentex) -> None:
+ response = client.agents.with_raw_response.register_build(
+ description="description",
+ name="name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ agent = response.parse()
+ assert_matches_type(Agent, agent, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_register_build(self, client: Agentex) -> None:
+ with client.agents.with_streaming_response.register_build(
+ description="description",
+ name="name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ agent = response.parse()
+ assert_matches_type(Agent, agent, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_retrieve_by_name(self, client: Agentex) -> None:
@@ -535,6 +584,55 @@ async def test_path_params_delete_by_name(self, async_client: AsyncAgentex) -> N
"",
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_register_build(self, async_client: AsyncAgentex) -> None:
+ agent = await async_client.agents.register_build(
+ description="description",
+ name="name",
+ )
+ assert_matches_type(Agent, agent, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_register_build_with_all_params(self, async_client: AsyncAgentex) -> None:
+ agent = await async_client.agents.register_build(
+ description="description",
+ name="name",
+ agent_input_type="text",
+ principal_context={},
+ registration_metadata={"foo": "bar"},
+ )
+ assert_matches_type(Agent, agent, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_register_build(self, async_client: AsyncAgentex) -> None:
+ response = await async_client.agents.with_raw_response.register_build(
+ description="description",
+ name="name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ agent = await response.parse()
+ assert_matches_type(Agent, agent, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_register_build(self, async_client: AsyncAgentex) -> None:
+ async with async_client.agents.with_streaming_response.register_build(
+ description="description",
+ name="name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ agent = await response.parse()
+ assert_matches_type(Agent, agent, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_retrieve_by_name(self, async_client: AsyncAgentex) -> None: