Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 5 additions & 3 deletions .github/workflows/agentex-tutorials-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,11 @@ jobs:

- name: Build AgentEx SDK
run: |
echo "🔨 Building AgentEx SDK wheel..."
uv build
echo "✅ SDK built successfully"
echo "🔨 Building both SDK wheels (slim client + heavy ADK overlay)..."
# uv workspace builds both members into the root dist/. --wheel: the
# heavy's cross-dir force-include can't build via the sdist default.
uv build --all-packages --wheel
echo "✅ Both SDK wheels built successfully"
ls -la dist/

- name: Test Tutorial
Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@ jobs:
version: '0.10.2'

- name: Install dependencies
run: uv sync --all-extras
run: uv sync --all-packages --all-extras

- name: Run lints
run: ./scripts/lint

- name: Check slim dependency set
run: ./scripts/check-slim-deps

build:
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
timeout-minutes: 10
Expand All @@ -51,10 +54,12 @@ jobs:
version: '0.10.2'

- name: Install dependencies
run: uv sync --all-extras
run: uv sync --all-packages --all-extras

- name: Run build
run: uv build
# Both workspace members. --wheel is load-bearing: the heavy's cross-dir
# force-include can't build via the sdist-then-wheel default.
run: uv build --all-packages --wheel

- name: Get GitHub OIDC Token
if: |-
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,11 @@ jobs:
run: |
bash ./bin/publish-pypi
env:
# Heavy `agentex-sdk` package token (existing PyPI name).
AGENTEX_PYPI_TOKEN: ${{ secrets.AGENTEX_PYPI_TOKEN }}
# Slim `agentex-client` package token (new PyPI name; needs
# to be added to repo secrets when the slim is registered).
AGENTEX_CLIENT_PYPI_TOKEN: ${{ secrets.AGENTEX_CLIENT_PYPI_TOKEN }}
# Back-compat fallback — used by bin/publish-pypi when the
# dedicated tokens above are unset.
PYPI_TOKEN: ${{ secrets.AGENTEX_PYPI_TOKEN || secrets.PYPI_TOKEN }}
3 changes: 2 additions & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
".": "0.12.0"
".": "0.13.0",
"adk": "0.13.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: 64
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp/agentex-sdk-46769b729d89151fb7e7ae15725678af99f55ef32d283e34a1e143057aa87b23.yml
openapi_spec_hash: 9115c9f283257e0636aba67fadfeda0a
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sgp/agentex-sdk-f6bcef733992533e1b1d66c2207e42a934fa0ec9646e3d6a6268fad17e73c834.yml
openapi_spec_hash: 3aae4790b24edf6ea9469c1680d513ae
config_hash: 82cb83ac175dbf40265128506294218b
54 changes: 54 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,60 @@

* **tracing:** emit OTel metrics for async span queue depth, batch drain, and SGP export success/failure (HTTP status labels). Disable SDK-side recording with ``AGENTEX_TRACING_METRICS=0``.

## 0.13.0 (2026-06-09)

Full Changelog: [agentex-client-v0.12.0...agentex-client-v0.13.0](https://github.com/scaleapi/scale-agentex-python/compare/agentex-client-v0.12.0...agentex-client-v0.13.0)

### ⚠ BREAKING CHANGES

* **packaging:** release tag scheme changes from v* to <component>-v*.

### Features

* add AgentCard for self-describing agent capabilities ([#296](https://github.com/scaleapi/scale-agentex-python/issues/296)) ([6509be1](https://github.com/scaleapi/scale-agentex-python/commit/6509be1e5d9bc53e6058b22c45c760e04a4c4006))
* add HTTP-proxy LangGraph checkpointer ([19fae2f](https://github.com/scaleapi/scale-agentex-python/commit/19fae2f6e3ce4302066a403cac4c6499410ec4ad))
* add OCI Helm registry support for agent deployments ([#255](https://github.com/scaleapi/scale-agentex-python/issues/255)) ([5f054b5](https://github.com/scaleapi/scale-agentex-python/commit/5f054b514ff919479b0914883ed163279820c848))
* **adk:** allow all ClaudeAgentOptions in run_claude_agent_activity ([25bbe24](https://github.com/scaleapi/scale-agentex-python/commit/25bbe24b57feaab2e557ca15279369bfb59e02db))
* **adk:** Revamp run_claude_agent_activity to use more streaming ([#309](https://github.com/scaleapi/scale-agentex-python/issues/309)) ([0c16595](https://github.com/scaleapi/scale-agentex-python/commit/0c16595017164649bbea1bab8767010c9be7228d))
* **api:** api update ([7b1b642](https://github.com/scaleapi/scale-agentex-python/commit/7b1b642404f34ff74d866e91a5ed2d6f0a4424c6))
* **api:** api update ([710c63f](https://github.com/scaleapi/scale-agentex-python/commit/710c63f3a9b0494635c41e0d3498d69dc9145b81))
* **api:** api update ([8abce2b](https://github.com/scaleapi/scale-agentex-python/commit/8abce2ba6131732688f04bacff33da506e47c77f))
* **lib:** Add task updates to adk ([a58747f](https://github.com/scaleapi/scale-agentex-python/commit/a58747f0d85733f32f67b06eee222a1464eb87fe))
* **openai_agents:** expose real `usage`, `response_id`, plumb `previous_response_id`, opt-in `prompt_cache_key` for stateful responses and prompt caching ([#335](https://github.com/scaleapi/scale-agentex-python/issues/335)) ([ba5d64b](https://github.com/scaleapi/scale-agentex-python/commit/ba5d64be1f959ff1a35b30e647a0a5ead21a8402))
* **packaging:** introduce slim agentex-client + heavy agentex-sdk split ([bbfb22e](https://github.com/scaleapi/scale-agentex-python/commit/bbfb22eb113dd1f3d5ddf82b4d377895f5ae5466))
* pass AGENTEX_DEPLOYMENT_ID in registration metadata ([#305](https://github.com/scaleapi/scale-agentex-python/issues/305)) ([31af8c6](https://github.com/scaleapi/scale-agentex-python/commit/31af8c6fc4aaafad57b70ded4883ced1254aeb1b))
* **tracing:** Add background queue for async span processing ([#303](https://github.com/scaleapi/scale-agentex-python/issues/303)) ([3a60add](https://github.com/scaleapi/scale-agentex-python/commit/3a60add048ff24266a45700b4e78def8ffed3e0b))


### Bug Fixes

* add litellm retry with exponential backoff for rate limit errors ([ccdb24a](https://github.com/scaleapi/scale-agentex-python/commit/ccdb24a08607298f8dafd748ee9e7fe8ba13d5fe))
* **adk:** fix to queue drain ([#327](https://github.com/scaleapi/scale-agentex-python/issues/327)) ([a862a06](https://github.com/scaleapi/scale-agentex-python/commit/a862a0646365d86acd4b0e1cf470fce522a6fbb3))
* **api:** remove agent_id and task_id parameters from states update method ([a7cbaae](https://github.com/scaleapi/scale-agentex-python/commit/a7cbaae4416e2d712623ecfac5e251c07c537958))
* **client:** preserve hardcoded query params when merging with user params ([d2c4788](https://github.com/scaleapi/scale-agentex-python/commit/d2c47883c4247a0c5a318042ff38384ddc8db4ea))
* ensure file data are only sent as 1 parameter ([48fae27](https://github.com/scaleapi/scale-agentex-python/commit/48fae27b6a761984f7fb70cb7a87da76a4192d12))
* render .env.example template in agentex init ([#351](https://github.com/scaleapi/scale-agentex-python/issues/351)) ([6092595](https://github.com/scaleapi/scale-agentex-python/commit/6092595fa8a267b2c305baba09e2682c04d593b3))
* Temporal Union deserialization causing tool_response messages to be lost ([79ef4dd](https://github.com/scaleapi/scale-agentex-python/commit/79ef4dd7a0ab1b8bb1151f5e16124ec5a947dfd4))
* **temporal:** allowing-ACP-temporal-telemetry ([9b44eb0](https://github.com/scaleapi/scale-agentex-python/commit/9b44eb0f5c6482984f972674d7a8612980c5b576))
* **tests:** repair test_streaming_model so all 28 tests run and pass ([#334](https://github.com/scaleapi/scale-agentex-python/issues/334)) ([7e5e69c](https://github.com/scaleapi/scale-agentex-python/commit/7e5e69c132c89d054516e1a762e0437375859663))
* **tracing:** Fix memory leak in SGP tracing processors ([#302](https://github.com/scaleapi/scale-agentex-python/issues/302)) ([f43dac4](https://github.com/scaleapi/scale-agentex-python/commit/f43dac4fa7ca7090b37c6c3bf285eb12515764bb))


### Performance Improvements

* **client:** optimize file structure copying in multipart requests ([f5064f9](https://github.com/scaleapi/scale-agentex-python/commit/f5064f939788d72fedac91436982a8848d0f1f4f))


### Chores

* **ci:** upgrade `actions/github-script` ([7c867e8](https://github.com/scaleapi/scale-agentex-python/commit/7c867e8960b51234e5e41a9b8e3129c1dada5680))


### Documentation

* **api:** clarify name parameter behavior in agent task creation ([ce5af72](https://github.com/scaleapi/scale-agentex-python/commit/ce5af729cc3a0f05905d0cebfe2ef18c16d8563e))
* clarify task name is optional in adk.acp.create_task ([#392](https://github.com/scaleapi/scale-agentex-python/issues/392)) ([bd41d9b](https://github.com/scaleapi/scale-agentex-python/commit/bd41d9bb10f08a354f02f982e6507847c19d2ad9))

## 0.12.0 (2026-06-02)

Full Changelog: [v0.11.9...v0.12.0](https://github.com/scaleapi/scale-agentex-python/compare/v0.11.9...v0.12.0)
Expand Down
13 changes: 13 additions & 0 deletions adk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Changelog

## 0.13.0 (2026-06-09)

Full Changelog: [agentex-sdk-v0.12.0...agentex-sdk-v0.13.0](https://github.com/scaleapi/scale-agentex-python/compare/agentex-sdk-v0.12.0...agentex-sdk-v0.13.0)

### ⚠ BREAKING CHANGES

* **packaging:** release tag scheme changes from v* to <component>-v*.

### Features

* **packaging:** introduce slim agentex-client + heavy agentex-sdk split ([bbfb22e](https://github.com/scaleapi/scale-agentex-python/commit/bbfb22eb113dd1f3d5ddf82b4d377895f5ae5466))
32 changes: 32 additions & 0 deletions adk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# agentex-sdk

The Agent Development Kit (ADK) overlay for the Agentex API.

## What's in here

This package ships everything under `agentex.lib.*`:

- **ACP server** (`agentex.lib.sdk.fastacp`) — FastAPI-based agent control plane.
- **Temporal workflows** (`agentex.lib.core.temporal`) — durable agent execution.
- **CLI** (`agentex.lib.cli`) — `agentex init`, `agentex run`, deploy helpers.
- **LLM provider integrations** (`agentex.lib.adk.providers`, `agentex.lib.core.temporal.plugins`) — OpenAI Agents, Claude Agent SDK, pydantic-ai, langgraph, litellm.
- **Observability** (`agentex.lib.core.tracing`, `agentex.lib.core.observability`) — SGP, Datadog, OpenTelemetry tracing processors.

## Installation

```sh
pip install agentex-sdk
```

This automatically pulls in [`agentex-client`](../) (the slim Stainless-generated REST client) so `from agentex import Agentex, AsyncAgentex` works the same as before.

## When to use this vs `agentex-client`

- **`agentex-sdk`** — you're authoring agents. Pulls everything: ACP server, Temporal, MCP, LLM providers, observability, CLI. ~37 deps.
- **`agentex-client`** — you only need to call the Agentex REST API. No agent authoring, no Temporal workflows, no FastACP server, no provider integrations. 6 deps.

The two packages contribute disjoint files to the `agentex.*` namespace — `agentex/lib/*` ships only from `agentex-sdk`.

## Repo layout

This package is hand-authored and lives at `adk/` inside [scaleapi/scale-agentex-python](https://github.com/scaleapi/scale-agentex-python). The Stainless generator preserves `adk/**` via `keep_files` so its codegen never touches anything here. The sibling `agentex-client` package lives at the repo root and IS Stainless-generated.
41 changes: 41 additions & 0 deletions adk/hatch_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Builds the agentex/lib force-include map per-file so test files can be pruned
— force-include ignores `exclude` (hatchling #1395)."""

from __future__ import annotations

import os

from hatchling.builders.hooks.plugin.interface import BuildHookInterface

_SKIP_DIRS = {"__pycache__", "tests"}
_SKIP_NAMES = {"conftest.py", "pytest.ini", "run_tests.py"}
# Floor below the ~333 shippable files: a collapse means the walk broke — fail
# loud rather than ship a near-empty wheel.
_MIN_FILES = 320


def _is_test_file(name: str) -> bool:
return name in _SKIP_NAMES or (name.startswith("test_") and name.endswith(".py"))


class CustomBuildHook(BuildHookInterface):
PLUGIN_NAME = "custom"

def initialize(self, version: str, build_data: dict) -> None: # noqa: ARG002
lib_root = os.path.normpath(os.path.join(self.root, "..", "src", "agentex", "lib"))
force_include = build_data.setdefault("force_include", {})
collected = 0
for dirpath, dirnames, filenames in os.walk(lib_root):
dirnames[:] = [d for d in dirnames if d not in _SKIP_DIRS]
for name in filenames:
if _is_test_file(name):
continue
src = os.path.join(dirpath, name)
rel = os.path.relpath(src, lib_root)
force_include[src] = os.path.join("agentex", "lib", rel)
collected += 1
if collected < _MIN_FILES:
raise RuntimeError(
f"agentex/lib force-include collected only {collected} files "
f"(expected >= {_MIN_FILES}); aborting build."
)
105 changes: 105 additions & 0 deletions adk/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
[project]
# Hand-authored ADK overlay for agentex. This package contributes only
# `agentex/lib/*` to the agentex.* namespace; the REST client surface
# (agentex/{__init__.py, _*.py, types/, resources/}) ships from the slim
# sibling package `agentex-client` which is pinned as a runtime dep.
#
# This entire `adk/` directory must be preserved across Stainless codegen
# via `keep_files: ["adk/**"]` in the Stainless dashboard config.
name = "agentex-sdk"
version = "0.13.0"
description = "Agent Development Kit (ADK) overlay for the Agentex API — FastACP server, Temporal workflows, LLM provider integrations, observability"
license = "Apache-2.0"
authors = [
{ name = "Agentex", email = "roxanne.farhad@scale.com" },
]
readme = "README.md"

dependencies = [
# Co-released in lockstep; floor-only by design — a ceiling would
# eventually exclude the co-versioned slim (release-please can't bump it).
"agentex-client>=0.12.0",
# CLI surface (agentex.lib.cli.*, agentex.lib.sdk.config.*)
"typer>=0.16,<0.17",
"questionary>=2.0.1,<3",
"rich>=13.9.2,<14",
"yaspin>=3.1.0",
"pyyaml>=6.0.2,<7",
"python-on-whales>=0.73.0,<0.74",
"kubernetes>=25.0.0,<36.0.0",
"jsonref>=1.1.0,<2",
"jsonschema>=4.23.0,<5",
"jinja2>=3.1.3,<4",
"watchfiles>=0.24.0,<1.0",
# ACP server (FastAPI app surface)
"fastapi>=0.115.0",
"starlette>=0.49.1",
"uvicorn>=0.31.1",
"aiohttp>=3.10.10,<4",
# Temporal workflows
"temporalio>=1.26.0,<2",
"cloudpickle>=3.1.1",
# Async streaming infra
"redis>=5.2.0,<8",
# LLM provider integrations
"litellm>=1.83.7,<2",
"openai-agents>=0.14.3,<0.15",
"openai>=2.2,<3", # Required by openai-agents; litellm now supports openai 2.x (issue #13711 resolved: https://github.com/BerriAI/litellm/issues/13711)
"claude-agent-sdk>=0.1.0",
"pydantic-ai-slim>=1.0,<2",
"langgraph-checkpoint>=2.0.0",
"scale-gp>=0.1.0a59",
"scale-gp-beta>=0.2.0",
"mcp>=1.4.1",
# Observability
"ddtrace>=3.13.0",
"opentelemetry-api>=1.20.0",
"opentelemetry-sdk>=1.20.0",
"json_log_formatter>=1.1.1",
]

# agentex/lib/* uses `from typing import override` (3.12+) in 19 files.
# The slim agentex-client keeps 3.11 support.
requires-python = ">= 3.12,<4"
classifiers = [
"Typing :: Typed",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Operating System :: OS Independent",
"Topic :: Software Development :: Libraries :: Python Modules",
"License :: OSI Approved :: Apache Software License",
]

[project.urls]
Homepage = "https://github.com/scaleapi/scale-agentex-python"
Repository = "https://github.com/scaleapi/scale-agentex-python"

[project.scripts]
agentex = "agentex.lib.cli.commands.main:app"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

# Ship only agentex/lib/*, pulled in from the parent repo's `src/agentex/lib`
# tree. The rest of agentex.* (the Stainless-generated client) ships from the
# sibling agentex-client package, which this package pins as a runtime dep.
# Stainless explicitly preserves `src/agentex/lib/` across codegen (per
# CONTRIBUTING.md), so it's safe to keep the source where it is.
[tool.hatch.build.targets.wheel]
bypass-selection = true

# Builds the ../src/agentex/lib force-include map per-file (see hatch_build.py)
# so test files can be pruned — force-include ignores `exclude` (hatchling #1395).
[tool.hatch.build.targets.wheel.hooks.custom]
path = "hatch_build.py"

# Sdist deferred: hatchling can't represent the wheel's ../src/agentex/lib
# force-include in an sdist include list. CI + bin/publish-pypi pass --wheel.
[tool.hatch.build.targets.sdist]
include = [
"/pyproject.toml",
"/README.md",
]
16 changes: 14 additions & 2 deletions bin/check-release-environment
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
#!/usr/bin/env bash

# This script is run by Release Doctor to validate the release environment.
# After the dual-package split (slim agentex-client + heavy agentex-sdk),
# both PyPI tokens must be present — one for each package name. If only
# PYPI_TOKEN is set, fall back to using it for both (back-compat for legacy
# single-token setups, which forces an account-scoped token).

errors=()

if [ -z "${PYPI_TOKEN}" ]; then
errors+=("The PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets.")
# Heavy `agentex-sdk` token (existing PyPI name).
if [ -z "${AGENTEX_PYPI_TOKEN}" ] && [ -z "${PYPI_TOKEN}" ]; then
errors+=("The AGENTEX_PYPI_TOKEN secret has not been set (and no fallback PYPI_TOKEN). Add it in repo secrets so the heavy 'agentex-sdk' package can be published.")
fi

# Slim `agentex-client` token (new PyPI name).
if [ -z "${AGENTEX_CLIENT_PYPI_TOKEN}" ] && [ -z "${PYPI_TOKEN}" ]; then
errors+=("The AGENTEX_CLIENT_PYPI_TOKEN secret has not been set (and no fallback PYPI_TOKEN). Add it in repo secrets so the slim 'agentex-client' package can be published. Falling back to PYPI_TOKEN requires an account-scoped token.")
fi

lenErrors=${#errors[@]}
Expand Down
13 changes: 10 additions & 3 deletions bin/publish-pypi
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
#!/usr/bin/env bash

# Publish slim (root) before heavy (adk/): heavy pins slim, so a slim-first
# failure aborts before shipping a heavy that needs an unreleased client.

set -eux

rm -rf dist
mkdir -p dist
uv build
uv publish --token=$PYPI_TOKEN
# --wheel: the heavy's cross-dir force-include can't build via sdist.
uv build --all-packages --wheel

# --check-url makes the per-component-tag double-trigger idempotent.
uv publish --check-url https://pypi.org/simple/ --token="${AGENTEX_CLIENT_PYPI_TOKEN:-$PYPI_TOKEN}" dist/agentex_client-*.whl
Comment on lines +12 to +13

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 agentex-client publish will fail until AGENTEX_CLIENT_PYPI_TOKEN is configured

When AGENTEX_CLIENT_PYPI_TOKEN is absent from repo secrets (the workflow comment explicitly notes it hasn't been created yet), this line resolves to ${PYPI_TOKEN} — which is secrets.AGENTEX_PYPI_TOKEN, a project-scoped token for agentex-sdk. PyPI project-scoped tokens cannot publish to a different project, so the agentex-client publish will get a 403 and abort the release, leaving the heavy agentex-sdk wheel unpublished (due to set -eux). The AGENTEX_CLIENT_PYPI_TOKEN secret (either a global upload token or one scoped to the new agentex-client project) must be added to repo secrets before this release workflow runs.

Prompt To Fix With AI
This is a comment left during a code review.
Path: bin/publish-pypi
Line: 12-13

Comment:
**`agentex-client` publish will fail until `AGENTEX_CLIENT_PYPI_TOKEN` is configured**

When `AGENTEX_CLIENT_PYPI_TOKEN` is absent from repo secrets (the workflow comment explicitly notes it hasn't been created yet), this line resolves to `${PYPI_TOKEN}` — which is `secrets.AGENTEX_PYPI_TOKEN`, a project-scoped token for `agentex-sdk`. PyPI project-scoped tokens cannot publish to a different project, so the `agentex-client` publish will get a 403 and abort the release, leaving the heavy `agentex-sdk` wheel unpublished (due to `set -eux`). The `AGENTEX_CLIENT_PYPI_TOKEN` secret (either a global upload token or one scoped to the new `agentex-client` project) must be added to repo secrets before this release workflow runs.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Cursor Fix in Claude Code Fix in Codex

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AGENTEX_CLIENT_PYPI_TOKEN has been added to repo secrets. The comment is stale.

uv publish --check-url https://pypi.org/simple/ --token="${AGENTEX_PYPI_TOKEN:-$PYPI_TOKEN}" dist/agentex_sdk-*.whl
Loading
Loading