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: