Skip to content

feat(deps)!: split ADK/server deps into optional [adk]/[cli]/[observability] extras#368

Closed
max-parke-scale wants to merge 1 commit into
maxparke/agx1-292-drop-unused-runtime-depsfrom
maxparke/agx1-292-extras-split-adk
Closed

feat(deps)!: split ADK/server deps into optional [adk]/[cli]/[observability] extras#368
max-parke-scale wants to merge 1 commit into
maxparke/agx1-292-drop-unused-runtime-depsfrom
maxparke/agx1-292-extras-split-adk

Conversation

@max-parke-scale
Copy link
Copy Markdown
Contributor

@max-parke-scale max-parke-scale commented May 26, 2026

Summary

Stacked on #367. Second PR under AGX1-292. Do not merge before #367 lands.

Splits the SDK into a 6-dep bare client plus three opt-in extras:

Install command Deps Use case
pip install agentex-sdk 6 REST client only (from agentex import Agentex, AsyncAgentex)
pip install agentex-sdk[cli] 6 + 11 Just CLI helpers (agentex.lib.cli.*, agentex.lib.sdk.config.*) + the agentex CLI
pip install agentex-sdk[observability] 6 + 4 Just tracing processors (agentex.lib.core.tracing.*)
pip install agentex-sdk[adk] 6 + 31 Full ADK: includes [cli] + [observability] + ACP server + Temporal + Redis + MCP + LLM providers

[cli] and [observability] are deliberately scoped to keep client-side tools (e.g. sgpctl, voice-agent tracing setup) from pulling temporal/fastapi/redis just to use a few helpers.

Also updates all 10 CLI scaffolding templates (agentex init) to pin agentex-sdk[adk] so newly bootstrapped agent projects work out of the box.

Why

agentex.lib is import-lazy (empty __init__.py), so a pure REST consumer never touches the heavy deps at import time. But pip still installs all of them today, dragging in temporalio, fastapi, redis, kubernetes, litellm, anthropic, openai-agents, claude-agent-sdk, observability stacks, etc. — for consumers who just want to make API calls or use a small slice of lib.

Audit: AGX1-292.

BREAKING CHANGE

Consumers who use agentex.lib.* must switch from agentex-sdk to one of:

  • agentex-sdk[cli] if they only use agentex.lib.cli.* or agentex.lib.sdk.config.*
  • agentex-sdk[observability] if they only use agentex.lib.core.tracing.* / .observability.*
  • agentex-sdk[adk] for full agent authoring (FastACP + Temporal + providers + …)

The REST client (from agentex import Agentex, AsyncAgentex) is unchanged and works with a bare install.

Known internal consumer blast radius

GitHub code-search across the scaleapi org. Migration PRs being opened in parallel:

Repo pyproject.toml pins Migration PR
scaleapi/agentex-agents 117 (~106 after excluding stuck/local pins) [adk] (coming)
scaleapi/models 10 (9 after excluding capped pins) [adk] scaleapi/models#18648
scaleapi/sgp 3 [cli] for sgpctl, [observability] for voice-agents scaleapi/sgp#3114 (being revised)
scaleapi/scale-agentex 2 [adk] scaleapi/scale-agentex#251
scaleapi/fna1-ops 0 toml / 1 requirements.txt [adk] (coming)

The CLI templates inside this repo are fixed in this PR so the agentex init flow stays working.

Verification

python -m build --wheel

unzip -p dist/agentex_sdk-*.whl '*.dist-info/METADATA' | grep -E '^Requires-Dist:' | grep -vc 'extra =='
# 6

unzip -p dist/agentex_sdk-*.whl '*.dist-info/METADATA' | grep '^Provides-Extra:'
# Provides-Extra: adk
# Provides-Extra: aiohttp
# Provides-Extra: cli
# Provides-Extra: dev
# Provides-Extra: observability

# per-extra dep counts
for x in cli observability adk; do
  echo "[$x]: $(unzip -p dist/agentex_sdk-*.whl '*.dist-info/METADATA' | grep -c "extra == '$x'") deps"
