diff --git a/.stats.yml b/.stats.yml
index 6de88712..33d57b57 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
-configured_endpoints: 12
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/arcade-ai%2Farcade-engine-2e241e72cb7992ad6ef82cde7a5b013da7773618a4c3e65c4804f49bf1fa9aac.yml
+configured_endpoints: 14
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/arcade-ai%2Farcade-engine-c089b91b0e1c2bc2e6a5bd42454c82a162957011f1d8469c680a82ff05ee9ec9.yml
diff --git a/api.md b/api.md
index 77126cba..1fb480a3 100644
--- a/api.md
+++ b/api.md
@@ -102,5 +102,11 @@ from arcadepy.types import (
UpdateWorkerRequest,
WorkerHealthResponse,
WorkerResponse,
+ WorkerListResponse,
)
```
+
+Methods:
+
+- client.worker.create(\*\*params) -> WorkerResponse
+- client.worker.list() -> WorkerListResponse
diff --git a/src/arcadepy/_client.py b/src/arcadepy/_client.py
index 3bf6f549..4d3ce344 100644
--- a/src/arcadepy/_client.py
+++ b/src/arcadepy/_client.py
@@ -24,7 +24,7 @@
get_async_library,
)
from ._version import __version__
-from .resources import auth, health
+from .resources import auth, health, worker
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
from ._exceptions import ArcadeError, APIStatusError
from ._base_client import (
@@ -43,6 +43,7 @@ class Arcade(SyncAPIClient):
health: health.HealthResource
chat: chat.ChatResource
tools: tools.ToolsResource
+ worker: worker.WorkerResource
with_raw_response: ArcadeWithRawResponse
with_streaming_response: ArcadeWithStreamedResponse
@@ -104,6 +105,7 @@ def __init__(
self.health = health.HealthResource(self)
self.chat = chat.ChatResource(self)
self.tools = tools.ToolsResource(self)
+ self.worker = worker.WorkerResource(self)
self.with_raw_response = ArcadeWithRawResponse(self)
self.with_streaming_response = ArcadeWithStreamedResponse(self)
@@ -217,6 +219,7 @@ class AsyncArcade(AsyncAPIClient):
health: health.AsyncHealthResource
chat: chat.AsyncChatResource
tools: tools.AsyncToolsResource
+ worker: worker.AsyncWorkerResource
with_raw_response: AsyncArcadeWithRawResponse
with_streaming_response: AsyncArcadeWithStreamedResponse
@@ -278,6 +281,7 @@ def __init__(
self.health = health.AsyncHealthResource(self)
self.chat = chat.AsyncChatResource(self)
self.tools = tools.AsyncToolsResource(self)
+ self.worker = worker.AsyncWorkerResource(self)
self.with_raw_response = AsyncArcadeWithRawResponse(self)
self.with_streaming_response = AsyncArcadeWithStreamedResponse(self)
@@ -392,6 +396,7 @@ def __init__(self, client: Arcade) -> None:
self.health = health.HealthResourceWithRawResponse(client.health)
self.chat = chat.ChatResourceWithRawResponse(client.chat)
self.tools = tools.ToolsResourceWithRawResponse(client.tools)
+ self.worker = worker.WorkerResourceWithRawResponse(client.worker)
class AsyncArcadeWithRawResponse:
@@ -400,6 +405,7 @@ def __init__(self, client: AsyncArcade) -> None:
self.health = health.AsyncHealthResourceWithRawResponse(client.health)
self.chat = chat.AsyncChatResourceWithRawResponse(client.chat)
self.tools = tools.AsyncToolsResourceWithRawResponse(client.tools)
+ self.worker = worker.AsyncWorkerResourceWithRawResponse(client.worker)
class ArcadeWithStreamedResponse:
@@ -408,6 +414,7 @@ def __init__(self, client: Arcade) -> None:
self.health = health.HealthResourceWithStreamingResponse(client.health)
self.chat = chat.ChatResourceWithStreamingResponse(client.chat)
self.tools = tools.ToolsResourceWithStreamingResponse(client.tools)
+ self.worker = worker.WorkerResourceWithStreamingResponse(client.worker)
class AsyncArcadeWithStreamedResponse:
@@ -416,6 +423,7 @@ def __init__(self, client: AsyncArcade) -> None:
self.health = health.AsyncHealthResourceWithStreamingResponse(client.health)
self.chat = chat.AsyncChatResourceWithStreamingResponse(client.chat)
self.tools = tools.AsyncToolsResourceWithStreamingResponse(client.tools)
+ self.worker = worker.AsyncWorkerResourceWithStreamingResponse(client.worker)
Client = Arcade
diff --git a/src/arcadepy/resources/__init__.py b/src/arcadepy/resources/__init__.py
index 648d6b2e..2c5b8eef 100644
--- a/src/arcadepy/resources/__init__.py
+++ b/src/arcadepy/resources/__init__.py
@@ -32,6 +32,14 @@
HealthResourceWithStreamingResponse,
AsyncHealthResourceWithStreamingResponse,
)
+from .worker import (
+ WorkerResource,
+ AsyncWorkerResource,
+ WorkerResourceWithRawResponse,
+ AsyncWorkerResourceWithRawResponse,
+ WorkerResourceWithStreamingResponse,
+ AsyncWorkerResourceWithStreamingResponse,
+)
__all__ = [
"AuthResource",
@@ -58,4 +66,10 @@
"AsyncToolsResourceWithRawResponse",
"ToolsResourceWithStreamingResponse",
"AsyncToolsResourceWithStreamingResponse",
+ "WorkerResource",
+ "AsyncWorkerResource",
+ "WorkerResourceWithRawResponse",
+ "AsyncWorkerResourceWithRawResponse",
+ "WorkerResourceWithStreamingResponse",
+ "AsyncWorkerResourceWithStreamingResponse",
]
diff --git a/src/arcadepy/resources/worker.py b/src/arcadepy/resources/worker.py
new file mode 100644
index 00000000..827013d0
--- /dev/null
+++ b/src/arcadepy/resources/worker.py
@@ -0,0 +1,235 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..types import worker_create_params
+from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from .._utils import (
+ maybe_transform,
+ async_maybe_transform,
+)
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.worker_response import WorkerResponse
+from ..types.worker_list_response import WorkerListResponse
+
+__all__ = ["WorkerResource", "AsyncWorkerResource"]
+
+
+class WorkerResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> WorkerResourceWithRawResponse:
+ """
+ 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/ArcadeAI/arcade-py#accessing-raw-response-data-eg-headers
+ """
+ return WorkerResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> WorkerResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/ArcadeAI/arcade-py#with_streaming_response
+ """
+ return WorkerResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ id: str,
+ enabled: bool,
+ http: worker_create_params.HTTP | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> WorkerResponse:
+ """
+ Create a worker
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/v1/admin/workers",
+ body=maybe_transform(
+ {
+ "id": id,
+ "enabled": enabled,
+ "http": http,
+ },
+ worker_create_params.WorkerCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=WorkerResponse,
+ )
+
+ def list(
+ self,
+ *,
+ # 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,
+ ) -> WorkerListResponse:
+ """List all workers with their definitions"""
+ return self._get(
+ "/v1/admin/workers",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=WorkerListResponse,
+ )
+
+
+class AsyncWorkerResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncWorkerResourceWithRawResponse:
+ """
+ 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/ArcadeAI/arcade-py#accessing-raw-response-data-eg-headers
+ """
+ return AsyncWorkerResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncWorkerResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/ArcadeAI/arcade-py#with_streaming_response
+ """
+ return AsyncWorkerResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ id: str,
+ enabled: bool,
+ http: worker_create_params.HTTP | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> WorkerResponse:
+ """
+ Create a worker
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/v1/admin/workers",
+ body=await async_maybe_transform(
+ {
+ "id": id,
+ "enabled": enabled,
+ "http": http,
+ },
+ worker_create_params.WorkerCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=WorkerResponse,
+ )
+
+ async def list(
+ self,
+ *,
+ # 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,
+ ) -> WorkerListResponse:
+ """List all workers with their definitions"""
+ return await self._get(
+ "/v1/admin/workers",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=WorkerListResponse,
+ )
+
+
+class WorkerResourceWithRawResponse:
+ def __init__(self, worker: WorkerResource) -> None:
+ self._worker = worker
+
+ self.create = to_raw_response_wrapper(
+ worker.create,
+ )
+ self.list = to_raw_response_wrapper(
+ worker.list,
+ )
+
+
+class AsyncWorkerResourceWithRawResponse:
+ def __init__(self, worker: AsyncWorkerResource) -> None:
+ self._worker = worker
+
+ self.create = async_to_raw_response_wrapper(
+ worker.create,
+ )
+ self.list = async_to_raw_response_wrapper(
+ worker.list,
+ )
+
+
+class WorkerResourceWithStreamingResponse:
+ def __init__(self, worker: WorkerResource) -> None:
+ self._worker = worker
+
+ self.create = to_streamed_response_wrapper(
+ worker.create,
+ )
+ self.list = to_streamed_response_wrapper(
+ worker.list,
+ )
+
+
+class AsyncWorkerResourceWithStreamingResponse:
+ def __init__(self, worker: AsyncWorkerResource) -> None:
+ self._worker = worker
+
+ self.create = async_to_streamed_response_wrapper(
+ worker.create,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ worker.list,
+ )
diff --git a/src/arcadepy/types/__init__.py b/src/arcadepy/types/__init__.py
index 77e592f3..e01175e0 100644
--- a/src/arcadepy/types/__init__.py
+++ b/src/arcadepy/types/__init__.py
@@ -15,10 +15,13 @@
from .health_schema import HealthSchema as HealthSchema
from .tool_execution import ToolExecution as ToolExecution
from .tool_definition import ToolDefinition as ToolDefinition
+from .worker_response import WorkerResponse as WorkerResponse
from .tool_list_params import ToolListParams as ToolListParams
from .auth_status_params import AuthStatusParams as AuthStatusParams
from .chat_message_param import ChatMessageParam as ChatMessageParam
from .tool_execute_params import ToolExecuteParams as ToolExecuteParams
+from .worker_create_params import WorkerCreateParams as WorkerCreateParams
+from .worker_list_response import WorkerListResponse as WorkerListResponse
from .auth_authorize_params import AuthAuthorizeParams as AuthAuthorizeParams
from .execute_tool_response import ExecuteToolResponse as ExecuteToolResponse
from .tool_authorize_params import ToolAuthorizeParams as ToolAuthorizeParams
diff --git a/src/arcadepy/types/worker_create_params.py b/src/arcadepy/types/worker_create_params.py
new file mode 100644
index 00000000..d08266e3
--- /dev/null
+++ b/src/arcadepy/types/worker_create_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["WorkerCreateParams", "HTTP"]
+
+
+class WorkerCreateParams(TypedDict, total=False):
+ id: Required[str]
+
+ enabled: Required[bool]
+
+ http: HTTP
+
+
+class HTTP(TypedDict, total=False):
+ retry: Required[int]
+
+ secret: Required[str]
+
+ timeout: Required[int]
+
+ uri: Required[str]
diff --git a/src/arcadepy/types/worker_list_response.py b/src/arcadepy/types/worker_list_response.py
new file mode 100644
index 00000000..9a7b24c5
--- /dev/null
+++ b/src/arcadepy/types/worker_list_response.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from .._models import BaseModel
+from .worker_response import WorkerResponse
+
+__all__ = ["WorkerListResponse"]
+
+
+class WorkerListResponse(BaseModel):
+ items: Optional[List[WorkerResponse]] = None
+
+ limit: Optional[int] = None
+
+ offset: Optional[int] = None
+
+ page_count: Optional[int] = None
+
+ total_count: Optional[int] = None
diff --git a/src/arcadepy/types/worker_response.py b/src/arcadepy/types/worker_response.py
new file mode 100644
index 00000000..0f7f434d
--- /dev/null
+++ b/src/arcadepy/types/worker_response.py
@@ -0,0 +1,40 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["WorkerResponse", "HTTP", "HTTPSecret"]
+
+
+class HTTPSecret(BaseModel):
+ binding: Optional[Literal["static", "tenant", "organization", "account"]] = None
+
+ editable: Optional[bool] = None
+
+ exists: Optional[bool] = None
+
+ hint: Optional[str] = None
+
+ value: Optional[str] = None
+
+
+class HTTP(BaseModel):
+ retry: Optional[int] = None
+
+ secret: Optional[HTTPSecret] = None
+
+ timeout: Optional[int] = None
+
+ uri: Optional[str] = None
+
+
+class WorkerResponse(BaseModel):
+ id: Optional[str] = None
+
+ enabled: Optional[bool] = None
+
+ http: Optional[HTTP] = None
+
+ type: Optional[str] = None
diff --git a/tests/api_resources/test_worker.py b/tests/api_resources/test_worker.py
new file mode 100644
index 00000000..34682074
--- /dev/null
+++ b/tests/api_resources/test_worker.py
@@ -0,0 +1,168 @@
+# 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 arcadepy import Arcade, AsyncArcade
+from tests.utils import assert_matches_type
+from arcadepy.types import WorkerResponse, WorkerListResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestWorker:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Arcade) -> None:
+ worker = client.worker.create(
+ id="id",
+ enabled=True,
+ )
+ assert_matches_type(WorkerResponse, worker, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Arcade) -> None:
+ worker = client.worker.create(
+ id="id",
+ enabled=True,
+ http={
+ "retry": 0,
+ "secret": "secret",
+ "timeout": 1,
+ "uri": "uri",
+ },
+ )
+ assert_matches_type(WorkerResponse, worker, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Arcade) -> None:
+ response = client.worker.with_raw_response.create(
+ id="id",
+ enabled=True,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ worker = response.parse()
+ assert_matches_type(WorkerResponse, worker, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Arcade) -> None:
+ with client.worker.with_streaming_response.create(
+ id="id",
+ enabled=True,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ worker = response.parse()
+ assert_matches_type(WorkerResponse, worker, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_list(self, client: Arcade) -> None:
+ worker = client.worker.list()
+ assert_matches_type(WorkerListResponse, worker, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Arcade) -> None:
+ response = client.worker.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ worker = response.parse()
+ assert_matches_type(WorkerListResponse, worker, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Arcade) -> None:
+ with client.worker.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ worker = response.parse()
+ assert_matches_type(WorkerListResponse, worker, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncWorker:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncArcade) -> None:
+ worker = await async_client.worker.create(
+ id="id",
+ enabled=True,
+ )
+ assert_matches_type(WorkerResponse, worker, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncArcade) -> None:
+ worker = await async_client.worker.create(
+ id="id",
+ enabled=True,
+ http={
+ "retry": 0,
+ "secret": "secret",
+ "timeout": 1,
+ "uri": "uri",
+ },
+ )
+ assert_matches_type(WorkerResponse, worker, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncArcade) -> None:
+ response = await async_client.worker.with_raw_response.create(
+ id="id",
+ enabled=True,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ worker = await response.parse()
+ assert_matches_type(WorkerResponse, worker, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncArcade) -> None:
+ async with async_client.worker.with_streaming_response.create(
+ id="id",
+ enabled=True,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ worker = await response.parse()
+ assert_matches_type(WorkerResponse, worker, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncArcade) -> None:
+ worker = await async_client.worker.list()
+ assert_matches_type(WorkerListResponse, worker, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncArcade) -> None:
+ response = await async_client.worker.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ worker = await response.parse()
+ assert_matches_type(WorkerListResponse, worker, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncArcade) -> None:
+ async with async_client.worker.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ worker = await response.parse()
+ assert_matches_type(WorkerListResponse, worker, path=["response"])
+
+ assert cast(Any, response.is_closed) is True