diff --git a/.release-please-manifest.json b/.release-please-manifest.json index da59f99..2aca35a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.4.0" + ".": "0.5.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 7405d06..d6127d4 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-5793d9138ec4b7af85e46c9b3f02baa0caeddcdfdf8b2c2192b26f62348392b9.yml -openapi_spec_hash: 0452abd7cb14486ce786a47a9a62e49b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/warp-bnavetta%2Fwarp-api-c99d72d8d845f1eeabf7a716949a12408df952a2a0ca2b97df570da3a7c8bb49.yml +openapi_spec_hash: 8a503cbccc8a5741554282327a557114 config_hash: 07820b17df23cbea39cb77fa05292538 diff --git a/CHANGELOG.md b/CHANGELOG.md index de2fc6f..bd6186a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.5.0 (2026-02-08) + +Full Changelog: [v0.4.0...v0.5.0](https://github.com/warpdotdev/warp-sdk-python/compare/v0.4.0...v0.5.0) + +### Features + +* **api:** modify openapi trigger ([db2d311](https://github.com/warpdotdev/warp-sdk-python/commit/db2d3116a353cc7a5b552e09769372264f6353b8)) + ## 0.4.0 (2026-02-06) Full Changelog: [v0.3.0...v0.4.0](https://github.com/warpdotdev/warp-sdk-python/compare/v0.3.0...v0.4.0) diff --git a/README.md b/README.md index 22c4697..62b1c60 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,6 @@ from warp_agent_sdk import WarpAPI client = WarpAPI() response = client.agent.run( - prompt="Fix the bug in auth.go", config={}, ) print(response.config) diff --git a/pyproject.toml b/pyproject.toml index 1f0ef39..8be071c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "warp-agent-sdk" -version = "0.4.0" +version = "0.5.0" description = "The official Python library for the warp-api API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/warp_agent_sdk/_version.py b/src/warp_agent_sdk/_version.py index 62e4ed0..17870c5 100644 --- a/src/warp_agent_sdk/_version.py +++ b/src/warp_agent_sdk/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "warp_agent_sdk" -__version__ = "0.4.0" # x-release-please-version +__version__ = "0.5.0" # x-release-please-version diff --git a/src/warp_agent_sdk/resources/agent/agent.py b/src/warp_agent_sdk/resources/agent/agent.py index 52ba8f8..70d325b 100644 --- a/src/warp_agent_sdk/resources/agent/agent.py +++ b/src/warp_agent_sdk/resources/agent/agent.py @@ -2,6 +2,9 @@ from __future__ import annotations +from typing import Iterable +from typing_extensions import Literal + import httpx from .runs import ( @@ -70,7 +73,9 @@ def with_streaming_response(self) -> AgentResourceWithStreamingResponse: def list( self, *, + refresh: bool | Omit = omit, repo: str | Omit = omit, + sort_by: Literal["name", "last_run"] | 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, @@ -83,9 +88,17 @@ def list( Agents are discovered from environments or a specific repository. Args: + refresh: When true, clears the agent list cache before fetching. Use this to force a + refresh of the available agents. + repo: Optional repository specification to list agents from (format: "owner/repo"). If not provided, lists agents from all accessible environments. + sort_by: Sort order for the returned agents. + + - "name": Sort alphabetically by name (default) + - "last_run": Sort by most recently used + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -101,7 +114,14 @@ def list( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"repo": repo}, agent_list_params.AgentListParams), + query=maybe_transform( + { + "refresh": refresh, + "repo": repo, + "sort_by": sort_by, + }, + agent_list_params.AgentListParams, + ), ), cast_to=AgentListResponse, ) @@ -109,8 +129,11 @@ def list( def run( self, *, - prompt: str, 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, title: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -120,17 +143,33 @@ def run( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AgentRunResponse: - """Spawn an ambient agent with a prompt and optional configuration. + """Spawn an cloud agent with a prompt and optional configuration. - The agent will - be queued for execution and assigned a unique run ID. + The agent will be + queued for execution and assigned a unique run ID. Args: - prompt: The prompt/instruction for the agent to execute + config: Configuration for an 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. - config: Configuration for an ambient agent run + images: Optional images to include with the prompt (max 5). Images are uploaded to cloud + storage and made available to the agent. - team: Make the run visible to all team members, not only the calling user + prompt: The prompt/instruction for the agent to execute. Required unless a skill is + specified via the skill field or config.skill_spec. + + skill: + Skill specification to use as the base prompt for the agent. Supported formats: + + - "repo:skill_name" - Simple name in specific repo + - "repo:skill_path" - Full path in specific repo + - "org/repo:skill_name" - Simple name with org and repo + - "org/repo:skill_path" - Full path with org and repo When provided, this takes + precedence over config.skill_spec. + + team: Whether to create a team-owned run. Defaults to true for users on a single team. title: Custom title for the run (auto-generated if not provided) @@ -146,8 +185,11 @@ def run( "/agent/run", body=maybe_transform( { - "prompt": prompt, "config": config, + "conversation_id": conversation_id, + "images": images, + "prompt": prompt, + "skill": skill, "team": team, "title": title, }, @@ -191,7 +233,9 @@ def with_streaming_response(self) -> AsyncAgentResourceWithStreamingResponse: async def list( self, *, + refresh: bool | Omit = omit, repo: str | Omit = omit, + sort_by: Literal["name", "last_run"] | 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, @@ -204,9 +248,17 @@ async def list( Agents are discovered from environments or a specific repository. Args: + refresh: When true, clears the agent list cache before fetching. Use this to force a + refresh of the available agents. + repo: Optional repository specification to list agents from (format: "owner/repo"). If not provided, lists agents from all accessible environments. + sort_by: Sort order for the returned agents. + + - "name": Sort alphabetically by name (default) + - "last_run": Sort by most recently used + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -222,7 +274,14 @@ async def list( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform({"repo": repo}, agent_list_params.AgentListParams), + query=await async_maybe_transform( + { + "refresh": refresh, + "repo": repo, + "sort_by": sort_by, + }, + agent_list_params.AgentListParams, + ), ), cast_to=AgentListResponse, ) @@ -230,8 +289,11 @@ async def list( async def run( self, *, - prompt: str, 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, title: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -241,17 +303,33 @@ async def run( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AgentRunResponse: - """Spawn an ambient agent with a prompt and optional configuration. + """Spawn an cloud agent with a prompt and optional configuration. - The agent will - be queued for execution and assigned a unique run ID. + The agent will be + queued for execution and assigned a unique run ID. Args: - prompt: The prompt/instruction for the agent to execute + config: Configuration for an 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. - config: Configuration for an ambient agent run + prompt: The prompt/instruction for the agent to execute. Required unless a skill is + specified via the skill field or config.skill_spec. - team: Make the run visible to all team members, not only the calling user + skill: + Skill specification to use as the base prompt for the agent. Supported formats: + + - "repo:skill_name" - Simple name in specific repo + - "repo:skill_path" - Full path in specific repo + - "org/repo:skill_name" - Simple name with org and repo + - "org/repo:skill_path" - Full path with org and repo When provided, this takes + precedence over config.skill_spec. + + team: Whether to create a team-owned run. Defaults to true for users on a single team. title: Custom title for the run (auto-generated if not provided) @@ -267,8 +345,11 @@ async def run( "/agent/run", body=await async_maybe_transform( { - "prompt": prompt, "config": config, + "conversation_id": conversation_id, + "images": images, + "prompt": prompt, + "skill": skill, "team": team, "title": title, }, diff --git a/src/warp_agent_sdk/resources/agent/runs.py b/src/warp_agent_sdk/resources/agent/runs.py index b50ddfa..9298692 100644 --- a/src/warp_agent_sdk/resources/agent/runs.py +++ b/src/warp_agent_sdk/resources/agent/runs.py @@ -4,6 +4,7 @@ from typing import List, Union from datetime import datetime +from typing_extensions import Literal import httpx @@ -84,7 +85,7 @@ def retrieve( def list( self, *, - config_name: str | Omit = omit, + artifact_type: Literal["PLAN", "PULL_REQUEST"] | Omit = omit, created_after: Union[str, datetime] | Omit = omit, created_before: Union[str, datetime] | Omit = omit, creator: str | Omit = omit, @@ -92,7 +93,10 @@ def list( environment_id: str | Omit = omit, limit: int | Omit = omit, model_id: str | Omit = omit, + name: str | Omit = omit, + q: str | Omit = omit, schedule_id: str | Omit = omit, + skill: str | Omit = omit, skill_spec: str | Omit = omit, source: RunSourceType | Omit = omit, state: List[RunState] | Omit = omit, @@ -110,7 +114,7 @@ def list( ordered by creation time (newest first). Args: - config_name: Filter by agent config name + artifact_type: Filter runs by artifact type (PLAN or PULL_REQUEST) created_after: Filter runs created after this timestamp (RFC3339 format) @@ -126,8 +130,15 @@ def list( model_id: Filter by model ID + name: Filter by agent config name + + q: Fuzzy search query across run title, prompt, and skill_spec + schedule_id: Filter runs by the scheduled agent ID that created them + skill: Filter runs by skill spec (e.g., "owner/repo:path/to/SKILL.md"). Alias for + skill_spec. + skill_spec: Filter runs by skill spec (e.g., "owner/repo:path/to/SKILL.md") source: Filter by run source type @@ -154,7 +165,7 @@ def list( timeout=timeout, query=maybe_transform( { - "config_name": config_name, + "artifact_type": artifact_type, "created_after": created_after, "created_before": created_before, "creator": creator, @@ -162,7 +173,10 @@ def list( "environment_id": environment_id, "limit": limit, "model_id": model_id, + "name": name, + "q": q, "schedule_id": schedule_id, + "skill": skill, "skill_spec": skill_spec, "source": source, "state": state, @@ -267,7 +281,7 @@ async def retrieve( async def list( self, *, - config_name: str | Omit = omit, + artifact_type: Literal["PLAN", "PULL_REQUEST"] | Omit = omit, created_after: Union[str, datetime] | Omit = omit, created_before: Union[str, datetime] | Omit = omit, creator: str | Omit = omit, @@ -275,7 +289,10 @@ async def list( environment_id: str | Omit = omit, limit: int | Omit = omit, model_id: str | Omit = omit, + name: str | Omit = omit, + q: str | Omit = omit, schedule_id: str | Omit = omit, + skill: str | Omit = omit, skill_spec: str | Omit = omit, source: RunSourceType | Omit = omit, state: List[RunState] | Omit = omit, @@ -293,7 +310,7 @@ async def list( ordered by creation time (newest first). Args: - config_name: Filter by agent config name + artifact_type: Filter runs by artifact type (PLAN or PULL_REQUEST) created_after: Filter runs created after this timestamp (RFC3339 format) @@ -309,8 +326,15 @@ async def list( model_id: Filter by model ID + name: Filter by agent config name + + q: Fuzzy search query across run title, prompt, and skill_spec + schedule_id: Filter runs by the scheduled agent ID that created them + skill: Filter runs by skill spec (e.g., "owner/repo:path/to/SKILL.md"). Alias for + skill_spec. + skill_spec: Filter runs by skill spec (e.g., "owner/repo:path/to/SKILL.md") source: Filter by run source type @@ -337,7 +361,7 @@ async def list( timeout=timeout, query=await async_maybe_transform( { - "config_name": config_name, + "artifact_type": artifact_type, "created_after": created_after, "created_before": created_before, "creator": creator, @@ -345,7 +369,10 @@ async def list( "environment_id": environment_id, "limit": limit, "model_id": model_id, + "name": name, + "q": q, "schedule_id": schedule_id, + "skill": skill, "skill_spec": skill_spec, "source": source, "state": state, diff --git a/src/warp_agent_sdk/resources/agent/schedules.py b/src/warp_agent_sdk/resources/agent/schedules.py index 6237dde..0f825f8 100644 --- a/src/warp_agent_sdk/resources/agent/schedules.py +++ b/src/warp_agent_sdk/resources/agent/schedules.py @@ -73,7 +73,7 @@ def create( prompt: The prompt/instruction for the agent to execute - agent_config: Configuration for an ambient agent run + agent_config: Configuration for an cloud agent run enabled: Whether the schedule should be active immediately @@ -171,7 +171,7 @@ def update( prompt: The prompt/instruction for the agent to execute - agent_config: Configuration for an ambient agent run + agent_config: Configuration for an cloud agent run extra_headers: Send extra headers @@ -378,7 +378,7 @@ async def create( prompt: The prompt/instruction for the agent to execute - agent_config: Configuration for an ambient agent run + agent_config: Configuration for an cloud agent run enabled: Whether the schedule should be active immediately @@ -476,7 +476,7 @@ async def update( prompt: The prompt/instruction for the agent to execute - agent_config: Configuration for an ambient agent run + agent_config: Configuration for an cloud agent run extra_headers: Send extra headers diff --git a/src/warp_agent_sdk/types/agent/run_item.py b/src/warp_agent_sdk/types/agent/run_item.py index d00a5f9..8befd28 100644 --- a/src/warp_agent_sdk/types/agent/run_item.py +++ b/src/warp_agent_sdk/types/agent/run_item.py @@ -2,6 +2,7 @@ from typing import List, Optional from datetime import datetime +from typing_extensions import Literal from ..._models import BaseModel from .run_state import RunState @@ -10,7 +11,26 @@ from .run_source_type import RunSourceType from ..ambient_agent_config import AmbientAgentConfig -__all__ = ["RunItem", "RequestUsage", "Schedule", "StatusMessage"] +__all__ = ["RunItem", "AgentSkill", "RequestUsage", "Schedule", "Scope", "StatusMessage"] + + +class AgentSkill(BaseModel): + """ + Information about the agent skill used for the run. + Either full_path or bundled_skill_id will be set, but not both. + """ + + bundled_skill_id: Optional[str] = None + """Unique identifier for bundled skills""" + + description: Optional[str] = None + """Description of the skill""" + + full_path: Optional[str] = None + """Path to the SKILL.md file (for file-based skills)""" + + name: Optional[str] = None + """Human-readable name of the skill""" class RequestUsage(BaseModel): @@ -38,6 +58,16 @@ class Schedule(BaseModel): """Name of the schedule at the time the run was created""" +class Scope(BaseModel): + """Ownership scope for a resource (team or personal)""" + + type: Literal["User", "Team"] + """Type of ownership ("User" for personal, "Team" for team-owned)""" + + uid: Optional[str] = None + """UID of the owning user or team""" + + class StatusMessage(BaseModel): message: Optional[str] = None """Human-readable status message""" @@ -78,7 +108,13 @@ class RunItem(BaseModel): """Timestamp when the run was last updated (RFC3339)""" agent_config: Optional[AmbientAgentConfig] = None - """Configuration for an ambient agent run""" + """Configuration for an cloud agent run""" + + agent_skill: Optional[AgentSkill] = None + """ + Information about the agent skill used for the run. Either full_path or + bundled_skill_id will be set, but not both. + """ artifacts: Optional[List[ArtifactItem]] = None """Artifacts created during the run (plans, pull requests, etc.)""" @@ -100,6 +136,9 @@ class RunItem(BaseModel): scheduled runs) """ + scope: Optional[Scope] = None + """Ownership scope for a resource (team or personal)""" + session_id: Optional[str] = None """UUID of the shared session (if available)""" diff --git a/src/warp_agent_sdk/types/agent/run_list_params.py b/src/warp_agent_sdk/types/agent/run_list_params.py index c1e9ffd..6aac8c4 100644 --- a/src/warp_agent_sdk/types/agent/run_list_params.py +++ b/src/warp_agent_sdk/types/agent/run_list_params.py @@ -4,7 +4,7 @@ from typing import List, Union from datetime import datetime -from typing_extensions import Annotated, TypedDict +from typing_extensions import Literal, Annotated, TypedDict from ..._utils import PropertyInfo from .run_state import RunState @@ -14,8 +14,8 @@ class RunListParams(TypedDict, total=False): - config_name: str - """Filter by agent config name""" + artifact_type: Literal["PLAN", "PULL_REQUEST"] + """Filter runs by artifact type (PLAN or PULL_REQUEST)""" created_after: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] """Filter runs created after this timestamp (RFC3339 format)""" @@ -38,9 +38,21 @@ class RunListParams(TypedDict, total=False): model_id: str """Filter by model ID""" + name: str + """Filter by agent config name""" + + q: str + """Fuzzy search query across run title, prompt, and skill_spec""" + schedule_id: str """Filter runs by the scheduled agent ID that created them""" + skill: str + """ + Filter runs by skill spec (e.g., "owner/repo:path/to/SKILL.md"). Alias for + skill_spec. + """ + skill_spec: str """Filter runs by skill spec (e.g., "owner/repo:path/to/SKILL.md")""" diff --git a/src/warp_agent_sdk/types/agent/schedule_create_params.py b/src/warp_agent_sdk/types/agent/schedule_create_params.py index 0c3a5d6..2c6a8c2 100644 --- a/src/warp_agent_sdk/types/agent/schedule_create_params.py +++ b/src/warp_agent_sdk/types/agent/schedule_create_params.py @@ -23,7 +23,7 @@ class ScheduleCreateParams(TypedDict, total=False): """The prompt/instruction for the agent to execute""" agent_config: AmbientAgentConfigParam - """Configuration for an ambient agent run""" + """Configuration for an cloud agent run""" enabled: bool """Whether the schedule should be active immediately""" diff --git a/src/warp_agent_sdk/types/agent/schedule_update_params.py b/src/warp_agent_sdk/types/agent/schedule_update_params.py index 111463b..7408ab1 100644 --- a/src/warp_agent_sdk/types/agent/schedule_update_params.py +++ b/src/warp_agent_sdk/types/agent/schedule_update_params.py @@ -23,4 +23,4 @@ class ScheduleUpdateParams(TypedDict, total=False): """The prompt/instruction for the agent to execute""" agent_config: AmbientAgentConfigParam - """Configuration for an ambient agent run""" + """Configuration for an cloud agent run""" diff --git a/src/warp_agent_sdk/types/agent/scheduled_agent_item.py b/src/warp_agent_sdk/types/agent/scheduled_agent_item.py index 141ea42..8de40ef 100644 --- a/src/warp_agent_sdk/types/agent/scheduled_agent_item.py +++ b/src/warp_agent_sdk/types/agent/scheduled_agent_item.py @@ -2,13 +2,14 @@ from typing import Optional from datetime import datetime +from typing_extensions import Literal from ..._models import BaseModel from ..user_profile import UserProfile from ..ambient_agent_config import AmbientAgentConfig from ..cloud_environment_config import CloudEnvironmentConfig -__all__ = ["ScheduledAgentItem", "History"] +__all__ = ["ScheduledAgentItem", "History", "Scope"] class History(BaseModel): @@ -21,6 +22,16 @@ class History(BaseModel): """Timestamp of the next scheduled run (RFC3339)""" +class Scope(BaseModel): + """Ownership scope for a resource (team or personal)""" + + type: Literal["User", "Team"] + """Type of ownership ("User" for personal, "Team" for team-owned)""" + + uid: Optional[str] = None + """UID of the owning user or team""" + + class ScheduledAgentItem(BaseModel): id: str """Unique identifier for the scheduled agent""" @@ -47,7 +58,7 @@ class ScheduledAgentItem(BaseModel): """Timestamp when the schedule was last updated (RFC3339)""" agent_config: Optional[AmbientAgentConfig] = None - """Configuration for an ambient agent run""" + """Configuration for an cloud agent run""" created_by: Optional[UserProfile] = None @@ -60,4 +71,7 @@ class ScheduledAgentItem(BaseModel): last_spawn_error: Optional[str] = None """Error message from the last failed spawn attempt, if any""" + scope: Optional[Scope] = None + """Ownership scope for a resource (team or personal)""" + updated_by: Optional[UserProfile] = None diff --git a/src/warp_agent_sdk/types/agent_list_params.py b/src/warp_agent_sdk/types/agent_list_params.py index 75ffda7..21781ff 100644 --- a/src/warp_agent_sdk/types/agent_list_params.py +++ b/src/warp_agent_sdk/types/agent_list_params.py @@ -2,14 +2,27 @@ from __future__ import annotations -from typing_extensions import TypedDict +from typing_extensions import Literal, TypedDict __all__ = ["AgentListParams"] class AgentListParams(TypedDict, total=False): + refresh: bool + """ + When true, clears the agent list cache before fetching. Use this to force a + refresh of the available agents. + """ + repo: str """ Optional repository specification to list agents from (format: "owner/repo"). If not provided, lists agents from all accessible environments. """ + + sort_by: Literal["name", "last_run"] + """Sort order for the returned agents. + + - "name": Sort alphabetically by name (default) + - "last_run": Sort by most recently used + """ diff --git a/src/warp_agent_sdk/types/agent_run_params.py b/src/warp_agent_sdk/types/agent_run_params.py index 3761f66..80a714b 100644 --- a/src/warp_agent_sdk/types/agent_run_params.py +++ b/src/warp_agent_sdk/types/agent_run_params.py @@ -2,22 +2,69 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing import Union, Iterable +from typing_extensions import Literal, 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"] +__all__ = ["AgentRunParams", "Image"] class AgentRunParams(TypedDict, total=False): - prompt: Required[str] - """The prompt/instruction for the agent to execute""" - config: AmbientAgentConfigParam - """Configuration for an ambient agent run""" + """Configuration for an cloud agent run""" + + conversation_id: str + """ + Optional conversation ID to continue an existing conversation. If provided, the + 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 + specified via the skill field or config.skill_spec. + """ + + skill: str + """Skill specification to use as the base prompt for the agent. Supported formats: + + - "repo:skill_name" - Simple name in specific repo + - "repo:skill_path" - Full path in specific repo + - "org/repo:skill_name" - Simple name with org and repo + - "org/repo:skill_path" - Full path with org and repo When provided, this takes + precedence over config.skill_spec. + """ team: bool - """Make the run visible to all team members, not only the calling user""" + """ + Whether to create a team-owned run. Defaults to true for users on a single team. + """ title: str """Custom title for the run (auto-generated if not provided)""" + + +class Image(TypedDict, total=False): + """A base64-encoded image to include with the prompt""" + + data: Required[Annotated[Union[str, Base64FileInput], PropertyInfo(format="base64")]] + """Base64-encoded image data""" + + mime_type: Required[Literal["image/jpeg", "image/png", "image/gif", "image/webp"]] + """ + MIME type of the image. Supported types: image/jpeg, image/png, image/gif, + image/webp + """ + + +set_pydantic_config(Image, {"arbitrary_types_allowed": True}) diff --git a/src/warp_agent_sdk/types/agent_run_response.py b/src/warp_agent_sdk/types/agent_run_response.py index 0013e37..bef3a36 100644 --- a/src/warp_agent_sdk/types/agent_run_response.py +++ b/src/warp_agent_sdk/types/agent_run_response.py @@ -21,3 +21,9 @@ class AgentRunResponse(BaseModel): - FAILED: Run failed - CANCELLED: Run was cancelled by user """ + + task_id: str + """Unique identifier for the task (same as run_id). + + Deprecated - use run_id instead. + """ diff --git a/src/warp_agent_sdk/types/agent_skill.py b/src/warp_agent_sdk/types/agent_skill.py index a7ff256..0f2c937 100644 --- a/src/warp_agent_sdk/types/agent_skill.py +++ b/src/warp_agent_sdk/types/agent_skill.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List +from typing import List, Optional +from datetime import datetime from .._models import BaseModel @@ -44,6 +45,9 @@ class Variant(BaseModel): source: VariantSource + last_run_timestamp: Optional[datetime] = None + """Timestamp of the last time this skill was run (RFC3339)""" + class AgentSkill(BaseModel): name: str diff --git a/src/warp_agent_sdk/types/ambient_agent_config.py b/src/warp_agent_sdk/types/ambient_agent_config.py index d8a941e..add389f 100644 --- a/src/warp_agent_sdk/types/ambient_agent_config.py +++ b/src/warp_agent_sdk/types/ambient_agent_config.py @@ -11,7 +11,7 @@ class AmbientAgentConfig(BaseModel): - """Configuration for an ambient agent run""" + """Configuration for an cloud agent run""" base_prompt: Optional[str] = None """Custom base prompt for the agent""" diff --git a/src/warp_agent_sdk/types/ambient_agent_config_param.py b/src/warp_agent_sdk/types/ambient_agent_config_param.py index 1441a8a..bf55e89 100644 --- a/src/warp_agent_sdk/types/ambient_agent_config_param.py +++ b/src/warp_agent_sdk/types/ambient_agent_config_param.py @@ -11,7 +11,7 @@ class AmbientAgentConfigParam(TypedDict, total=False): - """Configuration for an ambient agent run""" + """Configuration for an cloud agent run""" base_prompt: str """Custom base prompt for the agent""" diff --git a/tests/api_resources/agent/test_runs.py b/tests/api_resources/agent/test_runs.py index 2da4d4a..40cdbc0 100644 --- a/tests/api_resources/agent/test_runs.py +++ b/tests/api_resources/agent/test_runs.py @@ -70,7 +70,7 @@ def test_method_list(self, client: WarpAPI) -> None: @parametrize def test_method_list_with_all_params(self, client: WarpAPI) -> None: run = client.agent.runs.list( - config_name="config_name", + artifact_type="PLAN", created_after=parse_datetime("2019-12-27T18:11:19.117Z"), created_before=parse_datetime("2019-12-27T18:11:19.117Z"), creator="creator", @@ -78,7 +78,10 @@ def test_method_list_with_all_params(self, client: WarpAPI) -> None: environment_id="environment_id", limit=1, model_id="model_id", + name="name", + q="q", schedule_id="schedule_id", + skill="skill", skill_spec="skill_spec", source="LINEAR", state=["QUEUED"], @@ -208,7 +211,7 @@ async def test_method_list(self, async_client: AsyncWarpAPI) -> None: @parametrize async def test_method_list_with_all_params(self, async_client: AsyncWarpAPI) -> None: run = await async_client.agent.runs.list( - config_name="config_name", + artifact_type="PLAN", created_after=parse_datetime("2019-12-27T18:11:19.117Z"), created_before=parse_datetime("2019-12-27T18:11:19.117Z"), creator="creator", @@ -216,7 +219,10 @@ async def test_method_list_with_all_params(self, async_client: AsyncWarpAPI) -> environment_id="environment_id", limit=1, model_id="model_id", + name="name", + q="q", schedule_id="schedule_id", + skill="skill", skill_spec="skill_spec", source="LINEAR", state=["QUEUED"], diff --git a/tests/api_resources/test_agent.py b/tests/api_resources/test_agent.py index 3a7e7f6..8a53617 100644 --- a/tests/api_resources/test_agent.py +++ b/tests/api_resources/test_agent.py @@ -30,7 +30,9 @@ def test_method_list(self, client: WarpAPI) -> None: @parametrize def test_method_list_with_all_params(self, client: WarpAPI) -> None: agent = client.agent.list( + refresh=True, repo="repo", + sort_by="name", ) assert_matches_type(AgentListResponse, agent, path=["response"]) @@ -59,16 +61,13 @@ def test_streaming_response_list(self, client: WarpAPI) -> None: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_method_run(self, client: WarpAPI) -> None: - agent = client.agent.run( - prompt="Fix the bug in auth.go", - ) + agent = client.agent.run() assert_matches_type(AgentRunResponse, agent, path=["response"]) @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_method_run_with_all_params(self, client: WarpAPI) -> None: agent = client.agent.run( - prompt="Fix the bug in auth.go", config={ "base_prompt": "base_prompt", "computer_use_enabled": True, @@ -88,6 +87,15 @@ def test_method_run_with_all_params(self, client: WarpAPI) -> None: "skill_spec": "skill_spec", "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, title="title", ) @@ -96,9 +104,7 @@ def test_method_run_with_all_params(self, client: WarpAPI) -> None: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_raw_response_run(self, client: WarpAPI) -> None: - response = client.agent.with_raw_response.run( - prompt="Fix the bug in auth.go", - ) + response = client.agent.with_raw_response.run() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -108,9 +114,7 @@ def test_raw_response_run(self, client: WarpAPI) -> None: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_streaming_response_run(self, client: WarpAPI) -> None: - with client.agent.with_streaming_response.run( - prompt="Fix the bug in auth.go", - ) as response: + with client.agent.with_streaming_response.run() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -135,7 +139,9 @@ async def test_method_list(self, async_client: AsyncWarpAPI) -> None: @parametrize async def test_method_list_with_all_params(self, async_client: AsyncWarpAPI) -> None: agent = await async_client.agent.list( + refresh=True, repo="repo", + sort_by="name", ) assert_matches_type(AgentListResponse, agent, path=["response"]) @@ -164,16 +170,13 @@ async def test_streaming_response_list(self, async_client: AsyncWarpAPI) -> None @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_method_run(self, async_client: AsyncWarpAPI) -> None: - agent = await async_client.agent.run( - prompt="Fix the bug in auth.go", - ) + agent = await async_client.agent.run() assert_matches_type(AgentRunResponse, agent, path=["response"]) @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_method_run_with_all_params(self, async_client: AsyncWarpAPI) -> None: agent = await async_client.agent.run( - prompt="Fix the bug in auth.go", config={ "base_prompt": "base_prompt", "computer_use_enabled": True, @@ -193,6 +196,15 @@ async def test_method_run_with_all_params(self, async_client: AsyncWarpAPI) -> N "skill_spec": "skill_spec", "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, title="title", ) @@ -201,9 +213,7 @@ async def test_method_run_with_all_params(self, async_client: AsyncWarpAPI) -> N @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_raw_response_run(self, async_client: AsyncWarpAPI) -> None: - response = await async_client.agent.with_raw_response.run( - prompt="Fix the bug in auth.go", - ) + response = await async_client.agent.with_raw_response.run() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -213,9 +223,7 @@ async def test_raw_response_run(self, async_client: AsyncWarpAPI) -> None: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_streaming_response_run(self, async_client: AsyncWarpAPI) -> None: - async with async_client.agent.with_streaming_response.run( - prompt="Fix the bug in auth.go", - ) as response: + async with async_client.agent.with_streaming_response.run() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" diff --git a/tests/test_client.py b/tests/test_client.py index 92ea2da..6713c2c 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -852,7 +852,7 @@ def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, clien respx_mock.post("/agent/run").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - client.agent.with_streaming_response.run(prompt="Fix the bug in auth.go").__enter__() + client.agent.with_streaming_response.run().__enter__() assert _get_open_connections(client) == 0 @@ -862,7 +862,7 @@ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client respx_mock.post("/agent/run").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - client.agent.with_streaming_response.run(prompt="Fix the bug in auth.go").__enter__() + client.agent.with_streaming_response.run().__enter__() assert _get_open_connections(client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @@ -891,7 +891,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/agent/run").mock(side_effect=retry_handler) - response = client.agent.with_raw_response.run(prompt="Fix the bug in auth.go") + response = client.agent.with_raw_response.run() assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -915,9 +915,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/agent/run").mock(side_effect=retry_handler) - response = client.agent.with_raw_response.run( - prompt="Fix the bug in auth.go", extra_headers={"x-stainless-retry-count": Omit()} - ) + response = client.agent.with_raw_response.run(extra_headers={"x-stainless-retry-count": Omit()}) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -940,9 +938,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/agent/run").mock(side_effect=retry_handler) - response = client.agent.with_raw_response.run( - prompt="Fix the bug in auth.go", extra_headers={"x-stainless-retry-count": "42"} - ) + response = client.agent.with_raw_response.run(extra_headers={"x-stainless-retry-count": "42"}) assert response.http_request.headers.get("x-stainless-retry-count") == "42" @@ -1756,7 +1752,7 @@ async def test_retrying_timeout_errors_doesnt_leak( respx_mock.post("/agent/run").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - await async_client.agent.with_streaming_response.run(prompt="Fix the bug in auth.go").__aenter__() + await async_client.agent.with_streaming_response.run().__aenter__() assert _get_open_connections(async_client) == 0 @@ -1766,7 +1762,7 @@ async def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, respx_mock.post("/agent/run").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - await async_client.agent.with_streaming_response.run(prompt="Fix the bug in auth.go").__aenter__() + await async_client.agent.with_streaming_response.run().__aenter__() assert _get_open_connections(async_client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @@ -1795,7 +1791,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/agent/run").mock(side_effect=retry_handler) - response = await client.agent.with_raw_response.run(prompt="Fix the bug in auth.go") + response = await client.agent.with_raw_response.run() assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -1819,9 +1815,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/agent/run").mock(side_effect=retry_handler) - response = await client.agent.with_raw_response.run( - prompt="Fix the bug in auth.go", extra_headers={"x-stainless-retry-count": Omit()} - ) + response = await client.agent.with_raw_response.run(extra_headers={"x-stainless-retry-count": Omit()}) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -1844,9 +1838,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/agent/run").mock(side_effect=retry_handler) - response = await client.agent.with_raw_response.run( - prompt="Fix the bug in auth.go", extra_headers={"x-stainless-retry-count": "42"} - ) + response = await client.agent.with_raw_response.run(extra_headers={"x-stainless-retry-count": "42"}) assert response.http_request.headers.get("x-stainless-retry-count") == "42"