done
# [cli]: 11 deps
# [observability]: 4 deps
# [adk]: 31 deps

Test plan

  • CI builds the wheel and Validate PR title passes (note the ! — breaking change).
  • Smoke-test pip install agentex-sdk in a clean env → from agentex import Agentex works; import agentex.lib.adk fails with ModuleNotFoundError (expected).
  • Smoke-test pip install agentex-sdk[adk] → both work.
  • Smoke-test pip install agentex-sdk[cli]from agentex.lib.cli.handlers.agent_handlers import prepare_cloud_build_context works.
  • CHANGELOG / release notes call out the install-time change.
  • Internal consumer sweep PRs land alongside or after this PR.
  • agentex init against an updated template produces a project that imports successfully.

Rollout note

Worth a minor or major version bump to flag the install-time break in release notes.

Greptile Summary

This PR splits agentex-sdk's runtime dependencies into a lean base install (6 deps, REST client only) and a [adk] optional extra (6 + 31 deps, full agent development kit), with intermediate [cli] and [observability] extras as sub-components of [adk]. All 10 CLI scaffolding templates generated by agentex init are updated to pin agentex-sdk[adk] so newly scaffolded projects continue to work out of the box.

  • pyproject.toml: Moves 31 ADK/server dependencies (Temporal, FastAPI, Redis, LLM providers, CLI tools, observability) out of bare dependencies into [adk], which composes [cli] + [observability] sub-extras using the self-referential PEP 508 syntax.
  • CLI templates (*.j2): Uniform agentex-sdkagentex-sdk[adk] substitution across all 10 template pairs (pyproject.toml.j2 + requirements.txt.j2).

Confidence Score: 4/5

The dep split is mechanically correct, but the agentex binary remains registered unconditionally while its runtime imports land exclusively in the new optional extras, breaking the CLI on a bare install.

The packaging restructuring is logically sound — the self-referential extra syntax is valid PEP 508, all 10 templates are consistently updated, and the [cli] extra is correctly scoped (CLI handlers verified to not import scale-gp or ADK-only deps). The one outstanding defect is the unconditional [project.scripts] entry point for agentex that invokes agentex.lib.cli.commands.main:app, which immediately imports typer — a dep now living only in [cli]/[adk]. Any bare pip install agentex-sdk user who runs agentex will get a ModuleNotFoundError with no actionable guidance.

pyproject.toml — the [project.scripts] entry point at line 107 registers the agentex CLI unconditionally regardless of which extras are installed.

Important Files Changed

Filename Overview
pyproject.toml Core packaging change: moves 31 ADK deps into optional extras ([cli], [observability], [adk]); the agentex console-script entry point remains unconditionally registered while its runtime imports (typer, etc.) are now only in the [cli]/[adk] extras, causing a ModuleNotFoundError on a bare install.
src/agentex/lib/cli/templates/default/pyproject.toml.j2 Uniform agentex-sdk → agentex-sdk[adk] substitution; correct and consistent with the packaging change.
src/agentex/lib/cli/templates/default/requirements.txt.j2 Uniform agentex-sdk → agentex-sdk[adk] substitution in requirements.txt template; correct.
src/agentex/lib/cli/templates/temporal-openai-agents/pyproject.toml.j2 Updated to agentex-sdk[adk]; retains explicit openai-agents>=0.4.2 and temporalio pins which are satisfied by the [adk] extra's strict openai-agents==0.14.1 pin.
src/agentex/lib/cli/templates/default-langgraph/pyproject.toml.j2 Updated to agentex-sdk[adk]; correct — langgraph-checkpoint is now provided transitively via [adk].
src/agentex/lib/cli/templates/sync-openai-agents/pyproject.toml.j2 Updated to agentex-sdk[adk]; correct and consistent with other template updates.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["pip install agentex-sdk"] --> B["Base deps (6)\nhttpx, pydantic,\ntyping-extensions, anyio,\ndistro, sniffio"]
    
    C["pip install agentex-sdk[adk]"] --> D["[cli] extra (11)\ntyper, questionary, rich,\nkubernetes, jinja2, pyyaml,\npython-on-whales, etc."]
    C --> E["[observability] extra (4)\nddtrace, opentelemetry-api,\nopentelemetry-sdk,\njson_log_formatter"]
    C --> F["[adk]-only deps (16)\nfastapi, starlette, uvicorn,\ntemporalio, redis, litellm,\nopenai-agents, claude-agent-sdk,\nscale-gp, mcp, etc."]
    C --> B

    G["pip install agentex-sdk[aiohttp]"] --> H["aiohttp>=3.10.10,<4\nhttpx_aiohttp"]
    G --> B

    I["agentex init (CLI templates)"] --> J["Generated pyproject.toml\nagentex-sdk[adk]"]

    style B fill:#d4edda,stroke:#28a745
    style D fill:#cce5ff,stroke:#007bff
    style E fill:#cce5ff,stroke:#007bff
    style F fill:#cce5ff,stroke:#007bff
    style H fill:#fff3cd,stroke:#ffc107
