refactor(types): promote protocol types to agentex.protocol.*#371
Open
max-parke-scale wants to merge 2 commits into
Open
refactor(types): promote protocol types to agentex.protocol.*#371max-parke-scale wants to merge 2 commits into
max-parke-scale wants to merge 2 commits into
Conversation
Moves the JSON-RPC envelope types and ACP method-param types out of the
hand-authored ADK overlay (agentex.lib.types.*) into a new canonical
location at agentex.protocol.*. Back-compat shims at the old paths
re-export the same classes, so existing imports continue to work.
Motivation:
The existing layout puts protocol-shape types under agentex.lib.types.
That means a REST-only consumer who just wants typed JSON-RPC envelopes
(e.g. egp-api-backend, which today hand-rolls a ~600-line gateway
constructing `{"jsonrpc": "2.0", "method": "task/create", ...}` dicts by
hand) can't import the types without pulling in the full heavy ADK
runtime (~31 deps including temporalio, fastapi, claude-agent-sdk, etc.).
This is the first step toward letting that consumer drop hand-rolled
dict literals in favor of typed CreateTaskParams / SendMessageParams /
SendEventParams / JSONRPCRequest / JSONRPCResponse models, ahead of the
forthcoming slim-package split (a separate PR).
Scope:
- Move src/agentex/lib/types/acp.py → src/agentex/protocol/acp.py
- Move src/agentex/lib/types/json_rpc.py → src/agentex/protocol/json_rpc.py
- json_rpc.py: switch from `agentex.lib.utils.model_utils.BaseModel`
(which transitively imports pyyaml) to `pydantic.BaseModel` directly.
These classes don't use any model_utils extensions (from_yaml, to_json,
populate_by_name) so the swap is behavior-preserving.
- Add re-export shims at the old paths so existing
`from agentex.lib.types.{acp,json_rpc} import ...` imports continue
to work. Identity check confirms the shimmed and canonical classes
are the same objects.
- Update all internal usages within agentex.lib.* to import from the
canonical path (9 files in src/agentex/lib + 1 in tests/).
Files moved use only pydantic + agentex.types.{Task,Agent,Event,
TaskMessageContent} — all slim-safe deps. Other agentex.lib.types.*
modules with heavier deps (fastacp pulls temporal, converters pulls
openai-agents) are left in place.
Verified locally:
- ruff check . → All checks passed
- Wheel build → ships both agentex/protocol/* and shims at
agentex/lib/types/{acp,json_rpc}.py
- Import test from a fresh editable install: both canonical and shim
paths resolve to the same class objects (identity-checked)
Zero install-time impact for existing consumers — same import paths
keep working.
Tracking: AGX1-292 (the slim/heavy split that motivates this refactor
lands as a follow-up PR).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
max-parke-scale
added a commit
that referenced
this pull request
May 27, 2026
…dk split Stacks on #371 (which moved protocol types to agentex.protocol.*). Together they enable REST-only consumers to install just the slim package and use typed protocol types without pulling the full ADK stack. Two-package layout: - agentex-sdk-client (slim, root pyproject.toml) * 6 deps: httpx, pydantic, typing-extensions, anyio, distro, sniffio * Ships agentex/{__init__.py, _*.py, _utils/, types/, resources/, protocol/, py.typed} * requires-python >= 3.11 * Stainless-managed * Slim wheel excludes src/agentex/lib/** - agentex-sdk (heavy, adk/pyproject.toml) * Depends on agentex-sdk-client>=0.11.4,<0.12 (lockstep, see comment) * Plus 31 ADK deps: temporalio, fastapi, redis, MCP, LLM providers, observability, CLI surface * Ships only agentex/lib/* via hatchling force-include from ../src/agentex/lib (lib/ stays at its historical location) * requires-python >= 3.12 (lib uses `from typing import override`, a 3.12+ stdlib API) * Hand-authored overlay; entire adk/ directory must be preserved across Stainless codegen via `keep_files: ["adk/**"]` Existing consumers (`pip install agentex-sdk`) see no change: heavy depends on slim, so the slim deps install transitively. Both packages contribute disjoint files to the agentex.* namespace. Release / publish wiring: - bin/publish-pypi publishes slim BEFORE heavy. Heavy depends on slim, so if the slim publish errors we abort before shipping a broken heavy that pins an unreleased slim. (Staff-engineer review fix.) - bin/check-release-environment validates BOTH PyPI tokens, with the legacy PYPI_TOKEN as a back-compat fallback. - .github/workflows/publish-pypi.yml passes AGENTEX_SDK_CLIENT_PYPI_TOKEN and AGENTEX_PYPI_TOKEN to the script. - release-please-config.json: two-package mode with components (agentex-sdk-client at root, agentex-sdk at adk/), and include-component-in-tag=true so tags become e.g. `agentex-sdk-client-v0.11.4` and `agentex-sdk-v0.11.4`. - .release-please-manifest.json: seeds adk/ at 0.11.4 so the first release produces matched versions. CI build job runs `rye build --wheel` for both packages; --wheel only (not sdist) because adk's wheel uses cross-directory force-include which can't resolve from inside an unpacked sdist tarball. Tag scheme breakage flagged with `!` in commit/PR title — downstream tooling that filters by raw `v*` tags will need updates. Required maintainer follow-ups before this can ship: - Stainless dashboard: add `adk/**` to keep_files; reduce dashboard dep-list to the 6 slim-base deps so codegen doesn't re-add the 31 ADK deps to root pyproject's `dependencies = [...]`. - PyPI: claim `agentex-sdk-client` package name; add AGENTEX_SDK_CLIENT_PYPI_TOKEN to repo secrets. - (Defer to a follow-up PR) post-codegen CI guardrail that asserts root pyproject's `dependencies = [...]` matches the 6-dep slim set. Verified locally: - Both wheels build cleanly via `rye build --wheel` - Slim ships agentex/protocol/* and excludes agentex/lib/* - Heavy ships only agentex/lib/* (incl. the back-compat shims from #371) - Dual install on Python 3.13: from agentex import Agentex AND from agentex.protocol.acp import RPCMethod AND from agentex.lib.utils.logging import make_logger AND from agentex.lib.types.acp import RPCMethod (shim) — all resolve; shim and canonical identity-check as the same class objects. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
Three issues from Greptile's review (4/5 confidence, all P1/P2):
1. Back-compat shim at `agentex.lib.types.acp` was missing two public
names from the original module: `RPC_SYNC_METHODS` and
`PARAMS_MODEL_BY_METHOD`. External consumers importing those from the
old path would have hit ImportError, breaking the PR's "zero install-
time impact" guarantee. Added both to the re-export list.
2. `agentex.protocol.json_rpc` silently dropped `from_attributes=True`
and `populate_by_name=True` config when switching from
`model_utils.BaseModel` to plain `pydantic.BaseModel`. Restored via
an explicit `model_config = ConfigDict(...)` on all three classes,
with a comment explaining why. The previous version inherited these
flags transitively; making them explicit + documented avoids drift.
3. All 10 CLI scaffolding templates (`agentex init`) generated
`from agentex.lib.types.acp import ...` — works via the shim but
immediately stale on the day this PR establishes
`agentex.protocol.acp` as canonical. Updated all templates to use
the new path so scaffolded code starts on the right foot.
Verified locally:
- ruff check . → All checks passed
- shim re-exports all 7 original symbols (5 classes + 2 module-level
constants), identity-checked vs canonical
- JSONRPCRequest/Response/Error all have
`model_config.get('from_attributes') is True` and
`populate_by_name is True`
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
Author
|
@greptile review |
Contributor
|
This would be a breaking change right? Any consumer that imports these types (any agentex agent using them) will have to update their import paths |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Moves the JSON-RPC envelope types (
JSONRPCRequest/Response/Error) and ACP method-param types (CreateTaskParams,SendMessageParams,SendEventParams,CancelTaskParams,RPCMethod) out ofagentex.lib.types.*into a new canonical location atagentex.protocol.*. Back-compat shims at the old paths re-export the same classes — existing imports continue to work.Zero install-time impact for existing consumers. Same import paths keep working.
Tracking: AGX1-292. First of two PRs:
agentex.protocol.*as the canonical location for protocol typesagentex-sdk-clientpackage (which will shipagentex.protocol.*but notagentex.lib.*), letting REST-only consumers likepackages/egp-api-backenddrop hand-rolled JSON-RPC dict literals in favor of these typed shapesMotivation
egp-api-backendtoday hand-rolls a ~600-line JSON-RPC gateway ategp_api_backend/server/internal/interfaces/services/evaluation_task/evaluation_task_gateways/agentex_output_evaluation_task_gateway.py. Sample:These shapes map directly onto the types defined in
agentex.lib.types.acpandagentex.lib.types.json_rpc. They hand-roll because importing those types currently requires pulling in the full ADK runtime (~31 deps including temporalio, fastapi, claude-agent-sdk, etc.).Moving the protocol types out of
agentex.lib.*is the prerequisite for letting them ship in a future slim-package install.Changes
src/agentex/protocol/__init__.pysrc/agentex/protocol/acp.pysrc/agentex/lib/types/acp.py; no other changesrc/agentex/protocol/json_rpc.pysrc/agentex/lib/types/json_rpc.py; swappedfrom agentex.lib.utils.model_utils import BaseModel→from pydantic import BaseModel(behavior-preserving — these classes don't use anymodel_utilsextensions likefrom_yaml/to_json/populate_by_name)src/agentex/lib/types/acp.pysrc/agentex/lib/types/json_rpc.pysrc/agentex/lib/*tests/test_header_forwarding.pySlim-safety of moved files
Both moved modules depend only on
pydanticandagentex.types.{Task, Agent, Event, TaskMessageContent}— all already-slim-safe (Stainless-generated client surface + pydantic, which is in the bare client's 6 base deps).Other
agentex.lib.types.*modules have heavier deps (e.g.fastacp.pypulls temporal,converters.pypulls openai-agents) and are intentionally left in place. They can be promoted in follow-up PRs if/when other consumers need them slim-safe.Verification (local)
Test plan
from agentex.lib.types.acp import CreateTaskParamscontinues to work without change.from agentex.protocol.acp import CreateTaskParamsworks as the new canonical path.Greptile Summary
This PR promotes the JSON-RPC envelope types (
JSONRPCRequest/Response/Error) and ACP method-param types (CreateTaskParams,SendMessageParams, etc.) fromagentex.lib.types.*into a new canonicalagentex.protocol.*package, with back-compat shims at the old paths. The motivation is to enable a future slimagentex-sdk-clientpackage that ships only pydantic + stainless-generated types without the full ADK runtime.agentex.protocol.{acp,json_rpc}created; both previous concern points from earlier review (missingRPC_SYNC_METHODS/PARAMS_MODEL_BY_METHODin the shim, and the droppedmodel_utils.BaseModelconfig flags) are fully addressed in this version.agentex.lib.types.{acp,json_rpc}re-export all symbols including module-level constants; identity equality verified (A is B).Confidence Score: 5/5
This is a pure refactor — no logic changes, only type relocations with re-export shims at the old paths. Safe to merge.
The two issues flagged in a prior review pass (missing module-level constants in the shim, and the dropped model_utils.BaseModel config) are both fully resolved in this version. All symbols are re-exported at the old paths, the model_config is explicitly preserved in json_rpc.py with a clear comment, and every internal consumer has been updated to the new canonical path. No logic is changed anywhere.
No files require special attention. The shim files and canonical modules are consistent with each other.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD subgraph Canonical["agentex.protocol (new canonical)"] PA["agentex.protocol.acp\nRPCMethod, CreateTaskParams\nSendMessageParams, SendEventParams\nCancelTaskParams, RPC_SYNC_METHODS\nPARAMS_MODEL_BY_METHOD"] PJ["agentex.protocol.json_rpc\nJSONRPCRequest\nJSONRPCResponse\nJSONRPCError"] end subgraph Shims["agentex.lib.types (back-compat shims)"] LA["agentex.lib.types.acp\n(re-exports from protocol.acp)"] LJ["agentex.lib.types.json_rpc\n(re-exports from protocol.json_rpc)"] end subgraph Consumers["Internal consumers (updated)"] BS["base_acp_server.py"] TS["temporal_task_service.py"] WF["workflow.py"] IMPL["fastacp/impl/*.py"] TESTS["tests/"] TMPL["cli templates (*.j2)"] end PA -->|re-export| LA PJ -->|re-export| LJ BS --> PA BS --> PJ TS --> PA WF --> PA IMPL --> PA TESTS --> PA TESTS --> PJ TMPL --> PAReviews (3): Last reviewed commit: "fix(types): address Greptile review feed..." | Re-trigger Greptile