Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
cd7c9b7
feat(api): api update
stainless-app[bot] Apr 21, 2026
44664f7
codegen metadata
stainless-app[bot] Apr 21, 2026
c6c1b5e
codegen metadata
stainless-app[bot] Apr 21, 2026
ff8d02c
codegen metadata
stainless-app[bot] Apr 21, 2026
be31593
codegen metadata
stainless-app[bot] Apr 21, 2026
386f244
codegen metadata
stainless-app[bot] Apr 22, 2026
67507d5
codegen metadata
stainless-app[bot] Apr 22, 2026
35574d4
codegen metadata
stainless-app[bot] Apr 22, 2026
089c776
codegen metadata
stainless-app[bot] Apr 22, 2026
799afcb
codegen metadata
stainless-app[bot] Apr 22, 2026
dd59283
chore(internal): more robust bootstrap script
stainless-app[bot] Apr 22, 2026
cf8f366
codegen metadata
stainless-app[bot] Apr 22, 2026
6b1662f
codegen metadata
stainless-app[bot] Apr 22, 2026
ac2ca9e
codegen metadata
stainless-app[bot] Apr 23, 2026
dee4759
codegen metadata
stainless-app[bot] Apr 23, 2026
2e0012c
codegen metadata
stainless-app[bot] Apr 23, 2026
3333d5a
codegen metadata
stainless-app[bot] Apr 23, 2026
0ecc6e3
codegen metadata
stainless-app[bot] Apr 23, 2026
e1ca658
codegen metadata
stainless-app[bot] Apr 23, 2026
17d1148
codegen metadata
stainless-app[bot] Apr 23, 2026
84c23ba
codegen metadata
stainless-app[bot] Apr 23, 2026
fe4ffd0
codegen metadata
stainless-app[bot] Apr 23, 2026
f7c76f0
codegen metadata
stainless-app[bot] Apr 23, 2026
0948d41
codegen metadata
stainless-app[bot] Apr 23, 2026
d613307
codegen metadata
stainless-app[bot] Apr 23, 2026
291d2b7
codegen metadata
stainless-app[bot] Apr 24, 2026
6242b33
codegen metadata
stainless-app[bot] Apr 24, 2026
92724b0
codegen metadata
stainless-app[bot] Apr 24, 2026
05885c7
codegen metadata
stainless-app[bot] Apr 24, 2026
c7ddc9a
codegen metadata
stainless-app[bot] Apr 24, 2026
24a53f3
codegen metadata
stainless-app[bot] Apr 24, 2026
4c159a9
codegen metadata
stainless-app[bot] Apr 24, 2026
3a97da1
codegen metadata
stainless-app[bot] Apr 24, 2026
bf70b13
codegen metadata
stainless-app[bot] Apr 24, 2026
259ee53
codegen metadata
stainless-app[bot] Apr 25, 2026
37a5576
codegen metadata
stainless-app[bot] Apr 25, 2026
6a31847
codegen metadata
stainless-app[bot] Apr 25, 2026
eeb6863
codegen metadata
stainless-app[bot] Apr 25, 2026
2b3ba68
codegen metadata
stainless-app[bot] Apr 25, 2026
79a70a9
codegen metadata
stainless-app[bot] Apr 25, 2026
3dd4dc4
codegen metadata
stainless-app[bot] Apr 25, 2026
d9a19ce
codegen metadata
stainless-app[bot] Apr 25, 2026
0d942e4
codegen metadata
stainless-app[bot] Apr 25, 2026
e0240b3
codegen metadata
stainless-app[bot] Apr 25, 2026
d344fe4
codegen metadata
stainless-app[bot] Apr 25, 2026
79527a4
codegen metadata
stainless-app[bot] Apr 25, 2026
cdb378f
codegen metadata
stainless-app[bot] Apr 25, 2026
8c1b26a
codegen metadata
stainless-app[bot] Apr 26, 2026
73a79b2
codegen metadata
stainless-app[bot] Apr 26, 2026
667dc14
codegen metadata
stainless-app[bot] Apr 26, 2026
796f4fc
codegen metadata
stainless-app[bot] Apr 26, 2026
51a0bc0
codegen metadata
stainless-app[bot] Apr 26, 2026
7cf89d7
codegen metadata
stainless-app[bot] Apr 26, 2026
8b217b9
codegen metadata
stainless-app[bot] Apr 26, 2026
1abd156
codegen metadata
stainless-app[bot] Apr 26, 2026
eb6fc8e
codegen metadata
stainless-app[bot] Apr 26, 2026
34f5393
codegen metadata
stainless-app[bot] Apr 27, 2026
79b2411
codegen metadata
stainless-app[bot] Apr 27, 2026
2711a60
codegen metadata
stainless-app[bot] Apr 27, 2026
17381d3
codegen metadata
stainless-app[bot] Apr 27, 2026
94f9a1a
codegen metadata
stainless-app[bot] Apr 27, 2026
9482149
codegen metadata
stainless-app[bot] Apr 27, 2026
6f9288e
codegen metadata
stainless-app[bot] Apr 27, 2026
f787b68
codegen metadata
stainless-app[bot] Apr 27, 2026
117dba5
codegen metadata
stainless-app[bot] Apr 27, 2026
cd05ace
codegen metadata
stainless-app[bot] Apr 27, 2026
44078f4
fix: use correct field name format for multipart file arrays
stainless-app[bot] Apr 27, 2026
22b2b7d
codegen metadata
stainless-app[bot] Apr 27, 2026
c0b9578
codegen metadata
stainless-app[bot] Apr 27, 2026
7be5bcf
codegen metadata
stainless-app[bot] Apr 27, 2026
96969bb
codegen metadata
stainless-app[bot] Apr 27, 2026
574a34a
codegen metadata
stainless-app[bot] Apr 27, 2026
57a862c
feat: support setting headers via env
stainless-app[bot] Apr 27, 2026
47d7199
codegen metadata
stainless-app[bot] Apr 27, 2026
dfc3337
codegen metadata
stainless-app[bot] Apr 28, 2026
605b50e
codegen metadata
stainless-app[bot] Apr 28, 2026
117def2
codegen metadata
stainless-app[bot] Apr 28, 2026
b450098
release: 0.11.0
stainless-app[bot] Apr 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.10.2"
".": "0.11.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 45
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp%2Fagentex-sdk-eeb5bf63b18d948611eec48d0225e9bba63b170f64eeeb35d91825724b7cf6c3.yml
openapi_spec_hash: 5bbd18a405a11e8497d38a5a88b98018
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp%2Fagentex-sdk-636aa63c588134e6f47fc45212049593d91f810a9c7bd8d7a57810cf1b5ffc92.yml
openapi_spec_hash: 5339c136760ece9fa1efb9a4f7749673
config_hash: fb079ef7936611b032568661b8165f19
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## 0.11.0 (2026-04-28)