Loading

Reviews (3): Last reviewed commit: "feat(deps)!: split ADK/server deps into ..." | Re-trigger Greptile

…bility] extras

Bare `pip install agentex-sdk` now installs only the 6 deps the
Stainless-generated REST client actually needs (`httpx`, `pydantic`,
`typing-extensions`, `anyio`, `distro`, `sniffio`). Everything used by the
`agentex.lib.*` surface — CLI, ACP server, Temporal workflows, LLM provider
integrations, observability — moves to optional extras.

Three extras for different consumer slices:
- `[cli]` (11 deps) — `agentex.lib.cli.*`, `agentex.lib.sdk.config.*`, and the
  `agentex` CLI entry point. For tools like sgpctl that need the CLI helpers
  without temporal/fastapi/redis.
- `[observability]` (4 deps) — `agentex.lib.core.tracing.*`,
  `agentex.lib.core.observability.*`. For consumers that only attach the
  SGP/Datadog/OTel tracing processors.
- `[adk]` (31 deps) — union of [cli] + [observability] + ACP server + Temporal
  + Redis + MCP + LLM providers. Full agent authoring.

The current install behavior is recoverable with `pip install agentex-sdk[adk]`.
CLI templates (`agentex init`) are updated to pin `agentex-sdk[adk]` so newly
bootstrapped agents work out of the box.

BREAKING CHANGE: consumers who rely on `agentex.lib.*` must pin one of the new
extras instead of bare `agentex-sdk`. The REST client surface
(`from agentex import Agentex, AsyncAgentex`) is unchanged and still works with
a bare install.

Verified by building the wheel locally:
- `Requires-Dist` (base): 6
- `Requires-Dist; extra == 'cli'`: 11
- `Requires-Dist; extra == 'observability'`: 4
- `Requires-Dist; extra == 'adk'`: 31

Stacked on AGX1-292 / #367 (drop unused deps).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@max-parke-scale max-parke-scale force-pushed the maxparke/agx1-292-extras-split-adk branch from 4621f8a to d40200b Compare May 26, 2026 21:31
@max-parke-scale max-parke-scale changed the title feat(deps)!: split ADK/server deps into optional [adk] extra feat(deps)!: split ADK/server deps into optional [adk]/[cli]/[observability] extras May 26, 2026
@max-parke-scale
Copy link
Copy Markdown
Contributor Author

Closing in favor of a non-breaking redesign: publish a new lean sibling package agentex-sdk-client containing only the Stainless REST client surface (agentex/{__init__.py, _*.py, types/, resources/}) with 6 base deps. agentex-sdk keeps shipping agentex/lib/* and adds agentex-sdk-client as a runtime dep — existing consumers (pip install agentex-sdk) see no change. Only REST-only consumers like packages/egp-api-backend (currently hand-rolling clients to avoid dep weight) need to migrate.

This avoids the breaking-change blast radius (130+ files across 5 repos) that this PR would have required.

Tracking: AGX1-292. PR #367 (drop dead deps + exclude tests from wheel) stays open as a no-breaking-change cleanup.

🤖 — posted via Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant