From de1744eeddf1780ca9bae2690f0ed0b17406754f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 20:25:53 +0000 Subject: [PATCH 1/4] chore(internal): make `test_proxy_environment_variables` more resilient --- tests/test_client.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_client.py b/tests/test_client.py index 256da4b..0622cd8 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -943,6 +943,8 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: def test_proxy_environment_variables(self, monkeypatch: pytest.MonkeyPatch) -> None: # Test that the proxy environment variables are set correctly monkeypatch.setenv("HTTPS_PROXY", "https://example.org") + # Delete in case our environment has this set + monkeypatch.delenv("HTTP_PROXY", raising=False) client = DefaultHttpxClient() @@ -1843,6 +1845,8 @@ async def test_get_platform(self) -> None: async def test_proxy_environment_variables(self, monkeypatch: pytest.MonkeyPatch) -> None: # Test that the proxy environment variables are set correctly monkeypatch.setenv("HTTPS_PROXY", "https://example.org") + # Delete in case our environment has this set + monkeypatch.delenv("HTTP_PROXY", raising=False) client = DefaultAsyncHttpxClient() From 73b719a978f70ae36bd374535d80372dfaf1d47f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 20:32:53 +0000 Subject: [PATCH 2/4] feat(api): manual updates --- .stats.yml | 4 +- src/oz_agent_sdk/resources/agent/agent.py | 28 ++++++------- src/oz_agent_sdk/resources/agent/runs.py | 4 +- src/oz_agent_sdk/resources/agent/schedules.py | 40 ++++++++++--------- src/oz_agent_sdk/types/agent/artifact_item.py | 33 ++++++++++++++- src/oz_agent_sdk/types/agent/run_item.py | 4 +- .../types/agent/run_list_params.py | 2 +- src/oz_agent_sdk/types/agent/run_state.py | 4 +- .../types/agent/schedule_create_params.py | 11 +++-- .../types/agent/schedule_update_params.py | 11 +++-- .../types/agent/scheduled_agent_item.py | 2 +- src/oz_agent_sdk/types/agent_run_params.py | 35 ++++++++-------- src/oz_agent_sdk/types/agent_run_response.py | 7 ++++ .../types/ambient_agent_config.py | 9 ++++- .../types/ambient_agent_config_param.py | 9 ++++- src/oz_agent_sdk/types/user_profile.py | 3 ++ tests/api_resources/agent/test_schedules.py | 22 ++-------- tests/api_resources/test_agent.py | 26 ++++++------ 18 files changed, 154 insertions(+), 100 deletions(-) diff --git a/.stats.yml b/.stats.yml index 0643054..9d10843 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 12 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/warp-bnavetta%2Fwarp-api-c99d72d8d845f1eeabf7a716949a12408df952a2a0ca2b97df570da3a7c8bb49.yml -openapi_spec_hash: 8a503cbccc8a5741554282327a557114 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/warp-bnavetta%2Fwarp-api-91a7db62ba0752b9bdccd4bac4c6d09c1d59b7b69788159fe13598b7a5def7ee.yml +openapi_spec_hash: f03a889deaf6df14d678643be1e4dbe3 config_hash: 433e7a5579323a048aa173a0ace06bfc diff --git a/src/oz_agent_sdk/resources/agent/agent.py b/src/oz_agent_sdk/resources/agent/agent.py index 6e8b0ba..d15d211 100644 --- a/src/oz_agent_sdk/resources/agent/agent.py +++ b/src/oz_agent_sdk/resources/agent/agent.py @@ -129,9 +129,9 @@ def list( def run( self, *, + attachments: Iterable[agent_run_params.Attachment] | Omit = omit, config: AmbientAgentConfigParam | Omit = omit, conversation_id: str | Omit = omit, - images: Iterable[agent_run_params.Image] | Omit = omit, prompt: str | Omit = omit, skill: str | Omit = omit, team: bool | Omit = omit, @@ -143,20 +143,20 @@ def run( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AgentRunResponse: - """Spawn an cloud agent with a prompt and optional configuration. + """Spawn a cloud agent with a prompt and optional configuration. The agent will be queued for execution and assigned a unique run ID. Args: - config: Configuration for an cloud agent run + attachments: Optional file attachments to include with the prompt (max 5). Attachments are + uploaded to cloud storage and made available to the agent. + + config: Configuration for a cloud agent run conversation_id: Optional conversation ID to continue an existing conversation. If provided, the agent will continue from where the previous run left off. - images: Optional images to include with the prompt (max 5). Images are uploaded to cloud - storage and made available to the agent. - prompt: The prompt/instruction for the agent to execute. Required unless a skill is specified via the skill field or config.skill_spec. @@ -185,9 +185,9 @@ def run( "/agent/run", body=maybe_transform( { + "attachments": attachments, "config": config, "conversation_id": conversation_id, - "images": images, "prompt": prompt, "skill": skill, "team": team, @@ -289,9 +289,9 @@ async def list( async def run( self, *, + attachments: Iterable[agent_run_params.Attachment] | Omit = omit, config: AmbientAgentConfigParam | Omit = omit, conversation_id: str | Omit = omit, - images: Iterable[agent_run_params.Image] | Omit = omit, prompt: str | Omit = omit, skill: str | Omit = omit, team: bool | Omit = omit, @@ -303,20 +303,20 @@ async def run( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AgentRunResponse: - """Spawn an cloud agent with a prompt and optional configuration. + """Spawn a cloud agent with a prompt and optional configuration. The agent will be queued for execution and assigned a unique run ID. Args: - config: Configuration for an cloud agent run + attachments: Optional file attachments to include with the prompt (max 5). Attachments are + uploaded to cloud storage and made available to the agent. + + config: Configuration for a cloud agent run conversation_id: Optional conversation ID to continue an existing conversation. If provided, the agent will continue from where the previous run left off. - images: Optional images to include with the prompt (max 5). Images are uploaded to cloud - storage and made available to the agent. - prompt: The prompt/instruction for the agent to execute. Required unless a skill is specified via the skill field or config.skill_spec. @@ -345,9 +345,9 @@ async def run( "/agent/run", body=await async_maybe_transform( { + "attachments": attachments, "config": config, "conversation_id": conversation_id, - "images": images, "prompt": prompt, "skill": skill, "team": team, diff --git a/src/oz_agent_sdk/resources/agent/runs.py b/src/oz_agent_sdk/resources/agent/runs.py index 6633337..561ef78 100644 --- a/src/oz_agent_sdk/resources/agent/runs.py +++ b/src/oz_agent_sdk/resources/agent/runs.py @@ -85,7 +85,7 @@ def retrieve( def list( self, *, - artifact_type: Literal["PLAN", "PULL_REQUEST"] | Omit = omit, + artifact_type: Literal["PLAN", "PULL_REQUEST", "SCREENSHOT"] | Omit = omit, created_after: Union[str, datetime] | Omit = omit, created_before: Union[str, datetime] | Omit = omit, creator: str | Omit = omit, @@ -281,7 +281,7 @@ async def retrieve( async def list( self, *, - artifact_type: Literal["PLAN", "PULL_REQUEST"] | Omit = omit, + artifact_type: Literal["PLAN", "PULL_REQUEST", "SCREENSHOT"] | Omit = omit, created_after: Union[str, datetime] | Omit = omit, created_before: Union[str, datetime] | Omit = omit, creator: str | Omit = omit, diff --git a/src/oz_agent_sdk/resources/agent/schedules.py b/src/oz_agent_sdk/resources/agent/schedules.py index 38e177b..0a6a3c7 100644 --- a/src/oz_agent_sdk/resources/agent/schedules.py +++ b/src/oz_agent_sdk/resources/agent/schedules.py @@ -49,9 +49,9 @@ def create( *, cron_schedule: str, name: str, - prompt: str, agent_config: AmbientAgentConfigParam | Omit = omit, enabled: bool | Omit = omit, + prompt: str | Omit = omit, team: 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. @@ -71,12 +71,13 @@ def create( name: Human-readable name for the schedule - prompt: The prompt/instruction for the agent to execute - - agent_config: Configuration for an cloud agent run + agent_config: Configuration for a cloud agent run enabled: Whether the schedule should be active immediately + prompt: The prompt/instruction for the agent to execute. Required unless + agent_config.skill_spec is provided. + team: Whether to create a team-owned schedule. Defaults to true for users on a single team. @@ -94,9 +95,9 @@ def create( { "cron_schedule": cron_schedule, "name": name, - "prompt": prompt, "agent_config": agent_config, "enabled": enabled, + "prompt": prompt, "team": team, }, schedule_create_params.ScheduleCreateParams, @@ -148,8 +149,8 @@ def update( cron_schedule: str, enabled: bool, name: str, - prompt: str, agent_config: AmbientAgentConfigParam | Omit = omit, + prompt: 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, @@ -169,9 +170,10 @@ def update( name: Human-readable name for the schedule - prompt: The prompt/instruction for the agent to execute + agent_config: Configuration for a cloud agent run - agent_config: Configuration for an cloud agent run + prompt: The prompt/instruction for the agent to execute. Required unless + agent_config.skill_spec is provided. extra_headers: Send extra headers @@ -190,8 +192,8 @@ def update( "cron_schedule": cron_schedule, "enabled": enabled, "name": name, - "prompt": prompt, "agent_config": agent_config, + "prompt": prompt, }, schedule_update_params.ScheduleUpdateParams, ), @@ -354,9 +356,9 @@ async def create( *, cron_schedule: str, name: str, - prompt: str, agent_config: AmbientAgentConfigParam | Omit = omit, enabled: bool | Omit = omit, + prompt: str | Omit = omit, team: 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. @@ -376,12 +378,13 @@ async def create( name: Human-readable name for the schedule - prompt: The prompt/instruction for the agent to execute - - agent_config: Configuration for an cloud agent run + agent_config: Configuration for a cloud agent run enabled: Whether the schedule should be active immediately + prompt: The prompt/instruction for the agent to execute. Required unless + agent_config.skill_spec is provided. + team: Whether to create a team-owned schedule. Defaults to true for users on a single team. @@ -399,9 +402,9 @@ async def create( { "cron_schedule": cron_schedule, "name": name, - "prompt": prompt, "agent_config": agent_config, "enabled": enabled, + "prompt": prompt, "team": team, }, schedule_create_params.ScheduleCreateParams, @@ -453,8 +456,8 @@ async def update( cron_schedule: str, enabled: bool, name: str, - prompt: str, agent_config: AmbientAgentConfigParam | Omit = omit, + prompt: 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, @@ -474,9 +477,10 @@ async def update( name: Human-readable name for the schedule - prompt: The prompt/instruction for the agent to execute + agent_config: Configuration for a cloud agent run - agent_config: Configuration for an cloud agent run + prompt: The prompt/instruction for the agent to execute. Required unless + agent_config.skill_spec is provided. extra_headers: Send extra headers @@ -495,8 +499,8 @@ async def update( "cron_schedule": cron_schedule, "enabled": enabled, "name": name, - "prompt": prompt, "agent_config": agent_config, + "prompt": prompt, }, schedule_update_params.ScheduleUpdateParams, ), diff --git a/src/oz_agent_sdk/types/agent/artifact_item.py b/src/oz_agent_sdk/types/agent/artifact_item.py index c5bdbac..7cbba71 100644 --- a/src/oz_agent_sdk/types/agent/artifact_item.py +++ b/src/oz_agent_sdk/types/agent/artifact_item.py @@ -7,7 +7,15 @@ from ..._utils import PropertyInfo from ..._models import BaseModel -__all__ = ["ArtifactItem", "PlanArtifact", "PlanArtifactData", "PullRequestArtifact", "PullRequestArtifactData"] +__all__ = [ + "ArtifactItem", + "PlanArtifact", + "PlanArtifactData", + "PullRequestArtifact", + "PullRequestArtifactData", + "ScreenshotArtifact", + "ScreenshotArtifactData", +] class PlanArtifactData(BaseModel): @@ -49,6 +57,27 @@ class PullRequestArtifact(BaseModel): data: PullRequestArtifactData +class ScreenshotArtifactData(BaseModel): + artifact_uid: str + """Unique identifier for the screenshot artifact""" + + mime_type: str + """MIME type of the screenshot image""" + + description: Optional[str] = None + """Optional description of the screenshot""" + + +class ScreenshotArtifact(BaseModel): + artifact_type: Literal["SCREENSHOT"] + """Type of the artifact""" + + created_at: datetime + """Timestamp when the artifact was created (RFC3339)""" + + data: ScreenshotArtifactData + + ArtifactItem: TypeAlias = Annotated[ - Union[PlanArtifact, PullRequestArtifact], PropertyInfo(discriminator="artifact_type") + Union[PlanArtifact, PullRequestArtifact, ScreenshotArtifact], PropertyInfo(discriminator="artifact_type") ] diff --git a/src/oz_agent_sdk/types/agent/run_item.py b/src/oz_agent_sdk/types/agent/run_item.py index 8befd28..d7a2507 100644 --- a/src/oz_agent_sdk/types/agent/run_item.py +++ b/src/oz_agent_sdk/types/agent/run_item.py @@ -92,6 +92,8 @@ class RunItem(BaseModel): - INPROGRESS: Run is actively being executed - SUCCEEDED: Run completed successfully - FAILED: Run failed + - BLOCKED: Run is blocked (e.g., awaiting user input or approval) + - ERROR: Run encountered an error - CANCELLED: Run was cancelled by user """ @@ -108,7 +110,7 @@ class RunItem(BaseModel): """Timestamp when the run was last updated (RFC3339)""" agent_config: Optional[AmbientAgentConfig] = None - """Configuration for an cloud agent run""" + """Configuration for a cloud agent run""" agent_skill: Optional[AgentSkill] = None """ diff --git a/src/oz_agent_sdk/types/agent/run_list_params.py b/src/oz_agent_sdk/types/agent/run_list_params.py index 6aac8c4..d0c89d9 100644 --- a/src/oz_agent_sdk/types/agent/run_list_params.py +++ b/src/oz_agent_sdk/types/agent/run_list_params.py @@ -14,7 +14,7 @@ class RunListParams(TypedDict, total=False): - artifact_type: Literal["PLAN", "PULL_REQUEST"] + artifact_type: Literal["PLAN", "PULL_REQUEST", "SCREENSHOT"] """Filter runs by artifact type (PLAN or PULL_REQUEST)""" created_after: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] diff --git a/src/oz_agent_sdk/types/agent/run_state.py b/src/oz_agent_sdk/types/agent/run_state.py index de26b4d..c3fbe73 100644 --- a/src/oz_agent_sdk/types/agent/run_state.py +++ b/src/oz_agent_sdk/types/agent/run_state.py @@ -4,4 +4,6 @@ __all__ = ["RunState"] -RunState: TypeAlias = Literal["QUEUED", "PENDING", "CLAIMED", "INPROGRESS", "SUCCEEDED", "FAILED", "CANCELLED"] +RunState: TypeAlias = Literal[ + "QUEUED", "PENDING", "CLAIMED", "INPROGRESS", "SUCCEEDED", "FAILED", "BLOCKED", "ERROR", "CANCELLED" +] diff --git a/src/oz_agent_sdk/types/agent/schedule_create_params.py b/src/oz_agent_sdk/types/agent/schedule_create_params.py index 2c6a8c2..e94a3b3 100644 --- a/src/oz_agent_sdk/types/agent/schedule_create_params.py +++ b/src/oz_agent_sdk/types/agent/schedule_create_params.py @@ -19,15 +19,18 @@ class ScheduleCreateParams(TypedDict, total=False): name: Required[str] """Human-readable name for the schedule""" - prompt: Required[str] - """The prompt/instruction for the agent to execute""" - agent_config: AmbientAgentConfigParam - """Configuration for an cloud agent run""" + """Configuration for a cloud agent run""" enabled: bool """Whether the schedule should be active immediately""" + prompt: str + """ + The prompt/instruction for the agent to execute. Required unless + agent_config.skill_spec is provided. + """ + team: bool """ Whether to create a team-owned schedule. Defaults to true for users on a single diff --git a/src/oz_agent_sdk/types/agent/schedule_update_params.py b/src/oz_agent_sdk/types/agent/schedule_update_params.py index 7408ab1..2c82454 100644 --- a/src/oz_agent_sdk/types/agent/schedule_update_params.py +++ b/src/oz_agent_sdk/types/agent/schedule_update_params.py @@ -19,8 +19,11 @@ class ScheduleUpdateParams(TypedDict, total=False): name: Required[str] """Human-readable name for the schedule""" - prompt: Required[str] - """The prompt/instruction for the agent to execute""" - agent_config: AmbientAgentConfigParam - """Configuration for an cloud agent run""" + """Configuration for a cloud agent run""" + + prompt: str + """ + The prompt/instruction for the agent to execute. Required unless + agent_config.skill_spec is provided. + """ diff --git a/src/oz_agent_sdk/types/agent/scheduled_agent_item.py b/src/oz_agent_sdk/types/agent/scheduled_agent_item.py index 8de40ef..86716d7 100644 --- a/src/oz_agent_sdk/types/agent/scheduled_agent_item.py +++ b/src/oz_agent_sdk/types/agent/scheduled_agent_item.py @@ -58,7 +58,7 @@ class ScheduledAgentItem(BaseModel): """Timestamp when the schedule was last updated (RFC3339)""" agent_config: Optional[AmbientAgentConfig] = None - """Configuration for an cloud agent run""" + """Configuration for a cloud agent run""" created_by: Optional[UserProfile] = None diff --git a/src/oz_agent_sdk/types/agent_run_params.py b/src/oz_agent_sdk/types/agent_run_params.py index 80a714b..7f38ea2 100644 --- a/src/oz_agent_sdk/types/agent_run_params.py +++ b/src/oz_agent_sdk/types/agent_run_params.py @@ -3,19 +3,25 @@ from __future__ import annotations from typing import Union, Iterable -from typing_extensions import Literal, Required, Annotated, TypedDict +from typing_extensions import Required, Annotated, TypedDict from .._types import Base64FileInput from .._utils import PropertyInfo from .._models import set_pydantic_config from .ambient_agent_config_param import AmbientAgentConfigParam -__all__ = ["AgentRunParams", "Image"] +__all__ = ["AgentRunParams", "Attachment"] class AgentRunParams(TypedDict, total=False): + attachments: Iterable[Attachment] + """ + Optional file attachments to include with the prompt (max 5). Attachments are + uploaded to cloud storage and made available to the agent. + """ + config: AmbientAgentConfigParam - """Configuration for an cloud agent run""" + """Configuration for a cloud agent run""" conversation_id: str """ @@ -23,12 +29,6 @@ class AgentRunParams(TypedDict, total=False): agent will continue from where the previous run left off. """ - images: Iterable[Image] - """ - Optional images to include with the prompt (max 5). Images are uploaded to cloud - storage and made available to the agent. - """ - prompt: str """ The prompt/instruction for the agent to execute. Required unless a skill is @@ -54,17 +54,20 @@ class AgentRunParams(TypedDict, total=False): """Custom title for the run (auto-generated if not provided)""" -class Image(TypedDict, total=False): - """A base64-encoded image to include with the prompt""" +class Attachment(TypedDict, total=False): + """A base64-encoded file attachment to include with the prompt""" data: Required[Annotated[Union[str, Base64FileInput], PropertyInfo(format="base64")]] - """Base64-encoded image data""" + """Base64-encoded attachment data""" + + file_name: Required[str] + """Name of the attached file""" - mime_type: Required[Literal["image/jpeg", "image/png", "image/gif", "image/webp"]] + mime_type: Required[str] """ - MIME type of the image. Supported types: image/jpeg, image/png, image/gif, - image/webp + MIME type of the attachment. Supported image types: image/jpeg, image/png, + image/gif, image/webp """ -set_pydantic_config(Image, {"arbitrary_types_allowed": True}) +set_pydantic_config(Attachment, {"arbitrary_types_allowed": True}) diff --git a/src/oz_agent_sdk/types/agent_run_response.py b/src/oz_agent_sdk/types/agent_run_response.py index bef3a36..fb2480e 100644 --- a/src/oz_agent_sdk/types/agent_run_response.py +++ b/src/oz_agent_sdk/types/agent_run_response.py @@ -1,5 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from typing import Optional + from .._models import BaseModel from .agent.run_state import RunState @@ -19,6 +21,8 @@ class AgentRunResponse(BaseModel): - INPROGRESS: Run is actively being executed - SUCCEEDED: Run completed successfully - FAILED: Run failed + - BLOCKED: Run is blocked (e.g., awaiting user input or approval) + - ERROR: Run encountered an error - CANCELLED: Run was cancelled by user """ @@ -27,3 +31,6 @@ class AgentRunResponse(BaseModel): Deprecated - use run_id instead. """ + + at_capacity: Optional[bool] = None + """Whether the system is at capacity when the run was created""" diff --git a/src/oz_agent_sdk/types/ambient_agent_config.py b/src/oz_agent_sdk/types/ambient_agent_config.py index add389f..67667c8 100644 --- a/src/oz_agent_sdk/types/ambient_agent_config.py +++ b/src/oz_agent_sdk/types/ambient_agent_config.py @@ -11,7 +11,7 @@ class AmbientAgentConfig(BaseModel): - """Configuration for an cloud agent run""" + """Configuration for a cloud agent run""" base_prompt: Optional[str] = None """Custom base prompt for the agent""" @@ -32,7 +32,12 @@ class AmbientAgentConfig(BaseModel): """LLM model to use (uses team default if not specified)""" name: Optional[str] = None - """Config name for searchability and traceability""" + """ + Human-readable label for grouping, filtering, and traceability. Automatically + set to the skill name when running a skill-based agent. Set this explicitly to + categorize runs by intent (e.g., "nightly-dependency-check") so you can filter + and track them via the name query parameter on GET /agent/runs. + """ skill_spec: Optional[str] = None """ diff --git a/src/oz_agent_sdk/types/ambient_agent_config_param.py b/src/oz_agent_sdk/types/ambient_agent_config_param.py index bf55e89..1cd17fe 100644 --- a/src/oz_agent_sdk/types/ambient_agent_config_param.py +++ b/src/oz_agent_sdk/types/ambient_agent_config_param.py @@ -11,7 +11,7 @@ class AmbientAgentConfigParam(TypedDict, total=False): - """Configuration for an cloud agent run""" + """Configuration for a cloud agent run""" base_prompt: str """Custom base prompt for the agent""" @@ -32,7 +32,12 @@ class AmbientAgentConfigParam(TypedDict, total=False): """LLM model to use (uses team default if not specified)""" name: str - """Config name for searchability and traceability""" + """ + Human-readable label for grouping, filtering, and traceability. Automatically + set to the skill name when running a skill-based agent. Set this explicitly to + categorize runs by intent (e.g., "nightly-dependency-check") so you can filter + and track them via the name query parameter on GET /agent/runs. + """ skill_spec: str """ diff --git a/src/oz_agent_sdk/types/user_profile.py b/src/oz_agent_sdk/types/user_profile.py index ed7bb01..5892be4 100644 --- a/src/oz_agent_sdk/types/user_profile.py +++ b/src/oz_agent_sdk/types/user_profile.py @@ -12,6 +12,9 @@ class UserProfile(BaseModel): display_name: Optional[str] = None """Display name of the creator""" + email: Optional[str] = None + """Email address of the creator""" + photo_url: Optional[str] = None """URL to the creator's photo""" diff --git a/tests/api_resources/agent/test_schedules.py b/tests/api_resources/agent/test_schedules.py index 09c9b9d..e8f8a24 100644 --- a/tests/api_resources/agent/test_schedules.py +++ b/tests/api_resources/agent/test_schedules.py @@ -27,7 +27,6 @@ def test_method_create(self, client: OzAPI) -> None: schedule = client.agent.schedules.create( cron_schedule="0 9 * * *", name="Daily Code Review", - prompt="Review open pull requests and provide feedback", ) assert_matches_type(ScheduledAgentItem, schedule, path=["response"]) @@ -37,7 +36,6 @@ def test_method_create_with_all_params(self, client: OzAPI) -> None: schedule = client.agent.schedules.create( cron_schedule="0 9 * * *", name="Daily Code Review", - prompt="Review open pull requests and provide feedback", agent_config={ "base_prompt": "base_prompt", "computer_use_enabled": True, @@ -58,6 +56,7 @@ def test_method_create_with_all_params(self, client: OzAPI) -> None: "worker_host": "worker_host", }, enabled=True, + prompt="Review open pull requests and provide feedback", team=True, ) assert_matches_type(ScheduledAgentItem, schedule, path=["response"]) @@ -68,7 +67,6 @@ def test_raw_response_create(self, client: OzAPI) -> None: response = client.agent.schedules.with_raw_response.create( cron_schedule="0 9 * * *", name="Daily Code Review", - prompt="Review open pull requests and provide feedback", ) assert response.is_closed is True @@ -82,7 +80,6 @@ def test_streaming_response_create(self, client: OzAPI) -> None: with client.agent.schedules.with_streaming_response.create( cron_schedule="0 9 * * *", name="Daily Code Review", - prompt="Review open pull requests and provide feedback", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -142,7 +139,6 @@ def test_method_update(self, client: OzAPI) -> None: cron_schedule="cron_schedule", enabled=True, name="name", - prompt="prompt", ) assert_matches_type(ScheduledAgentItem, schedule, path=["response"]) @@ -154,7 +150,6 @@ def test_method_update_with_all_params(self, client: OzAPI) -> None: cron_schedule="cron_schedule", enabled=True, name="name", - prompt="prompt", agent_config={ "base_prompt": "base_prompt", "computer_use_enabled": True, @@ -174,6 +169,7 @@ def test_method_update_with_all_params(self, client: OzAPI) -> None: "skill_spec": "skill_spec", "worker_host": "worker_host", }, + prompt="prompt", ) assert_matches_type(ScheduledAgentItem, schedule, path=["response"]) @@ -185,7 +181,6 @@ def test_raw_response_update(self, client: OzAPI) -> None: cron_schedule="cron_schedule", enabled=True, name="name", - prompt="prompt", ) assert response.is_closed is True @@ -201,7 +196,6 @@ def test_streaming_response_update(self, client: OzAPI) -> None: cron_schedule="cron_schedule", enabled=True, name="name", - prompt="prompt", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -220,7 +214,6 @@ def test_path_params_update(self, client: OzAPI) -> None: cron_schedule="cron_schedule", enabled=True, name="name", - prompt="prompt", ) @pytest.mark.skip(reason="Mock server tests are disabled") @@ -389,7 +382,6 @@ async def test_method_create(self, async_client: AsyncOzAPI) -> None: schedule = await async_client.agent.schedules.create( cron_schedule="0 9 * * *", name="Daily Code Review", - prompt="Review open pull requests and provide feedback", ) assert_matches_type(ScheduledAgentItem, schedule, path=["response"]) @@ -399,7 +391,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncOzAPI) -> schedule = await async_client.agent.schedules.create( cron_schedule="0 9 * * *", name="Daily Code Review", - prompt="Review open pull requests and provide feedback", agent_config={ "base_prompt": "base_prompt", "computer_use_enabled": True, @@ -420,6 +411,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOzAPI) -> "worker_host": "worker_host", }, enabled=True, + prompt="Review open pull requests and provide feedback", team=True, ) assert_matches_type(ScheduledAgentItem, schedule, path=["response"]) @@ -430,7 +422,6 @@ async def test_raw_response_create(self, async_client: AsyncOzAPI) -> None: response = await async_client.agent.schedules.with_raw_response.create( cron_schedule="0 9 * * *", name="Daily Code Review", - prompt="Review open pull requests and provide feedback", ) assert response.is_closed is True @@ -444,7 +435,6 @@ async def test_streaming_response_create(self, async_client: AsyncOzAPI) -> None async with async_client.agent.schedules.with_streaming_response.create( cron_schedule="0 9 * * *", name="Daily Code Review", - prompt="Review open pull requests and provide feedback", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -504,7 +494,6 @@ async def test_method_update(self, async_client: AsyncOzAPI) -> None: cron_schedule="cron_schedule", enabled=True, name="name", - prompt="prompt", ) assert_matches_type(ScheduledAgentItem, schedule, path=["response"]) @@ -516,7 +505,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncOzAPI) -> cron_schedule="cron_schedule", enabled=True, name="name", - prompt="prompt", agent_config={ "base_prompt": "base_prompt", "computer_use_enabled": True, @@ -536,6 +524,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncOzAPI) -> "skill_spec": "skill_spec", "worker_host": "worker_host", }, + prompt="prompt", ) assert_matches_type(ScheduledAgentItem, schedule, path=["response"]) @@ -547,7 +536,6 @@ async def test_raw_response_update(self, async_client: AsyncOzAPI) -> None: cron_schedule="cron_schedule", enabled=True, name="name", - prompt="prompt", ) assert response.is_closed is True @@ -563,7 +551,6 @@ async def test_streaming_response_update(self, async_client: AsyncOzAPI) -> None cron_schedule="cron_schedule", enabled=True, name="name", - prompt="prompt", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -582,7 +569,6 @@ async def test_path_params_update(self, async_client: AsyncOzAPI) -> None: cron_schedule="cron_schedule", enabled=True, name="name", - prompt="prompt", ) @pytest.mark.skip(reason="Mock server tests are disabled") diff --git a/tests/api_resources/test_agent.py b/tests/api_resources/test_agent.py index 604eab0..5a71190 100644 --- a/tests/api_resources/test_agent.py +++ b/tests/api_resources/test_agent.py @@ -68,6 +68,13 @@ def test_method_run(self, client: OzAPI) -> None: @parametrize def test_method_run_with_all_params(self, client: OzAPI) -> None: agent = client.agent.run( + attachments=[ + { + "data": "U3RhaW5sZXNzIHJvY2tz", + "file_name": "file_name", + "mime_type": "mime_type", + } + ], config={ "base_prompt": "base_prompt", "computer_use_enabled": True, @@ -88,12 +95,6 @@ def test_method_run_with_all_params(self, client: OzAPI) -> None: "worker_host": "worker_host", }, conversation_id="conversation_id", - images=[ - { - "data": "U3RhaW5sZXNzIHJvY2tz", - "mime_type": "image/jpeg", - } - ], prompt="Fix the bug in auth.go", skill="skill", team=True, @@ -177,6 +178,13 @@ async def test_method_run(self, async_client: AsyncOzAPI) -> None: @parametrize async def test_method_run_with_all_params(self, async_client: AsyncOzAPI) -> None: agent = await async_client.agent.run( + attachments=[ + { + "data": "U3RhaW5sZXNzIHJvY2tz", + "file_name": "file_name", + "mime_type": "mime_type", + } + ], config={ "base_prompt": "base_prompt", "computer_use_enabled": True, @@ -197,12 +205,6 @@ async def test_method_run_with_all_params(self, async_client: AsyncOzAPI) -> Non "worker_host": "worker_host", }, conversation_id="conversation_id", - images=[ - { - "data": "U3RhaW5sZXNzIHJvY2tz", - "mime_type": "image/jpeg", - } - ], prompt="Fix the bug in auth.go", skill="skill", team=True, From 1b38e0943935c83c0283523fc045eb2ff2f56109 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 20:39:15 +0000 Subject: [PATCH 3/4] feat(api): manual updates --- .stats.yml | 4 +- api.md | 14 ++ src/oz_agent_sdk/resources/agent/__init__.py | 14 ++ src/oz_agent_sdk/resources/agent/agent.py | 115 ++++++++++++ src/oz_agent_sdk/resources/agent/sessions.py | 167 ++++++++++++++++++ src/oz_agent_sdk/types/__init__.py | 1 + src/oz_agent_sdk/types/agent/__init__.py | 1 + .../agent/session_check_redirect_response.py | 12 ++ .../types/agent_get_artifact_response.py | 40 +++++ tests/api_resources/agent/test_sessions.py | 108 +++++++++++ tests/api_resources/test_agent.py | 85 +++++++++ 11 files changed, 559 insertions(+), 2 deletions(-) create mode 100644 src/oz_agent_sdk/resources/agent/sessions.py create mode 100644 src/oz_agent_sdk/types/agent/session_check_redirect_response.py create mode 100644 src/oz_agent_sdk/types/agent_get_artifact_response.py create mode 100644 tests/api_resources/agent/test_sessions.py diff --git a/.stats.yml b/.stats.yml index 9d10843..ed196e5 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 12 +configured_endpoints: 14 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/warp-bnavetta%2Fwarp-api-91a7db62ba0752b9bdccd4bac4c6d09c1d59b7b69788159fe13598b7a5def7ee.yml openapi_spec_hash: f03a889deaf6df14d678643be1e4dbe3 -config_hash: 433e7a5579323a048aa173a0ace06bfc +config_hash: 25c1059aa958c8c2ad60ef16c318514d diff --git a/api.md b/api.md index b70e6d9..6f5ccdd 100644 --- a/api.md +++ b/api.md @@ -10,6 +10,7 @@ from oz_agent_sdk.types import ( McpServerConfig, UserProfile, AgentListResponse, + AgentGetArtifactResponse, AgentRunResponse, ) ``` @@ -17,6 +18,7 @@ from oz_agent_sdk.types import ( Methods: - client.agent.list(\*\*params) -> AgentListResponse +- client.agent.get_artifact(artifact_uid) -> AgentGetArtifactResponse - client.agent.run(\*\*params) -> AgentRunResponse ## Runs @@ -61,3 +63,15 @@ Methods: - client.agent.schedules.delete(schedule_id) -> ScheduleDeleteResponse - client.agent.schedules.pause(schedule_id) -> ScheduledAgentItem - client.agent.schedules.resume(schedule_id) -> ScheduledAgentItem + +## Sessions + +Types: + +```python +from oz_agent_sdk.types.agent import SessionCheckRedirectResponse +``` + +Methods: + +- client.agent.sessions.check_redirect(session_uuid) -> SessionCheckRedirectResponse diff --git a/src/oz_agent_sdk/resources/agent/__init__.py b/src/oz_agent_sdk/resources/agent/__init__.py index 84fc8a7..4336e34 100644 --- a/src/oz_agent_sdk/resources/agent/__init__.py +++ b/src/oz_agent_sdk/resources/agent/__init__.py @@ -16,6 +16,14 @@ AgentResourceWithStreamingResponse, AsyncAgentResourceWithStreamingResponse, ) +from .sessions import ( + SessionsResource, + AsyncSessionsResource, + SessionsResourceWithRawResponse, + AsyncSessionsResourceWithRawResponse, + SessionsResourceWithStreamingResponse, + AsyncSessionsResourceWithStreamingResponse, +) from .schedules import ( SchedulesResource, AsyncSchedulesResource, @@ -38,6 +46,12 @@ "AsyncSchedulesResourceWithRawResponse", "SchedulesResourceWithStreamingResponse", "AsyncSchedulesResourceWithStreamingResponse", + "SessionsResource", + "AsyncSessionsResource", + "SessionsResourceWithRawResponse", + "AsyncSessionsResourceWithRawResponse", + "SessionsResourceWithStreamingResponse", + "AsyncSessionsResourceWithStreamingResponse", "AgentResource", "AsyncAgentResource", "AgentResourceWithRawResponse", diff --git a/src/oz_agent_sdk/resources/agent/agent.py b/src/oz_agent_sdk/resources/agent/agent.py index d15d211..8e1ef5d 100644 --- a/src/oz_agent_sdk/resources/agent/agent.py +++ b/src/oz_agent_sdk/resources/agent/agent.py @@ -18,6 +18,14 @@ from ...types import agent_run_params, agent_list_params from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from ..._utils import maybe_transform, async_maybe_transform +from .sessions import ( + SessionsResource, + AsyncSessionsResource, + SessionsResourceWithRawResponse, + AsyncSessionsResourceWithRawResponse, + SessionsResourceWithStreamingResponse, + AsyncSessionsResourceWithStreamingResponse, +) from ..._compat import cached_property from .schedules import ( SchedulesResource, @@ -38,6 +46,7 @@ from ...types.agent_run_response import AgentRunResponse from ...types.agent_list_response import AgentListResponse from ...types.ambient_agent_config_param import AmbientAgentConfigParam +from ...types.agent_get_artifact_response import AgentGetArtifactResponse __all__ = ["AgentResource", "AsyncAgentResource"] @@ -51,6 +60,10 @@ def runs(self) -> RunsResource: def schedules(self) -> SchedulesResource: return SchedulesResource(self._client) + @cached_property + def sessions(self) -> SessionsResource: + return SessionsResource(self._client) + @cached_property def with_raw_response(self) -> AgentResourceWithRawResponse: """ @@ -126,6 +139,41 @@ def list( cast_to=AgentListResponse, ) + def get_artifact( + self, + artifact_uid: 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, + ) -> AgentGetArtifactResponse: + """Retrieve an artifact by its UUID. + + For screenshot artifacts, returns a + time-limited signed download URL. + + 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 artifact_uid: + raise ValueError(f"Expected a non-empty value for `artifact_uid` but received {artifact_uid!r}") + return self._get( + f"/agent/artifacts/{artifact_uid}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AgentGetArtifactResponse, + ) + def run( self, *, @@ -211,6 +259,10 @@ def runs(self) -> AsyncRunsResource: def schedules(self) -> AsyncSchedulesResource: return AsyncSchedulesResource(self._client) + @cached_property + def sessions(self) -> AsyncSessionsResource: + return AsyncSessionsResource(self._client) + @cached_property def with_raw_response(self) -> AsyncAgentResourceWithRawResponse: """ @@ -286,6 +338,41 @@ async def list( cast_to=AgentListResponse, ) + async def get_artifact( + self, + artifact_uid: 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, + ) -> AgentGetArtifactResponse: + """Retrieve an artifact by its UUID. + + For screenshot artifacts, returns a + time-limited signed download URL. + + 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 artifact_uid: + raise ValueError(f"Expected a non-empty value for `artifact_uid` but received {artifact_uid!r}") + return await self._get( + f"/agent/artifacts/{artifact_uid}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AgentGetArtifactResponse, + ) + async def run( self, *, @@ -369,6 +456,9 @@ def __init__(self, agent: AgentResource) -> None: self.list = to_raw_response_wrapper( agent.list, ) + self.get_artifact = to_raw_response_wrapper( + agent.get_artifact, + ) self.run = to_raw_response_wrapper( agent.run, ) @@ -381,6 +471,10 @@ def runs(self) -> RunsResourceWithRawResponse: def schedules(self) -> SchedulesResourceWithRawResponse: return SchedulesResourceWithRawResponse(self._agent.schedules) + @cached_property + def sessions(self) -> SessionsResourceWithRawResponse: + return SessionsResourceWithRawResponse(self._agent.sessions) + class AsyncAgentResourceWithRawResponse: def __init__(self, agent: AsyncAgentResource) -> None: @@ -389,6 +483,9 @@ def __init__(self, agent: AsyncAgentResource) -> None: self.list = async_to_raw_response_wrapper( agent.list, ) + self.get_artifact = async_to_raw_response_wrapper( + agent.get_artifact, + ) self.run = async_to_raw_response_wrapper( agent.run, ) @@ -401,6 +498,10 @@ def runs(self) -> AsyncRunsResourceWithRawResponse: def schedules(self) -> AsyncSchedulesResourceWithRawResponse: return AsyncSchedulesResourceWithRawResponse(self._agent.schedules) + @cached_property + def sessions(self) -> AsyncSessionsResourceWithRawResponse: + return AsyncSessionsResourceWithRawResponse(self._agent.sessions) + class AgentResourceWithStreamingResponse: def __init__(self, agent: AgentResource) -> None: @@ -409,6 +510,9 @@ def __init__(self, agent: AgentResource) -> None: self.list = to_streamed_response_wrapper( agent.list, ) + self.get_artifact = to_streamed_response_wrapper( + agent.get_artifact, + ) self.run = to_streamed_response_wrapper( agent.run, ) @@ -421,6 +525,10 @@ def runs(self) -> RunsResourceWithStreamingResponse: def schedules(self) -> SchedulesResourceWithStreamingResponse: return SchedulesResourceWithStreamingResponse(self._agent.schedules) + @cached_property + def sessions(self) -> SessionsResourceWithStreamingResponse: + return SessionsResourceWithStreamingResponse(self._agent.sessions) + class AsyncAgentResourceWithStreamingResponse: def __init__(self, agent: AsyncAgentResource) -> None: @@ -429,6 +537,9 @@ def __init__(self, agent: AsyncAgentResource) -> None: self.list = async_to_streamed_response_wrapper( agent.list, ) + self.get_artifact = async_to_streamed_response_wrapper( + agent.get_artifact, + ) self.run = async_to_streamed_response_wrapper( agent.run, ) @@ -440,3 +551,7 @@ def runs(self) -> AsyncRunsResourceWithStreamingResponse: @cached_property def schedules(self) -> AsyncSchedulesResourceWithStreamingResponse: return AsyncSchedulesResourceWithStreamingResponse(self._agent.schedules) + + @cached_property + def sessions(self) -> AsyncSessionsResourceWithStreamingResponse: + return AsyncSessionsResourceWithStreamingResponse(self._agent.sessions) diff --git a/src/oz_agent_sdk/resources/agent/sessions.py b/src/oz_agent_sdk/resources/agent/sessions.py new file mode 100644 index 0000000..a441a3e --- /dev/null +++ b/src/oz_agent_sdk/resources/agent/sessions.py @@ -0,0 +1,167 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ..._types import Body, Query, Headers, NotGiven, not_given +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.agent.session_check_redirect_response import SessionCheckRedirectResponse + +__all__ = ["SessionsResource", "AsyncSessionsResource"] + + +class SessionsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> SessionsResourceWithRawResponse: + """ + 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/warpdotdev/oz-sdk-python#accessing-raw-response-data-eg-headers + """ + return SessionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> SessionsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/warpdotdev/oz-sdk-python#with_streaming_response + """ + return SessionsResourceWithStreamingResponse(self) + + def check_redirect( + self, + session_uuid: 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, + ) -> SessionCheckRedirectResponse: + """ + Check whether a shared session should redirect to a conversation transcript. + Returns a conversation_id if the agent sandbox has finished and conversation + data is available, or an empty object if no redirect is needed. + + 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 session_uuid: + raise ValueError(f"Expected a non-empty value for `session_uuid` but received {session_uuid!r}") + return self._get( + f"/agent/sessions/{session_uuid}/redirect", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SessionCheckRedirectResponse, + ) + + +class AsyncSessionsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncSessionsResourceWithRawResponse: + """ + 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/warpdotdev/oz-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncSessionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSessionsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/warpdotdev/oz-sdk-python#with_streaming_response + """ + return AsyncSessionsResourceWithStreamingResponse(self) + + async def check_redirect( + self, + session_uuid: 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, + ) -> SessionCheckRedirectResponse: + """ + Check whether a shared session should redirect to a conversation transcript. + Returns a conversation_id if the agent sandbox has finished and conversation + data is available, or an empty object if no redirect is needed. + + 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 session_uuid: + raise ValueError(f"Expected a non-empty value for `session_uuid` but received {session_uuid!r}") + return await self._get( + f"/agent/sessions/{session_uuid}/redirect", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SessionCheckRedirectResponse, + ) + + +class SessionsResourceWithRawResponse: + def __init__(self, sessions: SessionsResource) -> None: + self._sessions = sessions + + self.check_redirect = to_raw_response_wrapper( + sessions.check_redirect, + ) + + +class AsyncSessionsResourceWithRawResponse: + def __init__(self, sessions: AsyncSessionsResource) -> None: + self._sessions = sessions + + self.check_redirect = async_to_raw_response_wrapper( + sessions.check_redirect, + ) + + +class SessionsResourceWithStreamingResponse: + def __init__(self, sessions: SessionsResource) -> None: + self._sessions = sessions + + self.check_redirect = to_streamed_response_wrapper( + sessions.check_redirect, + ) + + +class AsyncSessionsResourceWithStreamingResponse: + def __init__(self, sessions: AsyncSessionsResource) -> None: + self._sessions = sessions + + self.check_redirect = async_to_streamed_response_wrapper( + sessions.check_redirect, + ) diff --git a/src/oz_agent_sdk/types/__init__.py b/src/oz_agent_sdk/types/__init__.py index a69bb94..829402d 100644 --- a/src/oz_agent_sdk/types/__init__.py +++ b/src/oz_agent_sdk/types/__init__.py @@ -13,3 +13,4 @@ from .mcp_server_config_param import McpServerConfigParam as McpServerConfigParam from .cloud_environment_config import CloudEnvironmentConfig as CloudEnvironmentConfig from .ambient_agent_config_param import AmbientAgentConfigParam as AmbientAgentConfigParam +from .agent_get_artifact_response import AgentGetArtifactResponse as AgentGetArtifactResponse diff --git a/src/oz_agent_sdk/types/agent/__init__.py b/src/oz_agent_sdk/types/agent/__init__.py index 9aad9f6..87712e7 100644 --- a/src/oz_agent_sdk/types/agent/__init__.py +++ b/src/oz_agent_sdk/types/agent/__init__.py @@ -14,3 +14,4 @@ from .schedule_list_response import ScheduleListResponse as ScheduleListResponse from .schedule_update_params import ScheduleUpdateParams as ScheduleUpdateParams from .schedule_delete_response import ScheduleDeleteResponse as ScheduleDeleteResponse +from .session_check_redirect_response import SessionCheckRedirectResponse as SessionCheckRedirectResponse diff --git a/src/oz_agent_sdk/types/agent/session_check_redirect_response.py b/src/oz_agent_sdk/types/agent/session_check_redirect_response.py new file mode 100644 index 0000000..9a287fc --- /dev/null +++ b/src/oz_agent_sdk/types/agent/session_check_redirect_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ..._models import BaseModel + +__all__ = ["SessionCheckRedirectResponse"] + + +class SessionCheckRedirectResponse(BaseModel): + conversation_id: Optional[str] = None + """The conversation ID to redirect to (only present when redirect is needed)""" diff --git a/src/oz_agent_sdk/types/agent_get_artifact_response.py b/src/oz_agent_sdk/types/agent_get_artifact_response.py new file mode 100644 index 0000000..277baf3 --- /dev/null +++ b/src/oz_agent_sdk/types/agent_get_artifact_response.py @@ -0,0 +1,40 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from .._models import BaseModel + +__all__ = ["AgentGetArtifactResponse", "Data"] + + +class Data(BaseModel): + """Response data for a screenshot artifact, including a signed download URL.""" + + content_type: str + """MIME type of the screenshot (e.g., image/png)""" + + download_url: str + """Time-limited signed URL to download the screenshot""" + + expires_at: datetime + """Timestamp when the download URL expires (RFC3339)""" + + description: Optional[str] = None + """Optional description of the screenshot""" + + +class AgentGetArtifactResponse(BaseModel): + """Response for artifact retrieval. Currently supports screenshot artifacts.""" + + artifact_type: str + """Type of the artifact (e.g., SCREENSHOT)""" + + artifact_uid: str + """Unique identifier (UUID) for the artifact""" + + created_at: datetime + """Timestamp when the artifact was created (RFC3339)""" + + data: Data + """Response data for a screenshot artifact, including a signed download URL.""" diff --git a/tests/api_resources/agent/test_sessions.py b/tests/api_resources/agent/test_sessions.py new file mode 100644 index 0000000..5b344ac --- /dev/null +++ b/tests/api_resources/agent/test_sessions.py @@ -0,0 +1,108 @@ +# 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 tests.utils import assert_matches_type +from oz_agent_sdk import OzAPI, AsyncOzAPI +from oz_agent_sdk.types.agent import SessionCheckRedirectResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestSessions: + 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_check_redirect(self, client: OzAPI) -> None: + session = client.agent.sessions.check_redirect( + "sessionUuid", + ) + assert_matches_type(SessionCheckRedirectResponse, session, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_check_redirect(self, client: OzAPI) -> None: + response = client.agent.sessions.with_raw_response.check_redirect( + "sessionUuid", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + session = response.parse() + assert_matches_type(SessionCheckRedirectResponse, session, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_check_redirect(self, client: OzAPI) -> None: + with client.agent.sessions.with_streaming_response.check_redirect( + "sessionUuid", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + session = response.parse() + assert_matches_type(SessionCheckRedirectResponse, session, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_check_redirect(self, client: OzAPI) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_uuid` but received ''"): + client.agent.sessions.with_raw_response.check_redirect( + "", + ) + + +class TestAsyncSessions: + 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_check_redirect(self, async_client: AsyncOzAPI) -> None: + session = await async_client.agent.sessions.check_redirect( + "sessionUuid", + ) + assert_matches_type(SessionCheckRedirectResponse, session, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_check_redirect(self, async_client: AsyncOzAPI) -> None: + response = await async_client.agent.sessions.with_raw_response.check_redirect( + "sessionUuid", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + session = await response.parse() + assert_matches_type(SessionCheckRedirectResponse, session, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_check_redirect(self, async_client: AsyncOzAPI) -> None: + async with async_client.agent.sessions.with_streaming_response.check_redirect( + "sessionUuid", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + session = await response.parse() + assert_matches_type(SessionCheckRedirectResponse, session, 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_check_redirect(self, async_client: AsyncOzAPI) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_uuid` but received ''"): + await async_client.agent.sessions.with_raw_response.check_redirect( + "", + ) diff --git a/tests/api_resources/test_agent.py b/tests/api_resources/test_agent.py index 5a71190..63591c6 100644 --- a/tests/api_resources/test_agent.py +++ b/tests/api_resources/test_agent.py @@ -12,6 +12,7 @@ from oz_agent_sdk.types import ( AgentRunResponse, AgentListResponse, + AgentGetArtifactResponse, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -58,6 +59,48 @@ def test_streaming_response_list(self, client: OzAPI) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_artifact(self, client: OzAPI) -> None: + agent = client.agent.get_artifact( + "artifactUid", + ) + assert_matches_type(AgentGetArtifactResponse, agent, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_artifact(self, client: OzAPI) -> None: + response = client.agent.with_raw_response.get_artifact( + "artifactUid", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + agent = response.parse() + assert_matches_type(AgentGetArtifactResponse, agent, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_artifact(self, client: OzAPI) -> None: + with client.agent.with_streaming_response.get_artifact( + "artifactUid", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + agent = response.parse() + assert_matches_type(AgentGetArtifactResponse, agent, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_get_artifact(self, client: OzAPI) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `artifact_uid` but received ''"): + client.agent.with_raw_response.get_artifact( + "", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_run(self, client: OzAPI) -> None: @@ -168,6 +211,48 @@ async def test_streaming_response_list(self, async_client: AsyncOzAPI) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_artifact(self, async_client: AsyncOzAPI) -> None: + agent = await async_client.agent.get_artifact( + "artifactUid", + ) + assert_matches_type(AgentGetArtifactResponse, agent, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_artifact(self, async_client: AsyncOzAPI) -> None: + response = await async_client.agent.with_raw_response.get_artifact( + "artifactUid", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + agent = await response.parse() + assert_matches_type(AgentGetArtifactResponse, agent, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_artifact(self, async_client: AsyncOzAPI) -> None: + async with async_client.agent.with_streaming_response.get_artifact( + "artifactUid", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + agent = await response.parse() + assert_matches_type(AgentGetArtifactResponse, agent, 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_get_artifact(self, async_client: AsyncOzAPI) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `artifact_uid` but received ''"): + await async_client.agent.with_raw_response.get_artifact( + "", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_run(self, async_client: AsyncOzAPI) -> None: From 8b296f6a5809a714da2bdd79eedf2b1ea9816843 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 20:39:31 +0000 Subject: [PATCH 4/4] release: 0.7.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 14 ++++++++++++++ pyproject.toml | 2 +- src/oz_agent_sdk/_version.py | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e3778b2..1b77f50 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.6.2" + ".": "0.7.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f54613..b831860 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.7.0 (2026-02-23) + +Full Changelog: [v0.6.2...v0.7.0](https://github.com/warpdotdev/oz-sdk-python/compare/v0.6.2...v0.7.0) + +### Features + +* **api:** manual updates ([1b38e09](https://github.com/warpdotdev/oz-sdk-python/commit/1b38e0943935c83c0283523fc045eb2ff2f56109)) +* **api:** manual updates ([73b719a](https://github.com/warpdotdev/oz-sdk-python/commit/73b719a978f70ae36bd374535d80372dfaf1d47f)) + + +### Chores + +* **internal:** make `test_proxy_environment_variables` more resilient ([de1744e](https://github.com/warpdotdev/oz-sdk-python/commit/de1744eeddf1780ca9bae2690f0ed0b17406754f)) + ## 0.6.2 (2026-02-23) Full Changelog: [v0.6.1...v0.6.2](https://github.com/warpdotdev/oz-sdk-python/compare/v0.6.1...v0.6.2) diff --git a/pyproject.toml b/pyproject.toml index 3a7ec67..7f9d305 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "oz-agent-sdk" -version = "0.6.2" +version = "0.7.0" description = "The official Python library for the oz-api API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/oz_agent_sdk/_version.py b/src/oz_agent_sdk/_version.py index b177fc1..4f7bc92 100644 --- a/src/oz_agent_sdk/_version.py +++ b/src/oz_agent_sdk/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "oz_agent_sdk" -__version__ = "0.6.2" # x-release-please-version +__version__ = "0.7.0" # x-release-please-version