diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8ad7375d8..89688e25e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.11.2" + ".": "0.11.3" } diff --git a/.stats.yml b/.stats.yml index 3ed63da63..e009762b6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 45 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp/agentex-sdk-9ab4b375245291b8e37dd1cbc054fa65f17b7e7db28729126ea9f1289dc99214.yml +configured_endpoints: 63 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp/agentex-sdk-5400cbfee7eab6b5ace17d760b4997fd68f8d169470ab5040cf268a185250a0b.yml openapi_spec_hash: d31d828c46635cbc20165177c7187a70 -config_hash: fb079ef7936611b032568661b8165f19 +config_hash: 81470e0e689fe06fa3e013ec01a7f84f diff --git a/CHANGELOG.md b/CHANGELOG.md index d20b3dee9..97e702c01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.11.3 (2026-05-19) + +Full Changelog: [v0.11.2...v0.11.3](https://github.com/scaleapi/scale-agentex-python/compare/v0.11.2...v0.11.3) + +### Features + +* **api:** add schedule, checkpoints, and deployment endpoints ([53b5c36](https://github.com/scaleapi/scale-agentex-python/commit/53b5c3673e54ee4b49debd049483f1a1d4b0673d)) + + +### Bug Fixes + +* resolve lint and test failures from new endpoints ([#360](https://github.com/scaleapi/scale-agentex-python/issues/360)) ([bdf129c](https://github.com/scaleapi/scale-agentex-python/commit/bdf129c8ab976ed84aa9932d5585a753280a6a34)) + ## 0.11.2 (2026-05-13) Full Changelog: [v0.11.1...v0.11.2](https://github.com/scaleapi/scale-agentex-python/compare/v0.11.1...v0.11.2) diff --git a/api.md b/api.md index 3b091ec88..9fbe95277 100644 --- a/api.md +++ b/api.md @@ -30,13 +30,60 @@ from agentex.types import ( Methods: -- client.agents.retrieve(agent_id) -> Agent -- client.agents.list(\*\*params) -> AgentListResponse -- client.agents.delete(agent_id) -> DeleteResponse -- client.agents.delete_by_name(agent_name) -> DeleteResponse -- client.agents.retrieve_by_name(agent_name) -> Agent -- client.agents.rpc(agent_id, \*\*params) -> AgentRpcResponse -- client.agents.rpc_by_name(agent_name, \*\*params) -> AgentRpcResponse +- client.agents.retrieve(agent_id) -> Agent +- client.agents.list(\*\*params) -> AgentListResponse +- client.agents.delete(agent_id) -> DeleteResponse +- client.agents.delete_by_name(agent_name) -> DeleteResponse +- client.agents.retrieve_by_name(agent_name) -> Agent +- client.agents.rpc(agent_id, \*\*params) -> AgentRpcResponse +- client.agents.rpc_by_name(agent_name, \*\*params) -> AgentRpcResponse + +## Deployments + +Types: + +```python +from agentex.types.agents import ( + DeploymentCreateResponse, + DeploymentRetrieveResponse, + DeploymentListResponse, + DeploymentPromoteResponse, +) +``` + +Methods: + +- client.agents.deployments.create(agent_id, \*\*params) -> DeploymentCreateResponse +- client.agents.deployments.retrieve(deployment_id, \*, agent_id) -> DeploymentRetrieveResponse +- client.agents.deployments.list(agent_id, \*\*params) -> DeploymentListResponse +- client.agents.deployments.delete(deployment_id, \*, agent_id) -> DeleteResponse +- client.agents.deployments.preview_rpc(deployment_id, \*, agent_id, \*\*params) -> AgentRpcResponse +- client.agents.deployments.promote(deployment_id, \*, agent_id) -> DeploymentPromoteResponse + +## Schedules + +Types: + +```python +from agentex.types.agents import ( + ScheduleCreateResponse, + ScheduleRetrieveResponse, + ScheduleListResponse, + SchedulePauseResponse, + ScheduleTriggerResponse, + ScheduleUnpauseResponse, +) +``` + +Methods: + +- client.agents.schedules.create(agent_id, \*\*params) -> ScheduleCreateResponse +- client.agents.schedules.retrieve(schedule_name, \*, agent_id) -> ScheduleRetrieveResponse +- client.agents.schedules.list(agent_id, \*\*params) -> ScheduleListResponse +- client.agents.schedules.delete(schedule_name, \*, agent_id) -> DeleteResponse +- client.agents.schedules.pause(schedule_name, \*, agent_id, \*\*params) -> SchedulePauseResponse +- client.agents.schedules.trigger(schedule_name, \*, agent_id) -> ScheduleTriggerResponse +- client.agents.schedules.unpause(schedule_name, \*, agent_id, \*\*params) -> ScheduleUnpauseResponse # Tasks @@ -181,3 +228,19 @@ Methods: - client.deployment_history.retrieve(deployment_id) -> DeploymentHistory - client.deployment_history.list(\*\*params) -> DeploymentHistoryListResponse + +# Checkpoints + +Types: + +```python +from agentex.types import CheckpointListResponse, CheckpointGetTupleResponse, CheckpointPutResponse +``` + +Methods: + +- client.checkpoints.list(\*\*params) -> CheckpointListResponse +- client.checkpoints.delete_thread(\*\*params) -> None +- client.checkpoints.get_tuple(\*\*params) -> Optional[CheckpointGetTupleResponse] +- client.checkpoints.put(\*\*params) -> CheckpointPutResponse +- client.checkpoints.put_writes(\*\*params) -> None diff --git a/pyproject.toml b/pyproject.toml index b0d7750b4..249c1d4d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agentex-sdk" -version = "0.11.2" +version = "0.11.3" description = "The official Python library for the agentex API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/agentex/_client.py b/src/agentex/_client.py index ecb11b155..1be05b767 100644 --- a/src/agentex/_client.py +++ b/src/agentex/_client.py @@ -35,13 +35,14 @@ ) if TYPE_CHECKING: - from .resources import spans, tasks, agents, events, states, tracker, messages, deployment_history + from .resources import spans, tasks, agents, events, states, tracker, messages, checkpoints, deployment_history from .resources.spans import SpansResource, AsyncSpansResource from .resources.tasks import TasksResource, AsyncTasksResource - from .resources.agents import AgentsResource, AsyncAgentsResource from .resources.events import EventsResource, AsyncEventsResource from .resources.states import StatesResource, AsyncStatesResource from .resources.tracker import TrackerResource, AsyncTrackerResource + from .resources.checkpoints import CheckpointsResource, AsyncCheckpointsResource + from .resources.agents.agents import AgentsResource, AsyncAgentsResource from .resources.messages.messages import MessagesResource, AsyncMessagesResource from .resources.deployment_history import DeploymentHistoryResource, AsyncDeploymentHistoryResource @@ -195,6 +196,12 @@ def deployment_history(self) -> DeploymentHistoryResource: return DeploymentHistoryResource(self) + @cached_property + def checkpoints(self) -> CheckpointsResource: + from .resources.checkpoints import CheckpointsResource + + return CheckpointsResource(self) + @cached_property def with_raw_response(self) -> AgentexWithRawResponse: return AgentexWithRawResponse(self) @@ -444,6 +451,12 @@ def deployment_history(self) -> AsyncDeploymentHistoryResource: return AsyncDeploymentHistoryResource(self) + @cached_property + def checkpoints(self) -> AsyncCheckpointsResource: + from .resources.checkpoints import AsyncCheckpointsResource + + return AsyncCheckpointsResource(self) + @cached_property def with_raw_response(self) -> AsyncAgentexWithRawResponse: return AsyncAgentexWithRawResponse(self) @@ -615,6 +628,12 @@ def deployment_history(self) -> deployment_history.DeploymentHistoryResourceWith return DeploymentHistoryResourceWithRawResponse(self._client.deployment_history) + @cached_property + def checkpoints(self) -> checkpoints.CheckpointsResourceWithRawResponse: + from .resources.checkpoints import CheckpointsResourceWithRawResponse + + return CheckpointsResourceWithRawResponse(self._client.checkpoints) + class AsyncAgentexWithRawResponse: _client: AsyncAgentex @@ -670,6 +689,12 @@ def deployment_history(self) -> deployment_history.AsyncDeploymentHistoryResourc return AsyncDeploymentHistoryResourceWithRawResponse(self._client.deployment_history) + @cached_property + def checkpoints(self) -> checkpoints.AsyncCheckpointsResourceWithRawResponse: + from .resources.checkpoints import AsyncCheckpointsResourceWithRawResponse + + return AsyncCheckpointsResourceWithRawResponse(self._client.checkpoints) + class AgentexWithStreamedResponse: _client: Agentex @@ -725,6 +750,12 @@ def deployment_history(self) -> deployment_history.DeploymentHistoryResourceWith return DeploymentHistoryResourceWithStreamingResponse(self._client.deployment_history) + @cached_property + def checkpoints(self) -> checkpoints.CheckpointsResourceWithStreamingResponse: + from .resources.checkpoints import CheckpointsResourceWithStreamingResponse + + return CheckpointsResourceWithStreamingResponse(self._client.checkpoints) + class AsyncAgentexWithStreamedResponse: _client: AsyncAgentex @@ -780,6 +811,12 @@ def deployment_history(self) -> deployment_history.AsyncDeploymentHistoryResourc return AsyncDeploymentHistoryResourceWithStreamingResponse(self._client.deployment_history) + @cached_property + def checkpoints(self) -> checkpoints.AsyncCheckpointsResourceWithStreamingResponse: + from .resources.checkpoints import AsyncCheckpointsResourceWithStreamingResponse + + return AsyncCheckpointsResourceWithStreamingResponse(self._client.checkpoints) + Client = Agentex diff --git a/src/agentex/_version.py b/src/agentex/_version.py index 76a981edd..f583a14df 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.2" # x-release-please-version +__version__ = "0.11.3" # x-release-please-version diff --git a/src/agentex/resources/__init__.py b/src/agentex/resources/__init__.py index d0ccdc803..00e0bfea8 100644 --- a/src/agentex/resources/__init__.py +++ b/src/agentex/resources/__init__.py @@ -56,6 +56,14 @@ MessagesResourceWithStreamingResponse, AsyncMessagesResourceWithStreamingResponse, ) +from .checkpoints import ( + CheckpointsResource, + AsyncCheckpointsResource, + CheckpointsResourceWithRawResponse, + AsyncCheckpointsResourceWithRawResponse, + CheckpointsResourceWithStreamingResponse, + AsyncCheckpointsResourceWithStreamingResponse, +) from .deployment_history import ( DeploymentHistoryResource, AsyncDeploymentHistoryResource, @@ -114,4 +122,10 @@ "AsyncDeploymentHistoryResourceWithRawResponse", "DeploymentHistoryResourceWithStreamingResponse", "AsyncDeploymentHistoryResourceWithStreamingResponse", + "CheckpointsResource", + "AsyncCheckpointsResource", + "CheckpointsResourceWithRawResponse", + "AsyncCheckpointsResourceWithRawResponse", + "CheckpointsResourceWithStreamingResponse", + "AsyncCheckpointsResourceWithStreamingResponse", ] diff --git a/src/agentex/resources/agents/__init__.py b/src/agentex/resources/agents/__init__.py new file mode 100644 index 000000000..3760c4db7 --- /dev/null +++ b/src/agentex/resources/agents/__init__.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .agents import ( + AgentsResource, + AsyncAgentsResource, + AgentsResourceWithRawResponse, + AsyncAgentsResourceWithRawResponse, + AgentsResourceWithStreamingResponse, + AsyncAgentsResourceWithStreamingResponse, +) +from .schedules import ( + SchedulesResource, + AsyncSchedulesResource, + SchedulesResourceWithRawResponse, + AsyncSchedulesResourceWithRawResponse, + SchedulesResourceWithStreamingResponse, + AsyncSchedulesResourceWithStreamingResponse, +) +from .deployments import ( + DeploymentsResource, + AsyncDeploymentsResource, + DeploymentsResourceWithRawResponse, + AsyncDeploymentsResourceWithRawResponse, + DeploymentsResourceWithStreamingResponse, + AsyncDeploymentsResourceWithStreamingResponse, +) + +__all__ = [ + "DeploymentsResource", + "AsyncDeploymentsResource", + "DeploymentsResourceWithRawResponse", + "AsyncDeploymentsResourceWithRawResponse", + "DeploymentsResourceWithStreamingResponse", + "AsyncDeploymentsResourceWithStreamingResponse", + "SchedulesResource", + "AsyncSchedulesResource", + "SchedulesResourceWithRawResponse", + "AsyncSchedulesResourceWithRawResponse", + "SchedulesResourceWithStreamingResponse", + "AsyncSchedulesResourceWithStreamingResponse", + "AgentsResource", + "AsyncAgentsResource", + "AgentsResourceWithRawResponse", + "AsyncAgentsResourceWithRawResponse", + "AgentsResourceWithStreamingResponse", + "AsyncAgentsResourceWithStreamingResponse", +] diff --git a/src/agentex/resources/agents.py b/src/agentex/resources/agents/agents.py similarity index 94% rename from src/agentex/resources/agents.py rename to src/agentex/resources/agents/agents.py index ec18fa11d..3dd0c770d 100644 --- a/src/agentex/resources/agents.py +++ b/src/agentex/resources/agents/agents.py @@ -9,20 +9,36 @@ import httpx from pydantic import ValidationError -from ..types import agent_rpc_params, agent_list_params, agent_rpc_by_name_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 -from .._resource import SyncAPIResource, AsyncAPIResource -from .._response import ( +from ...types import agent_rpc_params, agent_list_params, agent_rpc_by_name_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 +from .schedules import ( + SchedulesResource, + AsyncSchedulesResource, + SchedulesResourceWithRawResponse, + AsyncSchedulesResourceWithRawResponse, + SchedulesResourceWithStreamingResponse, + AsyncSchedulesResourceWithStreamingResponse, +) +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( to_raw_response_wrapper, to_streamed_response_wrapper, async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ..types.agent import Agent -from .._base_client import make_request_options -from ..types.agent_rpc_response import ( +from .deployments import ( + DeploymentsResource, + AsyncDeploymentsResource, + DeploymentsResourceWithRawResponse, + AsyncDeploymentsResourceWithRawResponse, + DeploymentsResourceWithStreamingResponse, + AsyncDeploymentsResourceWithStreamingResponse, +) +from ...types.agent import Agent +from ..._base_client import make_request_options +from ...types.agent_rpc_response import ( AgentRpcResponse, SendEventResponse, CancelTaskResponse, @@ -30,13 +46,21 @@ SendMessageResponse, SendMessageStreamResponse, ) -from ..types.agent_list_response import AgentListResponse -from ..types.shared.delete_response import DeleteResponse +from ...types.agent_list_response import AgentListResponse +from ...types.shared.delete_response import DeleteResponse __all__ = ["AgentsResource", "AsyncAgentsResource"] class AgentsResource(SyncAPIResource): + @cached_property + def deployments(self) -> DeploymentsResource: + return DeploymentsResource(self._client) + + @cached_property + def schedules(self) -> SchedulesResource: + return SchedulesResource(self._client) + @cached_property def with_raw_response(self) -> AgentsResourceWithRawResponse: """ @@ -638,6 +662,14 @@ def send_event( class AsyncAgentsResource(AsyncAPIResource): + @cached_property + def deployments(self) -> AsyncDeploymentsResource: + return AsyncDeploymentsResource(self._client) + + @cached_property + def schedules(self) -> AsyncSchedulesResource: + return AsyncSchedulesResource(self._client) + @cached_property def with_raw_response(self) -> AsyncAgentsResourceWithRawResponse: """ @@ -1265,6 +1297,14 @@ def __init__(self, agents: AgentsResource) -> None: agents.rpc_by_name, ) + @cached_property + def deployments(self) -> DeploymentsResourceWithRawResponse: + return DeploymentsResourceWithRawResponse(self._agents.deployments) + + @cached_property + def schedules(self) -> SchedulesResourceWithRawResponse: + return SchedulesResourceWithRawResponse(self._agents.schedules) + class AsyncAgentsResourceWithRawResponse: def __init__(self, agents: AsyncAgentsResource) -> None: @@ -1292,6 +1332,14 @@ def __init__(self, agents: AsyncAgentsResource) -> None: agents.rpc_by_name, ) + @cached_property + def deployments(self) -> AsyncDeploymentsResourceWithRawResponse: + return AsyncDeploymentsResourceWithRawResponse(self._agents.deployments) + + @cached_property + def schedules(self) -> AsyncSchedulesResourceWithRawResponse: + return AsyncSchedulesResourceWithRawResponse(self._agents.schedules) + class AgentsResourceWithStreamingResponse: def __init__(self, agents: AgentsResource) -> None: @@ -1319,6 +1367,14 @@ def __init__(self, agents: AgentsResource) -> None: agents.rpc_by_name, ) + @cached_property + def deployments(self) -> DeploymentsResourceWithStreamingResponse: + return DeploymentsResourceWithStreamingResponse(self._agents.deployments) + + @cached_property + def schedules(self) -> SchedulesResourceWithStreamingResponse: + return SchedulesResourceWithStreamingResponse(self._agents.schedules) + class AsyncAgentsResourceWithStreamingResponse: def __init__(self, agents: AsyncAgentsResource) -> None: @@ -1345,3 +1401,11 @@ def __init__(self, agents: AsyncAgentsResource) -> None: self.rpc_by_name = async_to_streamed_response_wrapper( agents.rpc_by_name, ) + + @cached_property + def deployments(self) -> AsyncDeploymentsResourceWithStreamingResponse: + return AsyncDeploymentsResourceWithStreamingResponse(self._agents.deployments) + + @cached_property + def schedules(self) -> AsyncSchedulesResourceWithStreamingResponse: + return AsyncSchedulesResourceWithStreamingResponse(self._agents.schedules) diff --git a/src/agentex/resources/agents/deployments.py b/src/agentex/resources/agents/deployments.py new file mode 100644 index 000000000..2e02cf8b5 --- /dev/null +++ b/src/agentex/resources/agents/deployments.py @@ -0,0 +1,725 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Union, Optional +from typing_extensions import Literal + +import httpx + +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.agents import deployment_list_params, deployment_create_params, deployment_preview_rpc_params +from ...types.agent_rpc_response import AgentRpcResponse +from ...types.shared.delete_response import DeleteResponse +from ...types.agents.deployment_list_response import DeploymentListResponse +from ...types.agents.deployment_create_response import DeploymentCreateResponse +from ...types.agents.deployment_promote_response import DeploymentPromoteResponse +from ...types.agents.deployment_retrieve_response import DeploymentRetrieveResponse + +__all__ = ["DeploymentsResource", "AsyncDeploymentsResource"] + + +class DeploymentsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> DeploymentsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#accessing-raw-response-data-eg-headers + """ + return DeploymentsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> DeploymentsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#with_streaming_response + """ + return DeploymentsResourceWithStreamingResponse(self) + + def create( + self, + agent_id: str, + *, + docker_image: str, + helm_release_name: Optional[str] | Omit = omit, + registration_metadata: Optional[Dict[str, object]] | Omit = omit, + sgp_deploy_id: Optional[str] | 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, + ) -> DeploymentCreateResponse: + """ + Create a new deployment record in PENDING status. + + Args: + docker_image: Full Docker image URI. + + helm_release_name: Helm release name. + + registration_metadata: Git/build metadata (commit_hash, branch_name, author_name, author_email, + build_timestamp). + + sgp_deploy_id: SGP deployment ID. + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + return self._post( + path_template("/agents/{agent_id}/deployments", agent_id=agent_id), + body=maybe_transform( + { + "docker_image": docker_image, + "helm_release_name": helm_release_name, + "registration_metadata": registration_metadata, + "sgp_deploy_id": sgp_deploy_id, + }, + deployment_create_params.DeploymentCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DeploymentCreateResponse, + ) + + def retrieve( + self, + deployment_id: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DeploymentRetrieveResponse: + """ + Get a specific deployment by ID. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return self._get( + path_template( + "/agents/{agent_id}/deployments/{deployment_id}", agent_id=agent_id, deployment_id=deployment_id + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DeploymentRetrieveResponse, + ) + + def list( + self, + agent_id: str, + *, + limit: int | Omit = omit, + order_by: Optional[str] | Omit = omit, + order_direction: str | Omit = omit, + page_number: int | 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, + ) -> DeploymentListResponse: + """ + List deployments for an agent, newest first. + + Args: + limit: Limit + + order_by: Field to order by + + order_direction: Order direction (asc or desc) + + page_number: Page number + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + return self._get( + path_template("/agents/{agent_id}/deployments", agent_id=agent_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "limit": limit, + "order_by": order_by, + "order_direction": order_direction, + "page_number": page_number, + }, + deployment_list_params.DeploymentListParams, + ), + ), + cast_to=DeploymentListResponse, + ) + + def delete( + self, + deployment_id: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DeleteResponse: + """ + Delete a non-production deployment. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return self._delete( + path_template( + "/agents/{agent_id}/deployments/{deployment_id}", agent_id=agent_id, deployment_id=deployment_id + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DeleteResponse, + ) + + def preview_rpc( + self, + deployment_id: str, + *, + agent_id: str, + method: Literal["event/send", "task/create", "message/send", "task/cancel"], + params: deployment_preview_rpc_params.Params, + id: Union[int, str, None] | Omit = omit, + jsonrpc: Literal["2.0"] | 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, + ) -> AgentRpcResponse: + """ + Send an RPC request to a specific deployment (for preview testing). + + Args: + params: The parameters for the agent RPC request + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return self._post( + path_template( + "/agents/{agent_id}/deployments/{deployment_id}/rpc", agent_id=agent_id, deployment_id=deployment_id + ), + body=maybe_transform( + { + "method": method, + "params": params, + "id": id, + "jsonrpc": jsonrpc, + }, + deployment_preview_rpc_params.DeploymentPreviewRpcParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AgentRpcResponse, + ) + + def promote( + self, + deployment_id: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DeploymentPromoteResponse: + """ + Promote a deployment to production with atomic cutover. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return self._post( + path_template( + "/agents/{agent_id}/deployments/{deployment_id}/promote", agent_id=agent_id, deployment_id=deployment_id + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DeploymentPromoteResponse, + ) + + +class AsyncDeploymentsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncDeploymentsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#accessing-raw-response-data-eg-headers + """ + return AsyncDeploymentsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncDeploymentsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#with_streaming_response + """ + return AsyncDeploymentsResourceWithStreamingResponse(self) + + async def create( + self, + agent_id: str, + *, + docker_image: str, + helm_release_name: Optional[str] | Omit = omit, + registration_metadata: Optional[Dict[str, object]] | Omit = omit, + sgp_deploy_id: Optional[str] | 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, + ) -> DeploymentCreateResponse: + """ + Create a new deployment record in PENDING status. + + Args: + docker_image: Full Docker image URI. + + helm_release_name: Helm release name. + + registration_metadata: Git/build metadata (commit_hash, branch_name, author_name, author_email, + build_timestamp). + + sgp_deploy_id: SGP deployment ID. + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + return await self._post( + path_template("/agents/{agent_id}/deployments", agent_id=agent_id), + body=await async_maybe_transform( + { + "docker_image": docker_image, + "helm_release_name": helm_release_name, + "registration_metadata": registration_metadata, + "sgp_deploy_id": sgp_deploy_id, + }, + deployment_create_params.DeploymentCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DeploymentCreateResponse, + ) + + async def retrieve( + self, + deployment_id: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DeploymentRetrieveResponse: + """ + Get a specific deployment by ID. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return await self._get( + path_template( + "/agents/{agent_id}/deployments/{deployment_id}", agent_id=agent_id, deployment_id=deployment_id + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DeploymentRetrieveResponse, + ) + + async def list( + self, + agent_id: str, + *, + limit: int | Omit = omit, + order_by: Optional[str] | Omit = omit, + order_direction: str | Omit = omit, + page_number: int | 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, + ) -> DeploymentListResponse: + """ + List deployments for an agent, newest first. + + Args: + limit: Limit + + order_by: Field to order by + + order_direction: Order direction (asc or desc) + + page_number: Page number + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + return await self._get( + path_template("/agents/{agent_id}/deployments", agent_id=agent_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "limit": limit, + "order_by": order_by, + "order_direction": order_direction, + "page_number": page_number, + }, + deployment_list_params.DeploymentListParams, + ), + ), + cast_to=DeploymentListResponse, + ) + + async def delete( + self, + deployment_id: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DeleteResponse: + """ + Delete a non-production deployment. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return await self._delete( + path_template( + "/agents/{agent_id}/deployments/{deployment_id}", agent_id=agent_id, deployment_id=deployment_id + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DeleteResponse, + ) + + async def preview_rpc( + self, + deployment_id: str, + *, + agent_id: str, + method: Literal["event/send", "task/create", "message/send", "task/cancel"], + params: deployment_preview_rpc_params.Params, + id: Union[int, str, None] | Omit = omit, + jsonrpc: Literal["2.0"] | 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, + ) -> AgentRpcResponse: + """ + Send an RPC request to a specific deployment (for preview testing). + + Args: + params: The parameters for the agent RPC request + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return await self._post( + path_template( + "/agents/{agent_id}/deployments/{deployment_id}/rpc", agent_id=agent_id, deployment_id=deployment_id + ), + body=await async_maybe_transform( + { + "method": method, + "params": params, + "id": id, + "jsonrpc": jsonrpc, + }, + deployment_preview_rpc_params.DeploymentPreviewRpcParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AgentRpcResponse, + ) + + async def promote( + self, + deployment_id: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DeploymentPromoteResponse: + """ + Promote a deployment to production with atomic cutover. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return await self._post( + path_template( + "/agents/{agent_id}/deployments/{deployment_id}/promote", agent_id=agent_id, deployment_id=deployment_id + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DeploymentPromoteResponse, + ) + + +class DeploymentsResourceWithRawResponse: + def __init__(self, deployments: DeploymentsResource) -> None: + self._deployments = deployments + + self.create = to_raw_response_wrapper( + deployments.create, + ) + self.retrieve = to_raw_response_wrapper( + deployments.retrieve, + ) + self.list = to_raw_response_wrapper( + deployments.list, + ) + self.delete = to_raw_response_wrapper( + deployments.delete, + ) + self.preview_rpc = to_raw_response_wrapper( + deployments.preview_rpc, + ) + self.promote = to_raw_response_wrapper( + deployments.promote, + ) + + +class AsyncDeploymentsResourceWithRawResponse: + def __init__(self, deployments: AsyncDeploymentsResource) -> None: + self._deployments = deployments + + self.create = async_to_raw_response_wrapper( + deployments.create, + ) + self.retrieve = async_to_raw_response_wrapper( + deployments.retrieve, + ) + self.list = async_to_raw_response_wrapper( + deployments.list, + ) + self.delete = async_to_raw_response_wrapper( + deployments.delete, + ) + self.preview_rpc = async_to_raw_response_wrapper( + deployments.preview_rpc, + ) + self.promote = async_to_raw_response_wrapper( + deployments.promote, + ) + + +class DeploymentsResourceWithStreamingResponse: + def __init__(self, deployments: DeploymentsResource) -> None: + self._deployments = deployments + + self.create = to_streamed_response_wrapper( + deployments.create, + ) + self.retrieve = to_streamed_response_wrapper( + deployments.retrieve, + ) + self.list = to_streamed_response_wrapper( + deployments.list, + ) + self.delete = to_streamed_response_wrapper( + deployments.delete, + ) + self.preview_rpc = to_streamed_response_wrapper( + deployments.preview_rpc, + ) + self.promote = to_streamed_response_wrapper( + deployments.promote, + ) + + +class AsyncDeploymentsResourceWithStreamingResponse: + def __init__(self, deployments: AsyncDeploymentsResource) -> None: + self._deployments = deployments + + self.create = async_to_streamed_response_wrapper( + deployments.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + deployments.retrieve, + ) + self.list = async_to_streamed_response_wrapper( + deployments.list, + ) + self.delete = async_to_streamed_response_wrapper( + deployments.delete, + ) + self.preview_rpc = async_to_streamed_response_wrapper( + deployments.preview_rpc, + ) + self.promote = async_to_streamed_response_wrapper( + deployments.promote, + ) diff --git a/src/agentex/resources/agents/schedules.py b/src/agentex/resources/agents/schedules.py new file mode 100644 index 000000000..271f6c835 --- /dev/null +++ b/src/agentex/resources/agents/schedules.py @@ -0,0 +1,810 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Union, Optional +from datetime import datetime + +import httpx + +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.agents import schedule_list_params, schedule_pause_params, schedule_create_params, schedule_unpause_params +from ...types.shared.delete_response import DeleteResponse +from ...types.agents.schedule_list_response import ScheduleListResponse +from ...types.agents.schedule_pause_response import SchedulePauseResponse +from ...types.agents.schedule_create_response import ScheduleCreateResponse +from ...types.agents.schedule_trigger_response import ScheduleTriggerResponse +from ...types.agents.schedule_unpause_response import ScheduleUnpauseResponse +from ...types.agents.schedule_retrieve_response import ScheduleRetrieveResponse + +__all__ = ["SchedulesResource", "AsyncSchedulesResource"] + + +class SchedulesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> SchedulesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#accessing-raw-response-data-eg-headers + """ + return SchedulesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> SchedulesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#with_streaming_response + """ + return SchedulesResourceWithStreamingResponse(self) + + def create( + self, + agent_id: str, + *, + name: str, + task_queue: str, + workflow_name: str, + cron_expression: Optional[str] | Omit = omit, + end_at: Union[str, datetime, None] | Omit = omit, + execution_timeout_seconds: Optional[int] | Omit = omit, + interval_seconds: Optional[int] | Omit = omit, + paused: bool | Omit = omit, + start_at: Union[str, datetime, None] | Omit = omit, + workflow_params: 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, + ) -> ScheduleCreateResponse: + """ + Create a new schedule for recurring workflow execution for an agent. + + Args: + name: Human-readable name for the schedule (e.g., 'weekly-profiling'). Will be + combined with agent_id to form the full schedule_id. + + task_queue: Temporal task queue where the agent's worker is listening + + workflow_name: Name of the Temporal workflow to execute (e.g., 'sae-orchestrator') + + cron_expression: Cron expression for scheduling (e.g., '0 0 \\** \\** 0' for weekly on Sunday) + + end_at: When the schedule should stop being active + + execution_timeout_seconds: Maximum time in seconds for each workflow execution + + interval_seconds: Alternative to cron - run every N seconds + + paused: Whether to create the schedule in a paused state + + start_at: When the schedule should start being active + + workflow_params: Parameters to pass to the workflow + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + return self._post( + path_template("/agents/{agent_id}/schedules", agent_id=agent_id), + body=maybe_transform( + { + "name": name, + "task_queue": task_queue, + "workflow_name": workflow_name, + "cron_expression": cron_expression, + "end_at": end_at, + "execution_timeout_seconds": execution_timeout_seconds, + "interval_seconds": interval_seconds, + "paused": paused, + "start_at": start_at, + "workflow_params": workflow_params, + }, + schedule_create_params.ScheduleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ScheduleCreateResponse, + ) + + def retrieve( + self, + schedule_name: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ScheduleRetrieveResponse: + """ + Get details of a schedule by its name. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not schedule_name: + raise ValueError(f"Expected a non-empty value for `schedule_name` but received {schedule_name!r}") + return self._get( + path_template( + "/agents/{agent_id}/schedules/{schedule_name}", agent_id=agent_id, schedule_name=schedule_name + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ScheduleRetrieveResponse, + ) + + def list( + self, + agent_id: str, + *, + page_size: int | 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, + ) -> ScheduleListResponse: + """ + List all schedules for an agent. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + return self._get( + path_template("/agents/{agent_id}/schedules", agent_id=agent_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"page_size": page_size}, schedule_list_params.ScheduleListParams), + ), + cast_to=ScheduleListResponse, + ) + + def delete( + self, + schedule_name: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DeleteResponse: + """ + Delete a schedule permanently. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not schedule_name: + raise ValueError(f"Expected a non-empty value for `schedule_name` but received {schedule_name!r}") + return self._delete( + path_template( + "/agents/{agent_id}/schedules/{schedule_name}", agent_id=agent_id, schedule_name=schedule_name + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DeleteResponse, + ) + + def pause( + self, + schedule_name: str, + *, + agent_id: str, + note: Optional[str] | 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, + ) -> SchedulePauseResponse: + """ + Pause a schedule to stop it from executing. + + Args: + note: Optional note explaining why the schedule was paused + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not schedule_name: + raise ValueError(f"Expected a non-empty value for `schedule_name` but received {schedule_name!r}") + return self._post( + path_template( + "/agents/{agent_id}/schedules/{schedule_name}/pause", agent_id=agent_id, schedule_name=schedule_name + ), + body=maybe_transform({"note": note}, schedule_pause_params.SchedulePauseParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SchedulePauseResponse, + ) + + def trigger( + self, + schedule_name: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ScheduleTriggerResponse: + """ + Trigger a schedule to run immediately, regardless of its regular schedule. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not schedule_name: + raise ValueError(f"Expected a non-empty value for `schedule_name` but received {schedule_name!r}") + return self._post( + path_template( + "/agents/{agent_id}/schedules/{schedule_name}/trigger", agent_id=agent_id, schedule_name=schedule_name + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ScheduleTriggerResponse, + ) + + def unpause( + self, + schedule_name: str, + *, + agent_id: str, + note: Optional[str] | 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, + ) -> ScheduleUnpauseResponse: + """ + Unpause/resume a schedule to allow it to execute again. + + Args: + note: Optional note explaining why the schedule was unpaused + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not schedule_name: + raise ValueError(f"Expected a non-empty value for `schedule_name` but received {schedule_name!r}") + return self._post( + path_template( + "/agents/{agent_id}/schedules/{schedule_name}/unpause", agent_id=agent_id, schedule_name=schedule_name + ), + body=maybe_transform({"note": note}, schedule_unpause_params.ScheduleUnpauseParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ScheduleUnpauseResponse, + ) + + +class AsyncSchedulesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncSchedulesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#accessing-raw-response-data-eg-headers + """ + return AsyncSchedulesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSchedulesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#with_streaming_response + """ + return AsyncSchedulesResourceWithStreamingResponse(self) + + async def create( + self, + agent_id: str, + *, + name: str, + task_queue: str, + workflow_name: str, + cron_expression: Optional[str] | Omit = omit, + end_at: Union[str, datetime, None] | Omit = omit, + execution_timeout_seconds: Optional[int] | Omit = omit, + interval_seconds: Optional[int] | Omit = omit, + paused: bool | Omit = omit, + start_at: Union[str, datetime, None] | Omit = omit, + workflow_params: 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, + ) -> ScheduleCreateResponse: + """ + Create a new schedule for recurring workflow execution for an agent. + + Args: + name: Human-readable name for the schedule (e.g., 'weekly-profiling'). Will be + combined with agent_id to form the full schedule_id. + + task_queue: Temporal task queue where the agent's worker is listening + + workflow_name: Name of the Temporal workflow to execute (e.g., 'sae-orchestrator') + + cron_expression: Cron expression for scheduling (e.g., '0 0 \\** \\** 0' for weekly on Sunday) + + end_at: When the schedule should stop being active + + execution_timeout_seconds: Maximum time in seconds for each workflow execution + + interval_seconds: Alternative to cron - run every N seconds + + paused: Whether to create the schedule in a paused state + + start_at: When the schedule should start being active + + workflow_params: Parameters to pass to the workflow + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + return await self._post( + path_template("/agents/{agent_id}/schedules", agent_id=agent_id), + body=await async_maybe_transform( + { + "name": name, + "task_queue": task_queue, + "workflow_name": workflow_name, + "cron_expression": cron_expression, + "end_at": end_at, + "execution_timeout_seconds": execution_timeout_seconds, + "interval_seconds": interval_seconds, + "paused": paused, + "start_at": start_at, + "workflow_params": workflow_params, + }, + schedule_create_params.ScheduleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ScheduleCreateResponse, + ) + + async def retrieve( + self, + schedule_name: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ScheduleRetrieveResponse: + """ + Get details of a schedule by its name. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not schedule_name: + raise ValueError(f"Expected a non-empty value for `schedule_name` but received {schedule_name!r}") + return await self._get( + path_template( + "/agents/{agent_id}/schedules/{schedule_name}", agent_id=agent_id, schedule_name=schedule_name + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ScheduleRetrieveResponse, + ) + + async def list( + self, + agent_id: str, + *, + page_size: int | 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, + ) -> ScheduleListResponse: + """ + List all schedules for an agent. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + return await self._get( + path_template("/agents/{agent_id}/schedules", agent_id=agent_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"page_size": page_size}, schedule_list_params.ScheduleListParams), + ), + cast_to=ScheduleListResponse, + ) + + async def delete( + self, + schedule_name: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DeleteResponse: + """ + Delete a schedule permanently. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not schedule_name: + raise ValueError(f"Expected a non-empty value for `schedule_name` but received {schedule_name!r}") + return await self._delete( + path_template( + "/agents/{agent_id}/schedules/{schedule_name}", agent_id=agent_id, schedule_name=schedule_name + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DeleteResponse, + ) + + async def pause( + self, + schedule_name: str, + *, + agent_id: str, + note: Optional[str] | 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, + ) -> SchedulePauseResponse: + """ + Pause a schedule to stop it from executing. + + Args: + note: Optional note explaining why the schedule was paused + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not schedule_name: + raise ValueError(f"Expected a non-empty value for `schedule_name` but received {schedule_name!r}") + return await self._post( + path_template( + "/agents/{agent_id}/schedules/{schedule_name}/pause", agent_id=agent_id, schedule_name=schedule_name + ), + body=await async_maybe_transform({"note": note}, schedule_pause_params.SchedulePauseParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SchedulePauseResponse, + ) + + async def trigger( + self, + schedule_name: str, + *, + agent_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ScheduleTriggerResponse: + """ + Trigger a schedule to run immediately, regardless of its regular schedule. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not schedule_name: + raise ValueError(f"Expected a non-empty value for `schedule_name` but received {schedule_name!r}") + return await self._post( + path_template( + "/agents/{agent_id}/schedules/{schedule_name}/trigger", agent_id=agent_id, schedule_name=schedule_name + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ScheduleTriggerResponse, + ) + + async def unpause( + self, + schedule_name: str, + *, + agent_id: str, + note: Optional[str] | 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, + ) -> ScheduleUnpauseResponse: + """ + Unpause/resume a schedule to allow it to execute again. + + Args: + note: Optional note explaining why the schedule was unpaused + + 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 + """ + if not agent_id: + raise ValueError(f"Expected a non-empty value for `agent_id` but received {agent_id!r}") + if not schedule_name: + raise ValueError(f"Expected a non-empty value for `schedule_name` but received {schedule_name!r}") + return await self._post( + path_template( + "/agents/{agent_id}/schedules/{schedule_name}/unpause", agent_id=agent_id, schedule_name=schedule_name + ), + body=await async_maybe_transform({"note": note}, schedule_unpause_params.ScheduleUnpauseParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ScheduleUnpauseResponse, + ) + + +class SchedulesResourceWithRawResponse: + def __init__(self, schedules: SchedulesResource) -> None: + self._schedules = schedules + + self.create = to_raw_response_wrapper( + schedules.create, + ) + self.retrieve = to_raw_response_wrapper( + schedules.retrieve, + ) + self.list = to_raw_response_wrapper( + schedules.list, + ) + self.delete = to_raw_response_wrapper( + schedules.delete, + ) + self.pause = to_raw_response_wrapper( + schedules.pause, + ) + self.trigger = to_raw_response_wrapper( + schedules.trigger, + ) + self.unpause = to_raw_response_wrapper( + schedules.unpause, + ) + + +class AsyncSchedulesResourceWithRawResponse: + def __init__(self, schedules: AsyncSchedulesResource) -> None: + self._schedules = schedules + + self.create = async_to_raw_response_wrapper( + schedules.create, + ) + self.retrieve = async_to_raw_response_wrapper( + schedules.retrieve, + ) + self.list = async_to_raw_response_wrapper( + schedules.list, + ) + self.delete = async_to_raw_response_wrapper( + schedules.delete, + ) + self.pause = async_to_raw_response_wrapper( + schedules.pause, + ) + self.trigger = async_to_raw_response_wrapper( + schedules.trigger, + ) + self.unpause = async_to_raw_response_wrapper( + schedules.unpause, + ) + + +class SchedulesResourceWithStreamingResponse: + def __init__(self, schedules: SchedulesResource) -> None: + self._schedules = schedules + + self.create = to_streamed_response_wrapper( + schedules.create, + ) + self.retrieve = to_streamed_response_wrapper( + schedules.retrieve, + ) + self.list = to_streamed_response_wrapper( + schedules.list, + ) + self.delete = to_streamed_response_wrapper( + schedules.delete, + ) + self.pause = to_streamed_response_wrapper( + schedules.pause, + ) + self.trigger = to_streamed_response_wrapper( + schedules.trigger, + ) + self.unpause = to_streamed_response_wrapper( + schedules.unpause, + ) + + +class AsyncSchedulesResourceWithStreamingResponse: + def __init__(self, schedules: AsyncSchedulesResource) -> None: + self._schedules = schedules + + self.create = async_to_streamed_response_wrapper( + schedules.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + schedules.retrieve, + ) + self.list = async_to_streamed_response_wrapper( + schedules.list, + ) + self.delete = async_to_streamed_response_wrapper( + schedules.delete, + ) + self.pause = async_to_streamed_response_wrapper( + schedules.pause, + ) + self.trigger = async_to_streamed_response_wrapper( + schedules.trigger, + ) + self.unpause = async_to_streamed_response_wrapper( + schedules.unpause, + ) diff --git a/src/agentex/resources/checkpoints.py b/src/agentex/resources/checkpoints.py new file mode 100644 index 000000000..87e0f0c8b --- /dev/null +++ b/src/agentex/resources/checkpoints.py @@ -0,0 +1,589 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Iterable, Optional + +import httpx + +from ..types import ( + checkpoint_put_params, + checkpoint_list_params, + checkpoint_get_tuple_params, + checkpoint_put_writes_params, + checkpoint_delete_thread_params, +) +from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given +from .._utils import maybe_transform, async_maybe_transform +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .._base_client import make_request_options +from ..types.checkpoint_put_response import CheckpointPutResponse +from ..types.checkpoint_list_response import CheckpointListResponse +from ..types.checkpoint_get_tuple_response import CheckpointGetTupleResponse + +__all__ = ["CheckpointsResource", "AsyncCheckpointsResource"] + + +class CheckpointsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> CheckpointsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#accessing-raw-response-data-eg-headers + """ + return CheckpointsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> CheckpointsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#with_streaming_response + """ + return CheckpointsResourceWithStreamingResponse(self) + + def list( + self, + *, + thread_id: str, + before_checkpoint_id: Optional[str] | Omit = omit, + checkpoint_ns: Optional[str] | Omit = omit, + filter_metadata: Optional[Dict[str, object]] | Omit = omit, + limit: int | 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, + ) -> CheckpointListResponse: + """ + List Checkpoints + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/checkpoints/list", + body=maybe_transform( + { + "thread_id": thread_id, + "before_checkpoint_id": before_checkpoint_id, + "checkpoint_ns": checkpoint_ns, + "filter_metadata": filter_metadata, + "limit": limit, + }, + checkpoint_list_params.CheckpointListParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CheckpointListResponse, + ) + + def delete_thread( + self, + *, + thread_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Delete Thread + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._post( + "/checkpoints/delete-thread", + body=maybe_transform( + {"thread_id": thread_id}, checkpoint_delete_thread_params.CheckpointDeleteThreadParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def get_tuple( + self, + *, + thread_id: str, + checkpoint_id: Optional[str] | Omit = omit, + checkpoint_ns: str | 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, + ) -> Optional[CheckpointGetTupleResponse]: + """ + Get Checkpoint Tuple + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/checkpoints/get-tuple", + body=maybe_transform( + { + "thread_id": thread_id, + "checkpoint_id": checkpoint_id, + "checkpoint_ns": checkpoint_ns, + }, + checkpoint_get_tuple_params.CheckpointGetTupleParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CheckpointGetTupleResponse, + ) + + def put( + self, + *, + checkpoint: Dict[str, object], + checkpoint_id: str, + thread_id: str, + blobs: Iterable[checkpoint_put_params.Blob] | Omit = omit, + checkpoint_ns: str | Omit = omit, + metadata: Dict[str, object] | Omit = omit, + parent_checkpoint_id: Optional[str] | 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, + ) -> CheckpointPutResponse: + """ + Put Checkpoint + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/checkpoints/put", + body=maybe_transform( + { + "checkpoint": checkpoint, + "checkpoint_id": checkpoint_id, + "thread_id": thread_id, + "blobs": blobs, + "checkpoint_ns": checkpoint_ns, + "metadata": metadata, + "parent_checkpoint_id": parent_checkpoint_id, + }, + checkpoint_put_params.CheckpointPutParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CheckpointPutResponse, + ) + + def put_writes( + self, + *, + checkpoint_id: str, + thread_id: str, + writes: Iterable[checkpoint_put_writes_params.Write], + checkpoint_ns: str | Omit = omit, + upsert: bool | 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, + ) -> None: + """ + Put Writes + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._post( + "/checkpoints/put-writes", + body=maybe_transform( + { + "checkpoint_id": checkpoint_id, + "thread_id": thread_id, + "writes": writes, + "checkpoint_ns": checkpoint_ns, + "upsert": upsert, + }, + checkpoint_put_writes_params.CheckpointPutWritesParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + +class AsyncCheckpointsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncCheckpointsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#accessing-raw-response-data-eg-headers + """ + return AsyncCheckpointsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncCheckpointsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/scaleapi/scale-agentex-python#with_streaming_response + """ + return AsyncCheckpointsResourceWithStreamingResponse(self) + + async def list( + self, + *, + thread_id: str, + before_checkpoint_id: Optional[str] | Omit = omit, + checkpoint_ns: Optional[str] | Omit = omit, + filter_metadata: Optional[Dict[str, object]] | Omit = omit, + limit: int | 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, + ) -> CheckpointListResponse: + """ + List Checkpoints + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/checkpoints/list", + body=await async_maybe_transform( + { + "thread_id": thread_id, + "before_checkpoint_id": before_checkpoint_id, + "checkpoint_ns": checkpoint_ns, + "filter_metadata": filter_metadata, + "limit": limit, + }, + checkpoint_list_params.CheckpointListParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CheckpointListResponse, + ) + + async def delete_thread( + self, + *, + thread_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Delete Thread + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._post( + "/checkpoints/delete-thread", + body=await async_maybe_transform( + {"thread_id": thread_id}, checkpoint_delete_thread_params.CheckpointDeleteThreadParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def get_tuple( + self, + *, + thread_id: str, + checkpoint_id: Optional[str] | Omit = omit, + checkpoint_ns: str | 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, + ) -> Optional[CheckpointGetTupleResponse]: + """ + Get Checkpoint Tuple + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/checkpoints/get-tuple", + body=await async_maybe_transform( + { + "thread_id": thread_id, + "checkpoint_id": checkpoint_id, + "checkpoint_ns": checkpoint_ns, + }, + checkpoint_get_tuple_params.CheckpointGetTupleParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CheckpointGetTupleResponse, + ) + + async def put( + self, + *, + checkpoint: Dict[str, object], + checkpoint_id: str, + thread_id: str, + blobs: Iterable[checkpoint_put_params.Blob] | Omit = omit, + checkpoint_ns: str | Omit = omit, + metadata: Dict[str, object] | Omit = omit, + parent_checkpoint_id: Optional[str] | 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, + ) -> CheckpointPutResponse: + """ + Put Checkpoint + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/checkpoints/put", + body=await async_maybe_transform( + { + "checkpoint": checkpoint, + "checkpoint_id": checkpoint_id, + "thread_id": thread_id, + "blobs": blobs, + "checkpoint_ns": checkpoint_ns, + "metadata": metadata, + "parent_checkpoint_id": parent_checkpoint_id, + }, + checkpoint_put_params.CheckpointPutParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CheckpointPutResponse, + ) + + async def put_writes( + self, + *, + checkpoint_id: str, + thread_id: str, + writes: Iterable[checkpoint_put_writes_params.Write], + checkpoint_ns: str | Omit = omit, + upsert: bool | 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, + ) -> None: + """ + Put Writes + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._post( + "/checkpoints/put-writes", + body=await async_maybe_transform( + { + "checkpoint_id": checkpoint_id, + "thread_id": thread_id, + "writes": writes, + "checkpoint_ns": checkpoint_ns, + "upsert": upsert, + }, + checkpoint_put_writes_params.CheckpointPutWritesParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + +class CheckpointsResourceWithRawResponse: + def __init__(self, checkpoints: CheckpointsResource) -> None: + self._checkpoints = checkpoints + + self.list = to_raw_response_wrapper( + checkpoints.list, + ) + self.delete_thread = to_raw_response_wrapper( + checkpoints.delete_thread, + ) + self.get_tuple = to_raw_response_wrapper( + checkpoints.get_tuple, + ) + self.put = to_raw_response_wrapper( + checkpoints.put, + ) + self.put_writes = to_raw_response_wrapper( + checkpoints.put_writes, + ) + + +class AsyncCheckpointsResourceWithRawResponse: + def __init__(self, checkpoints: AsyncCheckpointsResource) -> None: + self._checkpoints = checkpoints + + self.list = async_to_raw_response_wrapper( + checkpoints.list, + ) + self.delete_thread = async_to_raw_response_wrapper( + checkpoints.delete_thread, + ) + self.get_tuple = async_to_raw_response_wrapper( + checkpoints.get_tuple, + ) + self.put = async_to_raw_response_wrapper( + checkpoints.put, + ) + self.put_writes = async_to_raw_response_wrapper( + checkpoints.put_writes, + ) + + +class CheckpointsResourceWithStreamingResponse: + def __init__(self, checkpoints: CheckpointsResource) -> None: + self._checkpoints = checkpoints + + self.list = to_streamed_response_wrapper( + checkpoints.list, + ) + self.delete_thread = to_streamed_response_wrapper( + checkpoints.delete_thread, + ) + self.get_tuple = to_streamed_response_wrapper( + checkpoints.get_tuple, + ) + self.put = to_streamed_response_wrapper( + checkpoints.put, + ) + self.put_writes = to_streamed_response_wrapper( + checkpoints.put_writes, + ) + + +class AsyncCheckpointsResourceWithStreamingResponse: + def __init__(self, checkpoints: AsyncCheckpointsResource) -> None: + self._checkpoints = checkpoints + + self.list = async_to_streamed_response_wrapper( + checkpoints.list, + ) + self.delete_thread = async_to_streamed_response_wrapper( + checkpoints.delete_thread, + ) + self.get_tuple = async_to_streamed_response_wrapper( + checkpoints.get_tuple, + ) + self.put = async_to_streamed_response_wrapper( + checkpoints.put, + ) + self.put_writes = async_to_streamed_response_wrapper( + checkpoints.put_writes, + ) diff --git a/src/agentex/types/__init__.py b/src/agentex/types/__init__.py index 5125c00b0..8dc75de60 100644 --- a/src/agentex/types/__init__.py +++ b/src/agentex/types/__init__.py @@ -52,6 +52,7 @@ from .task_message_content import TaskMessageContent as TaskMessageContent from .task_retrieve_params import TaskRetrieveParams as TaskRetrieveParams from .tool_request_content import ToolRequestContent as ToolRequestContent +from .checkpoint_put_params import CheckpointPutParams as CheckpointPutParams from .message_create_params import MessageCreateParams as MessageCreateParams from .message_list_response import MessageListResponse as MessageListResponse from .message_update_params import MessageUpdateParams as MessageUpdateParams @@ -59,20 +60,27 @@ from .tool_response_content import ToolResponseContent as ToolResponseContent from .tracker_list_response import TrackerListResponse as TrackerListResponse from .tracker_update_params import TrackerUpdateParams as TrackerUpdateParams +from .checkpoint_list_params import CheckpointListParams as CheckpointListParams from .task_retrieve_response import TaskRetrieveResponse as TaskRetrieveResponse +from .checkpoint_put_response import CheckpointPutResponse as CheckpointPutResponse from .reasoning_content_delta import ReasoningContentDelta as ReasoningContentDelta from .reasoning_content_param import ReasoningContentParam as ReasoningContentParam from .reasoning_summary_delta import ReasoningSummaryDelta as ReasoningSummaryDelta from .agent_rpc_by_name_params import AgentRpcByNameParams as AgentRpcByNameParams +from .checkpoint_list_response import CheckpointListResponse as CheckpointListResponse from .task_update_by_id_params import TaskUpdateByIDParams as TaskUpdateByIDParams 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 .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 from .task_query_workflow_response import TaskQueryWorkflowResponse as TaskQueryWorkflowResponse from .task_retrieve_by_name_params import TaskRetrieveByNameParams as TaskRetrieveByNameParams +from .checkpoint_get_tuple_response import CheckpointGetTupleResponse as CheckpointGetTupleResponse from .message_list_paginated_params import MessageListPaginatedParams as MessageListPaginatedParams from .deployment_history_list_params import DeploymentHistoryListParams as DeploymentHistoryListParams from .task_retrieve_by_name_response import TaskRetrieveByNameResponse as TaskRetrieveByNameResponse +from .checkpoint_delete_thread_params import CheckpointDeleteThreadParams as CheckpointDeleteThreadParams from .message_list_paginated_response import MessageListPaginatedResponse as MessageListPaginatedResponse from .deployment_history_list_response import DeploymentHistoryListResponse as DeploymentHistoryListResponse diff --git a/src/agentex/types/agent_rpc_response.py b/src/agentex/types/agent_rpc_response.py index 8b464b8d7..97f0f9c2f 100644 --- a/src/agentex/types/agent_rpc_response.py +++ b/src/agentex/types/agent_rpc_response.py @@ -11,7 +11,14 @@ from .agent_rpc_result import AgentRpcResult from .task_message_update import TaskMessageUpdate -__all__ = ["AgentRpcResponse"] +__all__ = [ + "AgentRpcResponse", + "CancelTaskResponse", + "CreateTaskResponse", + "SendEventResponse", + "SendMessageResponse", + "SendMessageStreamResponse", +] class BaseAgentRpcResponse(BaseModel): diff --git a/src/agentex/types/agents/__init__.py b/src/agentex/types/agents/__init__.py new file mode 100644 index 000000000..27c802742 --- /dev/null +++ b/src/agentex/types/agents/__init__.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .schedule_list_params import ScheduleListParams as ScheduleListParams +from .schedule_pause_params import SchedulePauseParams as SchedulePauseParams +from .deployment_list_params import DeploymentListParams as DeploymentListParams +from .schedule_create_params import ScheduleCreateParams as ScheduleCreateParams +from .schedule_list_response import ScheduleListResponse as ScheduleListResponse +from .schedule_pause_response import SchedulePauseResponse as SchedulePauseResponse +from .schedule_unpause_params import ScheduleUnpauseParams as ScheduleUnpauseParams +from .deployment_create_params import DeploymentCreateParams as DeploymentCreateParams +from .deployment_list_response import DeploymentListResponse as DeploymentListResponse +from .schedule_create_response import ScheduleCreateResponse as ScheduleCreateResponse +from .schedule_trigger_response import ScheduleTriggerResponse as ScheduleTriggerResponse +from .schedule_unpause_response import ScheduleUnpauseResponse as ScheduleUnpauseResponse +from .deployment_create_response import DeploymentCreateResponse as DeploymentCreateResponse +from .schedule_retrieve_response import ScheduleRetrieveResponse as ScheduleRetrieveResponse +from .deployment_promote_response import DeploymentPromoteResponse as DeploymentPromoteResponse +from .deployment_retrieve_response import DeploymentRetrieveResponse as DeploymentRetrieveResponse +from .deployment_preview_rpc_params import DeploymentPreviewRpcParams as DeploymentPreviewRpcParams diff --git a/src/agentex/types/agents/deployment_create_params.py b/src/agentex/types/agents/deployment_create_params.py new file mode 100644 index 000000000..b9f57c03c --- /dev/null +++ b/src/agentex/types/agents/deployment_create_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 Required, TypedDict + +__all__ = ["DeploymentCreateParams"] + + +class DeploymentCreateParams(TypedDict, total=False): + docker_image: Required[str] + """Full Docker image URI.""" + + helm_release_name: Optional[str] + """Helm release name.""" + + registration_metadata: Optional[Dict[str, object]] + """ + Git/build metadata (commit_hash, branch_name, author_name, author_email, + build_timestamp). + """ + + sgp_deploy_id: Optional[str] + """SGP deployment ID.""" diff --git a/src/agentex/types/agents/deployment_create_response.py b/src/agentex/types/agents/deployment_create_response.py new file mode 100644 index 000000000..a7d4007b9 --- /dev/null +++ b/src/agentex/types/agents/deployment_create_response.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["DeploymentCreateResponse"] + + +class DeploymentCreateResponse(BaseModel): + id: str + """The unique identifier of the deployment.""" + + agent_id: str + """The agent this deployment belongs to.""" + + docker_image: str + """Full Docker image URI.""" + + is_production: bool + """Whether this is the production deployment.""" + + status: Literal["Pending", "Ready", "Failed"] + """Current deployment status.""" + + acp_url: Optional[str] = None + """ACP URL set when agent registers.""" + + created_at: Optional[datetime] = None + """When the deployment was created.""" + + expires_at: Optional[datetime] = None + """When marked for cleanup.""" + + helm_release_name: Optional[str] = None + """Helm release name for cleanup.""" + + promoted_at: Optional[datetime] = None + """When promoted to production.""" + + registration_metadata: Optional[Dict[str, object]] = None + """Git/build metadata from the agent pod.""" + + sgp_deploy_id: Optional[str] = None + """Correlates to SGP's agentex_deploys.id.""" diff --git a/src/agentex/types/agents/deployment_list_params.py b/src/agentex/types/agents/deployment_list_params.py new file mode 100644 index 000000000..394905797 --- /dev/null +++ b/src/agentex/types/agents/deployment_list_params.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import TypedDict + +__all__ = ["DeploymentListParams"] + + +class DeploymentListParams(TypedDict, total=False): + limit: int + """Limit""" + + order_by: Optional[str] + """Field to order by""" + + order_direction: str + """Order direction (asc or desc)""" + + page_number: int + """Page number""" diff --git a/src/agentex/types/agents/deployment_list_response.py b/src/agentex/types/agents/deployment_list_response.py new file mode 100644 index 000000000..3e00fab2c --- /dev/null +++ b/src/agentex/types/agents/deployment_list_response.py @@ -0,0 +1,50 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional +from datetime import datetime +from typing_extensions import Literal, TypeAlias + +from ..._models import BaseModel + +__all__ = ["DeploymentListResponse", "DeploymentListResponseItem"] + + +class DeploymentListResponseItem(BaseModel): + id: str + """The unique identifier of the deployment.""" + + agent_id: str + """The agent this deployment belongs to.""" + + docker_image: str + """Full Docker image URI.""" + + is_production: bool + """Whether this is the production deployment.""" + + status: Literal["Pending", "Ready", "Failed"] + """Current deployment status.""" + + acp_url: Optional[str] = None + """ACP URL set when agent registers.""" + + created_at: Optional[datetime] = None + """When the deployment was created.""" + + expires_at: Optional[datetime] = None + """When marked for cleanup.""" + + helm_release_name: Optional[str] = None + """Helm release name for cleanup.""" + + promoted_at: Optional[datetime] = None + """When promoted to production.""" + + registration_metadata: Optional[Dict[str, object]] = None + """Git/build metadata from the agent pod.""" + + sgp_deploy_id: Optional[str] = None + """Correlates to SGP's agentex_deploys.id.""" + + +DeploymentListResponse: TypeAlias = List[DeploymentListResponseItem] diff --git a/src/agentex/types/agents/deployment_preview_rpc_params.py b/src/agentex/types/agents/deployment_preview_rpc_params.py new file mode 100644 index 000000000..61112956a --- /dev/null +++ b/src/agentex/types/agents/deployment_preview_rpc_params.py @@ -0,0 +1,86 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Union, Optional +from typing_extensions import Literal, Required, TypeAlias, TypedDict + +from ..task_message_content_param import TaskMessageContentParam + +__all__ = [ + "DeploymentPreviewRpcParams", + "Params", + "ParamsCreateTaskRequest", + "ParamsCancelTaskRequest", + "ParamsSendMessageRequest", + "ParamsSendEventRequest", +] + + +class DeploymentPreviewRpcParams(TypedDict, total=False): + agent_id: Required[str] + + method: Required[Literal["event/send", "task/create", "message/send", "task/cancel"]] + + params: Required[Params] + """The parameters for the agent RPC request""" + + id: Union[int, str, None] + + jsonrpc: Literal["2.0"] + + +class ParamsCreateTaskRequest(TypedDict, total=False): + name: Optional[str] + """The name of the task to create""" + + params: Optional[Dict[str, object]] + """The parameters for the task""" + + task_metadata: Optional[Dict[str, object]] + """Caller-provided metadata to persist on the task row. + + Only applied at task creation; ignored if a task with this name already exists. + Forwarded to the agent inside the ACP payload for backward compatibility. + """ + + +class ParamsCancelTaskRequest(TypedDict, total=False): + task_id: Optional[str] + """The ID of the task to cancel. Either this or task_name must be provided.""" + + task_name: Optional[str] + """The name of the task to cancel. Either this or task_id must be provided.""" + + +class ParamsSendMessageRequest(TypedDict, total=False): + content: Required[TaskMessageContentParam] + """The message that was sent to the agent""" + + stream: bool + """Whether to stream the response message back to the client""" + + task_id: Optional[str] + """The ID of the task that the message was sent to""" + + task_name: Optional[str] + """The name of the task that the message was sent to""" + + task_params: Optional[Dict[str, object]] + """The parameters for the task (only used when creating new tasks)""" + + +class ParamsSendEventRequest(TypedDict, total=False): + content: Optional[TaskMessageContentParam] + """The content to send to the event""" + + task_id: Optional[str] + """The ID of the task that the event was sent to""" + + task_name: Optional[str] + """The name of the task that the event was sent to""" + + +Params: TypeAlias = Union[ + ParamsCreateTaskRequest, ParamsCancelTaskRequest, ParamsSendMessageRequest, ParamsSendEventRequest +] diff --git a/src/agentex/types/agents/deployment_promote_response.py b/src/agentex/types/agents/deployment_promote_response.py new file mode 100644 index 000000000..94f9fb62d --- /dev/null +++ b/src/agentex/types/agents/deployment_promote_response.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["DeploymentPromoteResponse"] + + +class DeploymentPromoteResponse(BaseModel): + id: str + """The unique identifier of the deployment.""" + + agent_id: str + """The agent this deployment belongs to.""" + + docker_image: str + """Full Docker image URI.""" + + is_production: bool + """Whether this is the production deployment.""" + + status: Literal["Pending", "Ready", "Failed"] + """Current deployment status.""" + + acp_url: Optional[str] = None + """ACP URL set when agent registers.""" + + created_at: Optional[datetime] = None + """When the deployment was created.""" + + expires_at: Optional[datetime] = None + """When marked for cleanup.""" + + helm_release_name: Optional[str] = None + """Helm release name for cleanup.""" + + promoted_at: Optional[datetime] = None + """When promoted to production.""" + + registration_metadata: Optional[Dict[str, object]] = None + """Git/build metadata from the agent pod.""" + + sgp_deploy_id: Optional[str] = None + """Correlates to SGP's agentex_deploys.id.""" diff --git a/src/agentex/types/agents/deployment_retrieve_response.py b/src/agentex/types/agents/deployment_retrieve_response.py new file mode 100644 index 000000000..cd90f3a2a --- /dev/null +++ b/src/agentex/types/agents/deployment_retrieve_response.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["DeploymentRetrieveResponse"] + + +class DeploymentRetrieveResponse(BaseModel): + id: str + """The unique identifier of the deployment.""" + + agent_id: str + """The agent this deployment belongs to.""" + + docker_image: str + """Full Docker image URI.""" + + is_production: bool + """Whether this is the production deployment.""" + + status: Literal["Pending", "Ready", "Failed"] + """Current deployment status.""" + + acp_url: Optional[str] = None + """ACP URL set when agent registers.""" + + created_at: Optional[datetime] = None + """When the deployment was created.""" + + expires_at: Optional[datetime] = None + """When marked for cleanup.""" + + helm_release_name: Optional[str] = None + """Helm release name for cleanup.""" + + promoted_at: Optional[datetime] = None + """When promoted to production.""" + + registration_metadata: Optional[Dict[str, object]] = None + """Git/build metadata from the agent pod.""" + + sgp_deploy_id: Optional[str] = None + """Correlates to SGP's agentex_deploys.id.""" diff --git a/src/agentex/types/agents/schedule_create_params.py b/src/agentex/types/agents/schedule_create_params.py new file mode 100644 index 000000000..bfb2e0013 --- /dev/null +++ b/src/agentex/types/agents/schedule_create_params.py @@ -0,0 +1,46 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Union, Optional +from datetime import datetime +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["ScheduleCreateParams"] + + +class ScheduleCreateParams(TypedDict, total=False): + name: Required[str] + """Human-readable name for the schedule (e.g., 'weekly-profiling'). + + Will be combined with agent_id to form the full schedule_id. + """ + + task_queue: Required[str] + """Temporal task queue where the agent's worker is listening""" + + workflow_name: Required[str] + """Name of the Temporal workflow to execute (e.g., 'sae-orchestrator')""" + + cron_expression: Optional[str] + """Cron expression for scheduling (e.g., '0 0 \\** \\** 0' for weekly on Sunday)""" + + end_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """When the schedule should stop being active""" + + execution_timeout_seconds: Optional[int] + """Maximum time in seconds for each workflow execution""" + + interval_seconds: Optional[int] + """Alternative to cron - run every N seconds""" + + paused: bool + """Whether to create the schedule in a paused state""" + + start_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """When the schedule should start being active""" + + workflow_params: Optional[Dict[str, object]] + """Parameters to pass to the workflow""" diff --git a/src/agentex/types/agents/schedule_create_response.py b/src/agentex/types/agents/schedule_create_response.py new file mode 100644 index 000000000..7f717d7a5 --- /dev/null +++ b/src/agentex/types/agents/schedule_create_response.py @@ -0,0 +1,78 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["ScheduleCreateResponse", "Action", "Spec"] + + +class Action(BaseModel): + """Information about the scheduled action""" + + task_queue: str + """Task queue for the workflow""" + + workflow_id_prefix: str + """Prefix for workflow execution IDs""" + + workflow_name: str + """Name of the workflow being executed""" + + workflow_params: Optional[List[object]] = None + """Parameters passed to the workflow""" + + +class Spec(BaseModel): + """Schedule specification""" + + cron_expressions: Optional[List[str]] = None + """Cron expressions for the schedule""" + + end_at: Optional[datetime] = None + """When the schedule stops being active""" + + intervals_seconds: Optional[List[int]] = None + """Interval specifications in seconds""" + + start_at: Optional[datetime] = None + """When the schedule starts being active""" + + +class ScheduleCreateResponse(BaseModel): + """Response model for schedule operations""" + + action: Action + """Information about the scheduled action""" + + agent_id: str + """ID of the agent this schedule belongs to""" + + name: str + """Human-readable name for the schedule""" + + schedule_id: str + """Unique identifier for the schedule""" + + spec: Spec + """Schedule specification""" + + state: Literal["ACTIVE", "PAUSED"] + """Current state of the schedule""" + + created_at: Optional[datetime] = None + """When the schedule was created""" + + last_action_time: Optional[datetime] = None + """When the schedule last executed""" + + next_action_times: Optional[List[datetime]] = None + """Upcoming scheduled execution times""" + + num_actions_missed: Optional[int] = None + """Number of scheduled executions that were missed""" + + num_actions_taken: Optional[int] = None + """Number of times the schedule has executed""" diff --git a/src/agentex/types/agents/schedule_list_params.py b/src/agentex/types/agents/schedule_list_params.py new file mode 100644 index 000000000..210f8f557 --- /dev/null +++ b/src/agentex/types/agents/schedule_list_params.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["ScheduleListParams"] + + +class ScheduleListParams(TypedDict, total=False): + page_size: int diff --git a/src/agentex/types/agents/schedule_list_response.py b/src/agentex/types/agents/schedule_list_response.py new file mode 100644 index 000000000..fe54e11f1 --- /dev/null +++ b/src/agentex/types/agents/schedule_list_response.py @@ -0,0 +1,41 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["ScheduleListResponse", "Schedule"] + + +class Schedule(BaseModel): + """Abbreviated schedule info for list responses""" + + agent_id: str + """ID of the agent this schedule belongs to""" + + name: str + """Human-readable name for the schedule""" + + schedule_id: str + """Unique identifier for the schedule""" + + state: Literal["ACTIVE", "PAUSED"] + """Current state of the schedule""" + + next_action_time: Optional[datetime] = None + """Next scheduled execution time""" + + workflow_name: Optional[str] = None + """Name of the scheduled workflow""" + + +class ScheduleListResponse(BaseModel): + """Response model for listing schedules""" + + schedules: List[Schedule] + """List of schedules""" + + total: int + """Total number of schedules""" diff --git a/src/agentex/types/agents/schedule_pause_params.py b/src/agentex/types/agents/schedule_pause_params.py new file mode 100644 index 000000000..9832a49e2 --- /dev/null +++ b/src/agentex/types/agents/schedule_pause_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, TypedDict + +__all__ = ["SchedulePauseParams"] + + +class SchedulePauseParams(TypedDict, total=False): + agent_id: Required[str] + + note: Optional[str] + """Optional note explaining why the schedule was paused""" diff --git a/src/agentex/types/agents/schedule_pause_response.py b/src/agentex/types/agents/schedule_pause_response.py new file mode 100644 index 000000000..2897fe810 --- /dev/null +++ b/src/agentex/types/agents/schedule_pause_response.py @@ -0,0 +1,78 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["SchedulePauseResponse", "Action", "Spec"] + + +class Action(BaseModel): + """Information about the scheduled action""" + + task_queue: str + """Task queue for the workflow""" + + workflow_id_prefix: str + """Prefix for workflow execution IDs""" + + workflow_name: str + """Name of the workflow being executed""" + + workflow_params: Optional[List[object]] = None + """Parameters passed to the workflow""" + + +class Spec(BaseModel): + """Schedule specification""" + + cron_expressions: Optional[List[str]] = None + """Cron expressions for the schedule""" + + end_at: Optional[datetime] = None + """When the schedule stops being active""" + + intervals_seconds: Optional[List[int]] = None + """Interval specifications in seconds""" + + start_at: Optional[datetime] = None + """When the schedule starts being active""" + + +class SchedulePauseResponse(BaseModel): + """Response model for schedule operations""" + + action: Action + """Information about the scheduled action""" + + agent_id: str + """ID of the agent this schedule belongs to""" + + name: str + """Human-readable name for the schedule""" + + schedule_id: str + """Unique identifier for the schedule""" + + spec: Spec + """Schedule specification""" + + state: Literal["ACTIVE", "PAUSED"] + """Current state of the schedule""" + + created_at: Optional[datetime] = None + """When the schedule was created""" + + last_action_time: Optional[datetime] = None + """When the schedule last executed""" + + next_action_times: Optional[List[datetime]] = None + """Upcoming scheduled execution times""" + + num_actions_missed: Optional[int] = None + """Number of scheduled executions that were missed""" + + num_actions_taken: Optional[int] = None + """Number of times the schedule has executed""" diff --git a/src/agentex/types/agents/schedule_retrieve_response.py b/src/agentex/types/agents/schedule_retrieve_response.py new file mode 100644 index 000000000..e3a840a63 --- /dev/null +++ b/src/agentex/types/agents/schedule_retrieve_response.py @@ -0,0 +1,78 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["ScheduleRetrieveResponse", "Action", "Spec"] + + +class Action(BaseModel): + """Information about the scheduled action""" + + task_queue: str + """Task queue for the workflow""" + + workflow_id_prefix: str + """Prefix for workflow execution IDs""" + + workflow_name: str + """Name of the workflow being executed""" + + workflow_params: Optional[List[object]] = None + """Parameters passed to the workflow""" + + +class Spec(BaseModel): + """Schedule specification""" + + cron_expressions: Optional[List[str]] = None + """Cron expressions for the schedule""" + + end_at: Optional[datetime] = None + """When the schedule stops being active""" + + intervals_seconds: Optional[List[int]] = None + """Interval specifications in seconds""" + + start_at: Optional[datetime] = None + """When the schedule starts being active""" + + +class ScheduleRetrieveResponse(BaseModel): + """Response model for schedule operations""" + + action: Action + """Information about the scheduled action""" + + agent_id: str + """ID of the agent this schedule belongs to""" + + name: str + """Human-readable name for the schedule""" + + schedule_id: str + """Unique identifier for the schedule""" + + spec: Spec + """Schedule specification""" + + state: Literal["ACTIVE", "PAUSED"] + """Current state of the schedule""" + + created_at: Optional[datetime] = None + """When the schedule was created""" + + last_action_time: Optional[datetime] = None + """When the schedule last executed""" + + next_action_times: Optional[List[datetime]] = None + """Upcoming scheduled execution times""" + + num_actions_missed: Optional[int] = None + """Number of scheduled executions that were missed""" + + num_actions_taken: Optional[int] = None + """Number of times the schedule has executed""" diff --git a/src/agentex/types/agents/schedule_trigger_response.py b/src/agentex/types/agents/schedule_trigger_response.py new file mode 100644 index 000000000..ab65d1789 --- /dev/null +++ b/src/agentex/types/agents/schedule_trigger_response.py @@ -0,0 +1,78 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["ScheduleTriggerResponse", "Action", "Spec"] + + +class Action(BaseModel): + """Information about the scheduled action""" + + task_queue: str + """Task queue for the workflow""" + + workflow_id_prefix: str + """Prefix for workflow execution IDs""" + + workflow_name: str + """Name of the workflow being executed""" + + workflow_params: Optional[List[object]] = None + """Parameters passed to the workflow""" + + +class Spec(BaseModel): + """Schedule specification""" + + cron_expressions: Optional[List[str]] = None + """Cron expressions for the schedule""" + + end_at: Optional[datetime] = None + """When the schedule stops being active""" + + intervals_seconds: Optional[List[int]] = None + """Interval specifications in seconds""" + + start_at: Optional[datetime] = None + """When the schedule starts being active""" + + +class ScheduleTriggerResponse(BaseModel): + """Response model for schedule operations""" + + action: Action + """Information about the scheduled action""" + + agent_id: str + """ID of the agent this schedule belongs to""" + + name: str + """Human-readable name for the schedule""" + + schedule_id: str + """Unique identifier for the schedule""" + + spec: Spec + """Schedule specification""" + + state: Literal["ACTIVE", "PAUSED"] + """Current state of the schedule""" + + created_at: Optional[datetime] = None + """When the schedule was created""" + + last_action_time: Optional[datetime] = None + """When the schedule last executed""" + + next_action_times: Optional[List[datetime]] = None + """Upcoming scheduled execution times""" + + num_actions_missed: Optional[int] = None + """Number of scheduled executions that were missed""" + + num_actions_taken: Optional[int] = None + """Number of times the schedule has executed""" diff --git a/src/agentex/types/agents/schedule_unpause_params.py b/src/agentex/types/agents/schedule_unpause_params.py new file mode 100644 index 000000000..fa6341b96 --- /dev/null +++ b/src/agentex/types/agents/schedule_unpause_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, TypedDict + +__all__ = ["ScheduleUnpauseParams"] + + +class ScheduleUnpauseParams(TypedDict, total=False): + agent_id: Required[str] + + note: Optional[str] + """Optional note explaining why the schedule was unpaused""" diff --git a/src/agentex/types/agents/schedule_unpause_response.py b/src/agentex/types/agents/schedule_unpause_response.py new file mode 100644 index 000000000..188567a20 --- /dev/null +++ b/src/agentex/types/agents/schedule_unpause_response.py @@ -0,0 +1,78 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["ScheduleUnpauseResponse", "Action", "Spec"] + + +class Action(BaseModel): + """Information about the scheduled action""" + + task_queue: str + """Task queue for the workflow""" + + workflow_id_prefix: str + """Prefix for workflow execution IDs""" + + workflow_name: str + """Name of the workflow being executed""" + + workflow_params: Optional[List[object]] = None + """Parameters passed to the workflow""" + + +class Spec(BaseModel): + """Schedule specification""" + + cron_expressions: Optional[List[str]] = None + """Cron expressions for the schedule""" + + end_at: Optional[datetime] = None + """When the schedule stops being active""" + + intervals_seconds: Optional[List[int]] = None + """Interval specifications in seconds""" + + start_at: Optional[datetime] = None + """When the schedule starts being active""" + + +class ScheduleUnpauseResponse(BaseModel): + """Response model for schedule operations""" + + action: Action + """Information about the scheduled action""" + + agent_id: str + """ID of the agent this schedule belongs to""" + + name: str + """Human-readable name for the schedule""" + + schedule_id: str + """Unique identifier for the schedule""" + + spec: Spec + """Schedule specification""" + + state: Literal["ACTIVE", "PAUSED"] + """Current state of the schedule""" + + created_at: Optional[datetime] = None + """When the schedule was created""" + + last_action_time: Optional[datetime] = None + """When the schedule last executed""" + + next_action_times: Optional[List[datetime]] = None + """Upcoming scheduled execution times""" + + num_actions_missed: Optional[int] = None + """Number of scheduled executions that were missed""" + + num_actions_taken: Optional[int] = None + """Number of times the schedule has executed""" diff --git a/src/agentex/types/checkpoint_delete_thread_params.py b/src/agentex/types/checkpoint_delete_thread_params.py new file mode 100644 index 000000000..b0e3305ab --- /dev/null +++ b/src/agentex/types/checkpoint_delete_thread_params.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["CheckpointDeleteThreadParams"] + + +class CheckpointDeleteThreadParams(TypedDict, total=False): + thread_id: Required[str] diff --git a/src/agentex/types/checkpoint_get_tuple_params.py b/src/agentex/types/checkpoint_get_tuple_params.py new file mode 100644 index 000000000..947ef072d --- /dev/null +++ b/src/agentex/types/checkpoint_get_tuple_params.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, TypedDict + +__all__ = ["CheckpointGetTupleParams"] + + +class CheckpointGetTupleParams(TypedDict, total=False): + thread_id: Required[str] + + checkpoint_id: Optional[str] + + checkpoint_ns: str diff --git a/src/agentex/types/checkpoint_get_tuple_response.py b/src/agentex/types/checkpoint_get_tuple_response.py new file mode 100644 index 000000000..dab859d0d --- /dev/null +++ b/src/agentex/types/checkpoint_get_tuple_response.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional + +from .._models import BaseModel + +__all__ = ["CheckpointGetTupleResponse", "Blob", "PendingWrite"] + + +class Blob(BaseModel): + channel: str + + type: str + + version: str + + blob: Optional[str] = None + + +class PendingWrite(BaseModel): + channel: str + + idx: int + + task_id: str + + blob: Optional[str] = None + + type: Optional[str] = None + + +class CheckpointGetTupleResponse(BaseModel): + checkpoint: Dict[str, object] + + checkpoint_id: str + + checkpoint_ns: str + + metadata: Dict[str, object] + + thread_id: str + + blobs: Optional[List[Blob]] = None + + parent_checkpoint_id: Optional[str] = None + + pending_writes: Optional[List[PendingWrite]] = None diff --git a/src/agentex/types/checkpoint_list_params.py b/src/agentex/types/checkpoint_list_params.py new file mode 100644 index 000000000..20a21d6ac --- /dev/null +++ b/src/agentex/types/checkpoint_list_params.py @@ -0,0 +1,20 @@ +# 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 Required, TypedDict + +__all__ = ["CheckpointListParams"] + + +class CheckpointListParams(TypedDict, total=False): + thread_id: Required[str] + + before_checkpoint_id: Optional[str] + + checkpoint_ns: Optional[str] + + filter_metadata: Optional[Dict[str, object]] + + limit: int diff --git a/src/agentex/types/checkpoint_list_response.py b/src/agentex/types/checkpoint_list_response.py new file mode 100644 index 000000000..dce4bd9a1 --- /dev/null +++ b/src/agentex/types/checkpoint_list_response.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional +from typing_extensions import TypeAlias + +from .._models import BaseModel + +__all__ = ["CheckpointListResponse", "CheckpointListResponseItem"] + + +class CheckpointListResponseItem(BaseModel): + checkpoint: Dict[str, object] + + checkpoint_id: str + + checkpoint_ns: str + + metadata: Dict[str, object] + + thread_id: str + + parent_checkpoint_id: Optional[str] = None + + +CheckpointListResponse: TypeAlias = List[CheckpointListResponseItem] diff --git a/src/agentex/types/checkpoint_put_params.py b/src/agentex/types/checkpoint_put_params.py new file mode 100644 index 000000000..5e692961a --- /dev/null +++ b/src/agentex/types/checkpoint_put_params.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Iterable, Optional +from typing_extensions import Required, TypedDict + +__all__ = ["CheckpointPutParams", "Blob"] + + +class CheckpointPutParams(TypedDict, total=False): + checkpoint: Required[Dict[str, object]] + + checkpoint_id: Required[str] + + thread_id: Required[str] + + blobs: Iterable[Blob] + + checkpoint_ns: str + + metadata: Dict[str, object] + + parent_checkpoint_id: Optional[str] + + +class Blob(TypedDict, total=False): + channel: Required[str] + + type: Required[str] + + version: Required[str] + + blob: Optional[str] diff --git a/src/agentex/types/checkpoint_put_response.py b/src/agentex/types/checkpoint_put_response.py new file mode 100644 index 000000000..90afe9ce5 --- /dev/null +++ b/src/agentex/types/checkpoint_put_response.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .._models import BaseModel + +__all__ = ["CheckpointPutResponse"] + + +class CheckpointPutResponse(BaseModel): + checkpoint_id: str + + checkpoint_ns: str + + thread_id: str diff --git a/src/agentex/types/checkpoint_put_writes_params.py b/src/agentex/types/checkpoint_put_writes_params.py new file mode 100644 index 000000000..adf8c7852 --- /dev/null +++ b/src/agentex/types/checkpoint_put_writes_params.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable, Optional +from typing_extensions import Required, TypedDict + +__all__ = ["CheckpointPutWritesParams", "Write"] + + +class CheckpointPutWritesParams(TypedDict, total=False): + checkpoint_id: Required[str] + + thread_id: Required[str] + + writes: Required[Iterable[Write]] + + checkpoint_ns: str + + upsert: bool + + +class Write(TypedDict, total=False): + blob: Required[str] + + channel: Required[str] + + idx: Required[int] + + task_id: Required[str] + + task_path: str + + type: Optional[str] diff --git a/tests/api_resources/agents/__init__.py b/tests/api_resources/agents/__init__.py new file mode 100644 index 000000000..fd8019a9a --- /dev/null +++ b/tests/api_resources/agents/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/agents/test_deployments.py b/tests/api_resources/agents/test_deployments.py new file mode 100644 index 000000000..7bddf7c49 --- /dev/null +++ b/tests/api_resources/agents/test_deployments.py @@ -0,0 +1,726 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from agentex import Agentex, AsyncAgentex +from agentex.types import AgentRpcResponse +from agentex.types.agents import ( + DeploymentListResponse, + DeploymentCreateResponse, + DeploymentPromoteResponse, + DeploymentRetrieveResponse, +) +from agentex.types.shared import DeleteResponse + +from ...utils import assert_matches_type + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestDeployments: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Agentex) -> None: + deployment = client.agents.deployments.create( + agent_id="agent_id", + docker_image="docker_image", + ) + assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: Agentex) -> None: + deployment = client.agents.deployments.create( + agent_id="agent_id", + docker_image="docker_image", + helm_release_name="helm_release_name", + registration_metadata={"foo": "bar"}, + sgp_deploy_id="sgp_deploy_id", + ) + assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Agentex) -> None: + response = client.agents.deployments.with_raw_response.create( + agent_id="agent_id", + docker_image="docker_image", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Agentex) -> None: + with client.agents.deployments.with_streaming_response.create( + agent_id="agent_id", + docker_image="docker_image", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_create(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.deployments.with_raw_response.create( + agent_id="", + docker_image="docker_image", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Agentex) -> None: + deployment = client.agents.deployments.retrieve( + deployment_id="deployment_id", + agent_id="agent_id", + ) + assert_matches_type(DeploymentRetrieveResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Agentex) -> None: + response = client.agents.deployments.with_raw_response.retrieve( + deployment_id="deployment_id", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(DeploymentRetrieveResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Agentex) -> None: + with client.agents.deployments.with_streaming_response.retrieve( + deployment_id="deployment_id", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(DeploymentRetrieveResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.deployments.with_raw_response.retrieve( + deployment_id="deployment_id", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + client.agents.deployments.with_raw_response.retrieve( + deployment_id="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Agentex) -> None: + deployment = client.agents.deployments.list( + agent_id="agent_id", + ) + assert_matches_type(DeploymentListResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Agentex) -> None: + deployment = client.agents.deployments.list( + agent_id="agent_id", + limit=1, + order_by="order_by", + order_direction="order_direction", + page_number=1, + ) + assert_matches_type(DeploymentListResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Agentex) -> None: + response = client.agents.deployments.with_raw_response.list( + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(DeploymentListResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Agentex) -> None: + with client.agents.deployments.with_streaming_response.list( + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(DeploymentListResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_list(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.deployments.with_raw_response.list( + agent_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Agentex) -> None: + deployment = client.agents.deployments.delete( + deployment_id="deployment_id", + agent_id="agent_id", + ) + assert_matches_type(DeleteResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Agentex) -> None: + response = client.agents.deployments.with_raw_response.delete( + deployment_id="deployment_id", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(DeleteResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Agentex) -> None: + with client.agents.deployments.with_streaming_response.delete( + deployment_id="deployment_id", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(DeleteResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.deployments.with_raw_response.delete( + deployment_id="deployment_id", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + client.agents.deployments.with_raw_response.delete( + deployment_id="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_preview_rpc(self, client: Agentex) -> None: + deployment = client.agents.deployments.preview_rpc( + deployment_id="deployment_id", + agent_id="agent_id", + method="event/send", + params={}, + ) + assert_matches_type(AgentRpcResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_preview_rpc_with_all_params(self, client: Agentex) -> None: + deployment = client.agents.deployments.preview_rpc( + deployment_id="deployment_id", + agent_id="agent_id", + method="event/send", + params={ + "name": "name", + "params": {"foo": "bar"}, + "task_metadata": {"foo": "bar"}, + }, + id=0, + jsonrpc="2.0", + ) + assert_matches_type(AgentRpcResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_preview_rpc(self, client: Agentex) -> None: + response = client.agents.deployments.with_raw_response.preview_rpc( + deployment_id="deployment_id", + agent_id="agent_id", + method="event/send", + params={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(AgentRpcResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_preview_rpc(self, client: Agentex) -> None: + with client.agents.deployments.with_streaming_response.preview_rpc( + deployment_id="deployment_id", + agent_id="agent_id", + method="event/send", + params={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(AgentRpcResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_preview_rpc(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.deployments.with_raw_response.preview_rpc( + deployment_id="deployment_id", + agent_id="", + method="event/send", + params={}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + client.agents.deployments.with_raw_response.preview_rpc( + deployment_id="", + agent_id="agent_id", + method="event/send", + params={}, + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_promote(self, client: Agentex) -> None: + deployment = client.agents.deployments.promote( + deployment_id="deployment_id", + agent_id="agent_id", + ) + assert_matches_type(DeploymentPromoteResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_promote(self, client: Agentex) -> None: + response = client.agents.deployments.with_raw_response.promote( + deployment_id="deployment_id", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(DeploymentPromoteResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_promote(self, client: Agentex) -> None: + with client.agents.deployments.with_streaming_response.promote( + deployment_id="deployment_id", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(DeploymentPromoteResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_promote(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.deployments.with_raw_response.promote( + deployment_id="deployment_id", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + client.agents.deployments.with_raw_response.promote( + deployment_id="", + agent_id="agent_id", + ) + + +class TestAsyncDeployments: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncAgentex) -> None: + deployment = await async_client.agents.deployments.create( + agent_id="agent_id", + docker_image="docker_image", + ) + assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncAgentex) -> None: + deployment = await async_client.agents.deployments.create( + agent_id="agent_id", + docker_image="docker_image", + helm_release_name="helm_release_name", + registration_metadata={"foo": "bar"}, + sgp_deploy_id="sgp_deploy_id", + ) + assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.deployments.with_raw_response.create( + agent_id="agent_id", + docker_image="docker_image", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.deployments.with_streaming_response.create( + agent_id="agent_id", + docker_image="docker_image", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_create(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.deployments.with_raw_response.create( + agent_id="", + docker_image="docker_image", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncAgentex) -> None: + deployment = await async_client.agents.deployments.retrieve( + deployment_id="deployment_id", + agent_id="agent_id", + ) + assert_matches_type(DeploymentRetrieveResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.deployments.with_raw_response.retrieve( + deployment_id="deployment_id", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(DeploymentRetrieveResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.deployments.with_streaming_response.retrieve( + deployment_id="deployment_id", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(DeploymentRetrieveResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.deployments.with_raw_response.retrieve( + deployment_id="deployment_id", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + await async_client.agents.deployments.with_raw_response.retrieve( + deployment_id="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncAgentex) -> None: + deployment = await async_client.agents.deployments.list( + agent_id="agent_id", + ) + assert_matches_type(DeploymentListResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncAgentex) -> None: + deployment = await async_client.agents.deployments.list( + agent_id="agent_id", + limit=1, + order_by="order_by", + order_direction="order_direction", + page_number=1, + ) + assert_matches_type(DeploymentListResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.deployments.with_raw_response.list( + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(DeploymentListResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.deployments.with_streaming_response.list( + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(DeploymentListResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_list(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.deployments.with_raw_response.list( + agent_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncAgentex) -> None: + deployment = await async_client.agents.deployments.delete( + deployment_id="deployment_id", + agent_id="agent_id", + ) + assert_matches_type(DeleteResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.deployments.with_raw_response.delete( + deployment_id="deployment_id", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(DeleteResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.deployments.with_streaming_response.delete( + deployment_id="deployment_id", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(DeleteResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.deployments.with_raw_response.delete( + deployment_id="deployment_id", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + await async_client.agents.deployments.with_raw_response.delete( + deployment_id="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_preview_rpc(self, async_client: AsyncAgentex) -> None: + deployment = await async_client.agents.deployments.preview_rpc( + deployment_id="deployment_id", + agent_id="agent_id", + method="event/send", + params={}, + ) + assert_matches_type(AgentRpcResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_preview_rpc_with_all_params(self, async_client: AsyncAgentex) -> None: + deployment = await async_client.agents.deployments.preview_rpc( + deployment_id="deployment_id", + agent_id="agent_id", + method="event/send", + params={ + "name": "name", + "params": {"foo": "bar"}, + "task_metadata": {"foo": "bar"}, + }, + id=0, + jsonrpc="2.0", + ) + assert_matches_type(AgentRpcResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_preview_rpc(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.deployments.with_raw_response.preview_rpc( + deployment_id="deployment_id", + agent_id="agent_id", + method="event/send", + params={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(AgentRpcResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_preview_rpc(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.deployments.with_streaming_response.preview_rpc( + deployment_id="deployment_id", + agent_id="agent_id", + method="event/send", + params={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(AgentRpcResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_preview_rpc(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.deployments.with_raw_response.preview_rpc( + deployment_id="deployment_id", + agent_id="", + method="event/send", + params={}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + await async_client.agents.deployments.with_raw_response.preview_rpc( + deployment_id="", + agent_id="agent_id", + method="event/send", + params={}, + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_promote(self, async_client: AsyncAgentex) -> None: + deployment = await async_client.agents.deployments.promote( + deployment_id="deployment_id", + agent_id="agent_id", + ) + assert_matches_type(DeploymentPromoteResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_promote(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.deployments.with_raw_response.promote( + deployment_id="deployment_id", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(DeploymentPromoteResponse, deployment, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_promote(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.deployments.with_streaming_response.promote( + deployment_id="deployment_id", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(DeploymentPromoteResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_promote(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.deployments.with_raw_response.promote( + deployment_id="deployment_id", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + await async_client.agents.deployments.with_raw_response.promote( + deployment_id="", + agent_id="agent_id", + ) diff --git a/tests/api_resources/agents/test_schedules.py b/tests/api_resources/agents/test_schedules.py new file mode 100644 index 000000000..0431de18e --- /dev/null +++ b/tests/api_resources/agents/test_schedules.py @@ -0,0 +1,840 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from agentex import Agentex, AsyncAgentex +from agentex._utils import parse_datetime +from agentex.types.agents import ( + ScheduleListResponse, + SchedulePauseResponse, + ScheduleCreateResponse, + ScheduleTriggerResponse, + ScheduleUnpauseResponse, + ScheduleRetrieveResponse, +) +from agentex.types.shared import DeleteResponse + +from ...utils import assert_matches_type + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestSchedules: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Agentex) -> None: + schedule = client.agents.schedules.create( + agent_id="agent_id", + name="name", + task_queue="task_queue", + workflow_name="workflow_name", + ) + assert_matches_type(ScheduleCreateResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: Agentex) -> None: + schedule = client.agents.schedules.create( + agent_id="agent_id", + name="name", + task_queue="task_queue", + workflow_name="workflow_name", + cron_expression="cron_expression", + end_at=parse_datetime("2019-12-27T18:11:19.117Z"), + execution_timeout_seconds=1, + interval_seconds=1, + paused=True, + start_at=parse_datetime("2019-12-27T18:11:19.117Z"), + workflow_params={"foo": "bar"}, + ) + assert_matches_type(ScheduleCreateResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Agentex) -> None: + response = client.agents.schedules.with_raw_response.create( + agent_id="agent_id", + name="name", + task_queue="task_queue", + workflow_name="workflow_name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = response.parse() + assert_matches_type(ScheduleCreateResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Agentex) -> None: + with client.agents.schedules.with_streaming_response.create( + agent_id="agent_id", + name="name", + task_queue="task_queue", + workflow_name="workflow_name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = response.parse() + assert_matches_type(ScheduleCreateResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_create(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.schedules.with_raw_response.create( + agent_id="", + name="name", + task_queue="task_queue", + workflow_name="workflow_name", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Agentex) -> None: + schedule = client.agents.schedules.retrieve( + schedule_name="schedule_name", + agent_id="agent_id", + ) + assert_matches_type(ScheduleRetrieveResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Agentex) -> None: + response = client.agents.schedules.with_raw_response.retrieve( + schedule_name="schedule_name", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = response.parse() + assert_matches_type(ScheduleRetrieveResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Agentex) -> None: + with client.agents.schedules.with_streaming_response.retrieve( + schedule_name="schedule_name", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = response.parse() + assert_matches_type(ScheduleRetrieveResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.schedules.with_raw_response.retrieve( + schedule_name="schedule_name", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `schedule_name` but received ''"): + client.agents.schedules.with_raw_response.retrieve( + schedule_name="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Agentex) -> None: + schedule = client.agents.schedules.list( + agent_id="agent_id", + ) + assert_matches_type(ScheduleListResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Agentex) -> None: + schedule = client.agents.schedules.list( + agent_id="agent_id", + page_size=1, + ) + assert_matches_type(ScheduleListResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Agentex) -> None: + response = client.agents.schedules.with_raw_response.list( + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = response.parse() + assert_matches_type(ScheduleListResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Agentex) -> None: + with client.agents.schedules.with_streaming_response.list( + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = response.parse() + assert_matches_type(ScheduleListResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_list(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.schedules.with_raw_response.list( + agent_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Agentex) -> None: + schedule = client.agents.schedules.delete( + schedule_name="schedule_name", + agent_id="agent_id", + ) + assert_matches_type(DeleteResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Agentex) -> None: + response = client.agents.schedules.with_raw_response.delete( + schedule_name="schedule_name", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = response.parse() + assert_matches_type(DeleteResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Agentex) -> None: + with client.agents.schedules.with_streaming_response.delete( + schedule_name="schedule_name", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = response.parse() + assert_matches_type(DeleteResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.schedules.with_raw_response.delete( + schedule_name="schedule_name", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `schedule_name` but received ''"): + client.agents.schedules.with_raw_response.delete( + schedule_name="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_pause(self, client: Agentex) -> None: + schedule = client.agents.schedules.pause( + schedule_name="schedule_name", + agent_id="agent_id", + ) + assert_matches_type(SchedulePauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_pause_with_all_params(self, client: Agentex) -> None: + schedule = client.agents.schedules.pause( + schedule_name="schedule_name", + agent_id="agent_id", + note="note", + ) + assert_matches_type(SchedulePauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_pause(self, client: Agentex) -> None: + response = client.agents.schedules.with_raw_response.pause( + schedule_name="schedule_name", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = response.parse() + assert_matches_type(SchedulePauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_pause(self, client: Agentex) -> None: + with client.agents.schedules.with_streaming_response.pause( + schedule_name="schedule_name", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = response.parse() + assert_matches_type(SchedulePauseResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_pause(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.schedules.with_raw_response.pause( + schedule_name="schedule_name", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `schedule_name` but received ''"): + client.agents.schedules.with_raw_response.pause( + schedule_name="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_trigger(self, client: Agentex) -> None: + schedule = client.agents.schedules.trigger( + schedule_name="schedule_name", + agent_id="agent_id", + ) + assert_matches_type(ScheduleTriggerResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_trigger(self, client: Agentex) -> None: + response = client.agents.schedules.with_raw_response.trigger( + schedule_name="schedule_name", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = response.parse() + assert_matches_type(ScheduleTriggerResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_trigger(self, client: Agentex) -> None: + with client.agents.schedules.with_streaming_response.trigger( + schedule_name="schedule_name", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = response.parse() + assert_matches_type(ScheduleTriggerResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_trigger(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.schedules.with_raw_response.trigger( + schedule_name="schedule_name", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `schedule_name` but received ''"): + client.agents.schedules.with_raw_response.trigger( + schedule_name="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_unpause(self, client: Agentex) -> None: + schedule = client.agents.schedules.unpause( + schedule_name="schedule_name", + agent_id="agent_id", + ) + assert_matches_type(ScheduleUnpauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_unpause_with_all_params(self, client: Agentex) -> None: + schedule = client.agents.schedules.unpause( + schedule_name="schedule_name", + agent_id="agent_id", + note="note", + ) + assert_matches_type(ScheduleUnpauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_unpause(self, client: Agentex) -> None: + response = client.agents.schedules.with_raw_response.unpause( + schedule_name="schedule_name", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = response.parse() + assert_matches_type(ScheduleUnpauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_unpause(self, client: Agentex) -> None: + with client.agents.schedules.with_streaming_response.unpause( + schedule_name="schedule_name", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = response.parse() + assert_matches_type(ScheduleUnpauseResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_unpause(self, client: Agentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + client.agents.schedules.with_raw_response.unpause( + schedule_name="schedule_name", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `schedule_name` but received ''"): + client.agents.schedules.with_raw_response.unpause( + schedule_name="", + agent_id="agent_id", + ) + + +class TestAsyncSchedules: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.create( + agent_id="agent_id", + name="name", + task_queue="task_queue", + workflow_name="workflow_name", + ) + assert_matches_type(ScheduleCreateResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.create( + agent_id="agent_id", + name="name", + task_queue="task_queue", + workflow_name="workflow_name", + cron_expression="cron_expression", + end_at=parse_datetime("2019-12-27T18:11:19.117Z"), + execution_timeout_seconds=1, + interval_seconds=1, + paused=True, + start_at=parse_datetime("2019-12-27T18:11:19.117Z"), + workflow_params={"foo": "bar"}, + ) + assert_matches_type(ScheduleCreateResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.schedules.with_raw_response.create( + agent_id="agent_id", + name="name", + task_queue="task_queue", + workflow_name="workflow_name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = await response.parse() + assert_matches_type(ScheduleCreateResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.schedules.with_streaming_response.create( + agent_id="agent_id", + name="name", + task_queue="task_queue", + workflow_name="workflow_name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = await response.parse() + assert_matches_type(ScheduleCreateResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_create(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.schedules.with_raw_response.create( + agent_id="", + name="name", + task_queue="task_queue", + workflow_name="workflow_name", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.retrieve( + schedule_name="schedule_name", + agent_id="agent_id", + ) + assert_matches_type(ScheduleRetrieveResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.schedules.with_raw_response.retrieve( + schedule_name="schedule_name", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = await response.parse() + assert_matches_type(ScheduleRetrieveResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.schedules.with_streaming_response.retrieve( + schedule_name="schedule_name", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = await response.parse() + assert_matches_type(ScheduleRetrieveResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.schedules.with_raw_response.retrieve( + schedule_name="schedule_name", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `schedule_name` but received ''"): + await async_client.agents.schedules.with_raw_response.retrieve( + schedule_name="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.list( + agent_id="agent_id", + ) + assert_matches_type(ScheduleListResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.list( + agent_id="agent_id", + page_size=1, + ) + assert_matches_type(ScheduleListResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.schedules.with_raw_response.list( + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = await response.parse() + assert_matches_type(ScheduleListResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.schedules.with_streaming_response.list( + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = await response.parse() + assert_matches_type(ScheduleListResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_list(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.schedules.with_raw_response.list( + agent_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.delete( + schedule_name="schedule_name", + agent_id="agent_id", + ) + assert_matches_type(DeleteResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.schedules.with_raw_response.delete( + schedule_name="schedule_name", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = await response.parse() + assert_matches_type(DeleteResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.schedules.with_streaming_response.delete( + schedule_name="schedule_name", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = await response.parse() + assert_matches_type(DeleteResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.schedules.with_raw_response.delete( + schedule_name="schedule_name", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `schedule_name` but received ''"): + await async_client.agents.schedules.with_raw_response.delete( + schedule_name="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_pause(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.pause( + schedule_name="schedule_name", + agent_id="agent_id", + ) + assert_matches_type(SchedulePauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_pause_with_all_params(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.pause( + schedule_name="schedule_name", + agent_id="agent_id", + note="note", + ) + assert_matches_type(SchedulePauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_pause(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.schedules.with_raw_response.pause( + schedule_name="schedule_name", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = await response.parse() + assert_matches_type(SchedulePauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_pause(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.schedules.with_streaming_response.pause( + schedule_name="schedule_name", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = await response.parse() + assert_matches_type(SchedulePauseResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_pause(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.schedules.with_raw_response.pause( + schedule_name="schedule_name", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `schedule_name` but received ''"): + await async_client.agents.schedules.with_raw_response.pause( + schedule_name="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_trigger(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.trigger( + schedule_name="schedule_name", + agent_id="agent_id", + ) + assert_matches_type(ScheduleTriggerResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_trigger(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.schedules.with_raw_response.trigger( + schedule_name="schedule_name", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = await response.parse() + assert_matches_type(ScheduleTriggerResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_trigger(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.schedules.with_streaming_response.trigger( + schedule_name="schedule_name", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = await response.parse() + assert_matches_type(ScheduleTriggerResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_trigger(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.schedules.with_raw_response.trigger( + schedule_name="schedule_name", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `schedule_name` but received ''"): + await async_client.agents.schedules.with_raw_response.trigger( + schedule_name="", + agent_id="agent_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_unpause(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.unpause( + schedule_name="schedule_name", + agent_id="agent_id", + ) + assert_matches_type(ScheduleUnpauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_unpause_with_all_params(self, async_client: AsyncAgentex) -> None: + schedule = await async_client.agents.schedules.unpause( + schedule_name="schedule_name", + agent_id="agent_id", + note="note", + ) + assert_matches_type(ScheduleUnpauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_unpause(self, async_client: AsyncAgentex) -> None: + response = await async_client.agents.schedules.with_raw_response.unpause( + schedule_name="schedule_name", + agent_id="agent_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + schedule = await response.parse() + assert_matches_type(ScheduleUnpauseResponse, schedule, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_unpause(self, async_client: AsyncAgentex) -> None: + async with async_client.agents.schedules.with_streaming_response.unpause( + schedule_name="schedule_name", + agent_id="agent_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + schedule = await response.parse() + assert_matches_type(ScheduleUnpauseResponse, schedule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_unpause(self, async_client: AsyncAgentex) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `agent_id` but received ''"): + await async_client.agents.schedules.with_raw_response.unpause( + schedule_name="schedule_name", + agent_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `schedule_name` but received ''"): + await async_client.agents.schedules.with_raw_response.unpause( + schedule_name="", + agent_id="agent_id", + ) diff --git a/tests/api_resources/test_checkpoints.py b/tests/api_resources/test_checkpoints.py new file mode 100644 index 000000000..3c13fd43a --- /dev/null +++ b/tests/api_resources/test_checkpoints.py @@ -0,0 +1,563 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from agentex import Agentex, AsyncAgentex +from agentex.types import ( + CheckpointPutResponse, + CheckpointListResponse, + CheckpointGetTupleResponse, +) + +from ..utils import assert_matches_type + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestCheckpoints: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Agentex) -> None: + checkpoint = client.checkpoints.list( + thread_id="thread_id", + ) + assert_matches_type(CheckpointListResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Agentex) -> None: + checkpoint = client.checkpoints.list( + thread_id="thread_id", + before_checkpoint_id="before_checkpoint_id", + checkpoint_ns="checkpoint_ns", + filter_metadata={"foo": "bar"}, + limit=1, + ) + assert_matches_type(CheckpointListResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Agentex) -> None: + response = client.checkpoints.with_raw_response.list( + thread_id="thread_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + checkpoint = response.parse() + assert_matches_type(CheckpointListResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Agentex) -> None: + with client.checkpoints.with_streaming_response.list( + thread_id="thread_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + checkpoint = response.parse() + assert_matches_type(CheckpointListResponse, checkpoint, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete_thread(self, client: Agentex) -> None: + checkpoint = client.checkpoints.delete_thread( + thread_id="thread_id", + ) + assert checkpoint is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete_thread(self, client: Agentex) -> None: + response = client.checkpoints.with_raw_response.delete_thread( + thread_id="thread_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + checkpoint = response.parse() + assert checkpoint is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete_thread(self, client: Agentex) -> None: + with client.checkpoints.with_streaming_response.delete_thread( + thread_id="thread_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + checkpoint = response.parse() + assert checkpoint is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_tuple(self, client: Agentex) -> None: + checkpoint = client.checkpoints.get_tuple( + thread_id="thread_id", + ) + assert_matches_type(Optional[CheckpointGetTupleResponse], checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_tuple_with_all_params(self, client: Agentex) -> None: + checkpoint = client.checkpoints.get_tuple( + thread_id="thread_id", + checkpoint_id="checkpoint_id", + checkpoint_ns="checkpoint_ns", + ) + assert_matches_type(Optional[CheckpointGetTupleResponse], checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_tuple(self, client: Agentex) -> None: + response = client.checkpoints.with_raw_response.get_tuple( + thread_id="thread_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + checkpoint = response.parse() + assert_matches_type(Optional[CheckpointGetTupleResponse], checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_tuple(self, client: Agentex) -> None: + with client.checkpoints.with_streaming_response.get_tuple( + thread_id="thread_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + checkpoint = response.parse() + assert_matches_type(Optional[CheckpointGetTupleResponse], checkpoint, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_put(self, client: Agentex) -> None: + checkpoint = client.checkpoints.put( + checkpoint={"foo": "bar"}, + checkpoint_id="checkpoint_id", + thread_id="thread_id", + ) + assert_matches_type(CheckpointPutResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_put_with_all_params(self, client: Agentex) -> None: + checkpoint = client.checkpoints.put( + checkpoint={"foo": "bar"}, + checkpoint_id="checkpoint_id", + thread_id="thread_id", + blobs=[ + { + "channel": "channel", + "type": "type", + "version": "version", + "blob": "blob", + } + ], + checkpoint_ns="checkpoint_ns", + metadata={"foo": "bar"}, + parent_checkpoint_id="parent_checkpoint_id", + ) + assert_matches_type(CheckpointPutResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_put(self, client: Agentex) -> None: + response = client.checkpoints.with_raw_response.put( + checkpoint={"foo": "bar"}, + checkpoint_id="checkpoint_id", + thread_id="thread_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + checkpoint = response.parse() + assert_matches_type(CheckpointPutResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_put(self, client: Agentex) -> None: + with client.checkpoints.with_streaming_response.put( + checkpoint={"foo": "bar"}, + checkpoint_id="checkpoint_id", + thread_id="thread_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + checkpoint = response.parse() + assert_matches_type(CheckpointPutResponse, checkpoint, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_put_writes(self, client: Agentex) -> None: + checkpoint = client.checkpoints.put_writes( + checkpoint_id="checkpoint_id", + thread_id="thread_id", + writes=[ + { + "blob": "blob", + "channel": "channel", + "idx": 0, + "task_id": "task_id", + } + ], + ) + assert checkpoint is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_put_writes_with_all_params(self, client: Agentex) -> None: + checkpoint = client.checkpoints.put_writes( + checkpoint_id="checkpoint_id", + thread_id="thread_id", + writes=[ + { + "blob": "blob", + "channel": "channel", + "idx": 0, + "task_id": "task_id", + "task_path": "task_path", + "type": "type", + } + ], + checkpoint_ns="checkpoint_ns", + upsert=True, + ) + assert checkpoint is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_put_writes(self, client: Agentex) -> None: + response = client.checkpoints.with_raw_response.put_writes( + checkpoint_id="checkpoint_id", + thread_id="thread_id", + writes=[ + { + "blob": "blob", + "channel": "channel", + "idx": 0, + "task_id": "task_id", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + checkpoint = response.parse() + assert checkpoint is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_put_writes(self, client: Agentex) -> None: + with client.checkpoints.with_streaming_response.put_writes( + checkpoint_id="checkpoint_id", + thread_id="thread_id", + writes=[ + { + "blob": "blob", + "channel": "channel", + "idx": 0, + "task_id": "task_id", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + checkpoint = response.parse() + assert checkpoint is None + + assert cast(Any, response.is_closed) is True + + +class TestAsyncCheckpoints: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncAgentex) -> None: + checkpoint = await async_client.checkpoints.list( + thread_id="thread_id", + ) + assert_matches_type(CheckpointListResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncAgentex) -> None: + checkpoint = await async_client.checkpoints.list( + thread_id="thread_id", + before_checkpoint_id="before_checkpoint_id", + checkpoint_ns="checkpoint_ns", + filter_metadata={"foo": "bar"}, + limit=1, + ) + assert_matches_type(CheckpointListResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncAgentex) -> None: + response = await async_client.checkpoints.with_raw_response.list( + thread_id="thread_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + checkpoint = await response.parse() + assert_matches_type(CheckpointListResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncAgentex) -> None: + async with async_client.checkpoints.with_streaming_response.list( + thread_id="thread_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + checkpoint = await response.parse() + assert_matches_type(CheckpointListResponse, checkpoint, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete_thread(self, async_client: AsyncAgentex) -> None: + checkpoint = await async_client.checkpoints.delete_thread( + thread_id="thread_id", + ) + assert checkpoint is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete_thread(self, async_client: AsyncAgentex) -> None: + response = await async_client.checkpoints.with_raw_response.delete_thread( + thread_id="thread_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + checkpoint = await response.parse() + assert checkpoint is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete_thread(self, async_client: AsyncAgentex) -> None: + async with async_client.checkpoints.with_streaming_response.delete_thread( + thread_id="thread_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + checkpoint = await response.parse() + assert checkpoint is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_tuple(self, async_client: AsyncAgentex) -> None: + checkpoint = await async_client.checkpoints.get_tuple( + thread_id="thread_id", + ) + assert_matches_type(Optional[CheckpointGetTupleResponse], checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_tuple_with_all_params(self, async_client: AsyncAgentex) -> None: + checkpoint = await async_client.checkpoints.get_tuple( + thread_id="thread_id", + checkpoint_id="checkpoint_id", + checkpoint_ns="checkpoint_ns", + ) + assert_matches_type(Optional[CheckpointGetTupleResponse], checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_tuple(self, async_client: AsyncAgentex) -> None: + response = await async_client.checkpoints.with_raw_response.get_tuple( + thread_id="thread_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + checkpoint = await response.parse() + assert_matches_type(Optional[CheckpointGetTupleResponse], checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_tuple(self, async_client: AsyncAgentex) -> None: + async with async_client.checkpoints.with_streaming_response.get_tuple( + thread_id="thread_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + checkpoint = await response.parse() + assert_matches_type(Optional[CheckpointGetTupleResponse], checkpoint, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_put(self, async_client: AsyncAgentex) -> None: + checkpoint = await async_client.checkpoints.put( + checkpoint={"foo": "bar"}, + checkpoint_id="checkpoint_id", + thread_id="thread_id", + ) + assert_matches_type(CheckpointPutResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_put_with_all_params(self, async_client: AsyncAgentex) -> None: + checkpoint = await async_client.checkpoints.put( + checkpoint={"foo": "bar"}, + checkpoint_id="checkpoint_id", + thread_id="thread_id", + blobs=[ + { + "channel": "channel", + "type": "type", + "version": "version", + "blob": "blob", + } + ], + checkpoint_ns="checkpoint_ns", + metadata={"foo": "bar"}, + parent_checkpoint_id="parent_checkpoint_id", + ) + assert_matches_type(CheckpointPutResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_put(self, async_client: AsyncAgentex) -> None: + response = await async_client.checkpoints.with_raw_response.put( + checkpoint={"foo": "bar"}, + checkpoint_id="checkpoint_id", + thread_id="thread_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + checkpoint = await response.parse() + assert_matches_type(CheckpointPutResponse, checkpoint, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_put(self, async_client: AsyncAgentex) -> None: + async with async_client.checkpoints.with_streaming_response.put( + checkpoint={"foo": "bar"}, + checkpoint_id="checkpoint_id", + thread_id="thread_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + checkpoint = await response.parse() + assert_matches_type(CheckpointPutResponse, checkpoint, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_put_writes(self, async_client: AsyncAgentex) -> None: + checkpoint = await async_client.checkpoints.put_writes( + checkpoint_id="checkpoint_id", + thread_id="thread_id", + writes=[ + { + "blob": "blob", + "channel": "channel", + "idx": 0, + "task_id": "task_id", + } + ], + ) + assert checkpoint is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_put_writes_with_all_params(self, async_client: AsyncAgentex) -> None: + checkpoint = await async_client.checkpoints.put_writes( + checkpoint_id="checkpoint_id", + thread_id="thread_id", + writes=[ + { + "blob": "blob", + "channel": "channel", + "idx": 0, + "task_id": "task_id", + "task_path": "task_path", + "type": "type", + } + ], + checkpoint_ns="checkpoint_ns", + upsert=True, + ) + assert checkpoint is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_put_writes(self, async_client: AsyncAgentex) -> None: + response = await async_client.checkpoints.with_raw_response.put_writes( + checkpoint_id="checkpoint_id", + thread_id="thread_id", + writes=[ + { + "blob": "blob", + "channel": "channel", + "idx": 0, + "task_id": "task_id", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + checkpoint = await response.parse() + assert checkpoint is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_put_writes(self, async_client: AsyncAgentex) -> None: + async with async_client.checkpoints.with_streaming_response.put_writes( + checkpoint_id="checkpoint_id", + thread_id="thread_id", + writes=[ + { + "blob": "blob", + "channel": "channel", + "idx": 0, + "task_id": "task_id", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + checkpoint = await response.parse() + assert checkpoint is None + + assert cast(Any, response.is_closed) is True