Full Changelog: [v0.10.2...v0.11.0](https://github.com/scaleapi/scale-agentex-python/compare/v0.10.2...v0.11.0)

### Features

* **api:** api update ([cd7c9b7](https://github.com/scaleapi/scale-agentex-python/commit/cd7c9b76a28f61d95c1c9f5477048c85f7e9f277))
* support setting headers via env ([57a862c](https://github.com/scaleapi/scale-agentex-python/commit/57a862c8543f67a6cdc62dc9da623467676d2c53))


### Bug Fixes

* use correct field name format for multipart file arrays ([44078f4](https://github.com/scaleapi/scale-agentex-python/commit/44078f417c347b031933c6f6faae40b7681deb5f))


### Chores

* **internal:** more robust bootstrap script ([dd59283](https://github.com/scaleapi/scale-agentex-python/commit/dd592831d5d0304cf2c585b8a995ac4a8c407773))

## 0.10.2 (2026-04-21)

Full Changelog: [v0.10.1...v0.10.2](https://github.com/scaleapi/scale-agentex-python/compare/v0.10.1...v0.10.2)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "agentex-sdk"
version = "0.10.2"
version = "0.11.0"
description = "The official Python library for the agentex API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion scripts/bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -e

cd "$(dirname "$0")/.."

if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then
if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1" ] && [ -t 0 ]; then
brew bundle check >/dev/null 2>&1 || {
echo -n "==> Install Homebrew dependencies? (y/N): "
read -r response
Expand Down
24 changes: 23 additions & 1 deletion src/agentex/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
RequestOptions,
not_given,
)
from ._utils import is_given, get_async_library
from ._utils import (
is_given,
is_mapping_t,
get_async_library,
)
from ._compat import cached_property
from ._version import __version__
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
Expand Down Expand Up @@ -123,6 +127,15 @@ def __init__(
except KeyError as exc:
raise ValueError(f"Unknown environment: {environment}") from exc

custom_headers_env = os.environ.get("AGENTEX_CUSTOM_HEADERS")
if custom_headers_env is not None:
parsed: dict[str, str] = {}
for line in custom_headers_env.split("\n"):
colon = line.find(":")
if colon >= 0:
parsed[line[:colon].strip()] = line[colon + 1 :].strip()
default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})}

super().__init__(
version=__version__,
base_url=base_url,
Expand Down Expand Up @@ -363,6 +376,15 @@ def __init__(
except KeyError as exc:
raise ValueError(f"Unknown environment: {environment}") from exc

custom_headers_env = os.environ.get("AGENTEX_CUSTOM_HEADERS")
if custom_headers_env is not None:
parsed: dict[str, str] = {}
for line in custom_headers_env.split("\n"):
colon = line.find(":")
if colon >= 0:
parsed[line[:colon].strip()] = line[colon + 1 :].strip()
default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})}

super().__init__(
version=__version__,
base_url=base_url,
Expand Down
8 changes: 2 additions & 6 deletions src/agentex/_qs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@

from typing import Any, List, Tuple, Union, Mapping, TypeVar
from urllib.parse import parse_qs, urlencode
from typing_extensions import Literal, get_args
from typing_extensions import get_args

from ._types import NotGiven, not_given
from ._types import NotGiven, ArrayFormat, NestedFormat, not_given
from ._utils import flatten

_T = TypeVar("_T")


ArrayFormat = Literal["comma", "repeat", "indices", "brackets"]
NestedFormat = Literal["dots", "brackets"]

PrimitiveData = Union[str, int, float, bool, None]
# this should be Data = Union[PrimitiveData, "List[Data]", "Tuple[Data]", "Mapping[str, Data]"]
# https://github.com/microsoft/pyright/issues/3555
Expand Down
3 changes: 3 additions & 0 deletions src/agentex/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
ModelT = TypeVar("ModelT", bound=pydantic.BaseModel)
_T = TypeVar("_T")

ArrayFormat = Literal["comma", "repeat", "indices", "brackets"]
NestedFormat = Literal["dots", "brackets"]


# Approximates httpx internal ProxiesTypes and RequestFiles types
# while adding support for `PathLike` instances
Expand Down
42 changes: 34 additions & 8 deletions src/agentex/_utils/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
)
from pathlib import Path
from datetime import date, datetime
from typing_extensions import TypeGuard
from typing_extensions import TypeGuard, get_args

import sniffio

from .._types import Omit, NotGiven, FileTypes, HeadersLike
from .._types import Omit, NotGiven, FileTypes, ArrayFormat, HeadersLike

_T = TypeVar("_T")
_TupleT = TypeVar("_TupleT", bound=Tuple[object, ...])
Expand All @@ -40,25 +40,45 @@ def extract_files(
query: Mapping[str, object],
*,
paths: Sequence[Sequence[str]],
array_format: ArrayFormat = "brackets",
) -> list[tuple[str, FileTypes]]:
"""Recursively extract files from the given dictionary based on specified paths.

A path may look like this ['foo', 'files', '<array>', 'data'].

``array_format`` controls how ``<array>`` segments contribute to the emitted
field name. Supported values: ``"brackets"`` (``foo[]``), ``"repeat"`` and
``"comma"`` (``foo``), ``"indices"`` (``foo[0]``, ``foo[1]``).

Note: this mutates the given dictionary.
"""
files: list[tuple[str, FileTypes]] = []
for path in paths:
files.extend(_extract_items(query, path, index=0, flattened_key=None))
files.extend(_extract_items(query, path, index=0, flattened_key=None, array_format=array_format))
return files


def _array_suffix(array_format: ArrayFormat, array_index: int) -> str:
if array_format == "brackets":
return "[]"
if array_format == "indices":
return f"[{array_index}]"
if array_format == "repeat" or array_format == "comma":
# Both repeat the bare field name for each file part; there is no
# meaningful way to comma-join binary parts.
return ""
raise NotImplementedError(
f"Unknown array_format value: {array_format}, choose from {', '.join(get_args(ArrayFormat))}"
)


def _extract_items(
obj: object,
path: Sequence[str],
*,
index: int,
flattened_key: str | None,
array_format: ArrayFormat,
) -> list[tuple[str, FileTypes]]:
try:
key = path[index]
Expand All @@ -75,9 +95,11 @@ def _extract_items(

if is_list(obj):
files: list[tuple[str, FileTypes]] = []
for entry in obj:
assert_is_file_content(entry, key=flattened_key + "[]" if flattened_key else "")
files.append((flattened_key + "[]", cast(FileTypes, entry)))
for array_index, entry in enumerate(obj):
suffix = _array_suffix(array_format, array_index)
emitted_key = (flattened_key + suffix) if flattened_key else suffix
assert_is_file_content(entry, key=emitted_key)
files.append((emitted_key, cast(FileTypes, entry)))
return files

assert_is_file_content(obj, key=flattened_key)
Expand Down Expand Up @@ -106,6 +128,7 @@ def _extract_items(
path,
index=index,
flattened_key=flattened_key,
array_format=array_format,
)
elif is_list(obj):
if key != "<array>":
Expand All @@ -117,9 +140,12 @@ def _extract_items(
item,
path,
index=index,
flattened_key=flattened_key + "[]" if flattened_key is not None else "[]",
flattened_key=(
(flattened_key if flattened_key is not None else "") + _array_suffix(array_format, array_index)
),
array_format=array_format,
)
for item in obj
for array_index, item in enumerate(obj)
]
)

Expand Down
2 changes: 1 addition & 1 deletion src/agentex/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "agentex"
__version__ = "0.10.2" # x-release-please-version
__version__ = "0.11.0" # x-release-please-version
24 changes: 2 additions & 22 deletions src/agentex/resources/spans.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ def create(
input: Union[Dict[str, object], Iterable[Dict[str, object]], None] | Omit = omit,
output: Union[Dict[str, object], Iterable[Dict[str, object]], None] | Omit = omit,
parent_id: Optional[str] | Omit = omit,
task_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
Expand Down Expand Up @@ -87,8 +86,6 @@ def create(

parent_id: ID of the parent span if this is a child span in a trace

task_id: ID of the task this span belongs to

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request
Expand All @@ -110,7 +107,6 @@ def create(
"input": input,
"output": output,
"parent_id": parent_id,
"task_id": task_id,
},
span_create_params.SpanCreateParams,
),
Expand Down Expand Up @@ -164,7 +160,6 @@ def update(
output: Union[Dict[str, object], Iterable[Dict[str, object]], None] | Omit = omit,
parent_id: Optional[str] | Omit = omit,
start_time: Union[str, datetime, None] | Omit = omit,
task_id: Optional[str] | Omit = omit,
trace_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
Expand All @@ -191,8 +186,6 @@ def update(

start_time: The time the span started

task_id: ID of the task this span belongs to

trace_id: Unique identifier for the trace this span belongs to

extra_headers: Send extra headers
Expand All @@ -216,7 +209,6 @@ def update(
"output": output,
"parent_id": parent_id,
"start_time": start_time,
"task_id": task_id,
"trace_id": trace_id,
},
span_update_params.SpanUpdateParams,
Expand All @@ -234,7 +226,6 @@ def list(
order_by: Optional[str] | Omit = omit,
order_direction: str | Omit = omit,
page_number: int | Omit = omit,
task_id: Optional[str] | Omit = omit,
trace_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
Expand All @@ -244,7 +235,7 @@ def list(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SpanListResponse:
"""
List spans, optionally filtered by trace_id and/or task_id
List all spans for a given trace ID

Args:
extra_headers: Send extra headers
Expand All @@ -268,7 +259,6 @@ def list(
"order_by": order_by,
"order_direction": order_direction,
"page_number": page_number,
"task_id": task_id,
"trace_id": trace_id,
},
span_list_params.SpanListParams,
Expand Down Expand Up @@ -310,7 +300,6 @@ async def create(
input: Union[Dict[str, object], Iterable[Dict[str, object]], None] | Omit = omit,
output: Union[Dict[str, object], Iterable[Dict[str, object]], None] | Omit = omit,
parent_id: Optional[str] | Omit = omit,
task_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
Expand Down Expand Up @@ -340,8 +329,6 @@ async def create(

parent_id: ID of the parent span if this is a child span in a trace

task_id: ID of the task this span belongs to

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request
Expand All @@ -363,7 +350,6 @@ async def create(
"input": input,
"output": output,
"parent_id": parent_id,
"task_id": task_id,
},
span_create_params.SpanCreateParams,
),
Expand Down Expand Up @@ -417,7 +403,6 @@ async def update(
output: Union[Dict[str, object], Iterable[Dict[str, object]], None] | Omit = omit,
parent_id: Optional[str] | Omit = omit,
start_time: Union[str, datetime, None] | Omit = omit,
task_id: Optional[str] | Omit = omit,
trace_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
Expand All @@ -444,8 +429,6 @@ async def update(

start_time: The time the span started

task_id: ID of the task this span belongs to

trace_id: Unique identifier for the trace this span belongs to

extra_headers: Send extra headers
Expand All @@ -469,7 +452,6 @@ async def update(
"output": output,
"parent_id": parent_id,
"start_time": start_time,
"task_id": task_id,
"trace_id": trace_id,
},
span_update_params.SpanUpdateParams,
Expand All @@ -487,7 +469,6 @@ async def list(
order_by: Optional[str] | Omit = omit,
order_direction: str | Omit = omit,
page_number: int | Omit = omit,
task_id: Optional[str] | Omit = omit,
trace_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
Expand All @@ -497,7 +478,7 @@ async def list(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SpanListResponse:
"""
List spans, optionally filtered by trace_id and/or task_id
List all spans for a given trace ID

Args:
extra_headers: Send extra headers
Expand All @@ -521,7 +502,6 @@ async def list(
"order_by": order_by,
"order_direction": order_direction,
"page_number": page_number,
"task_id": task_id,
"trace_id": trace_id,
},
span_list_params.SpanListParams,
Expand Down
3 changes: 0 additions & 3 deletions src/agentex/types/span.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,3 @@ class Span(BaseModel):

parent_id: Optional[str] = None
"""ID of the parent span if this is a child span in a trace"""

task_id: Optional[str] = None
"""ID of the task this span belongs to"""
3 changes: 0 additions & 3 deletions src/agentex/types/span_create_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,3 @@ class SpanCreateParams(TypedDict, total=False):

parent_id: Optional[str]
"""ID of the parent span if this is a child span in a trace"""

task_id: Optional[str]
"""ID of the task this span belongs to"""
Loading
Loading