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