Skip to content

[AAASM-4547] 🐛 (python-sdk): Register targets gRPC endpoint + loud unregistered warning - #250

Merged
Chisanan232 merged 4 commits into
masterfrom
v0.0.1/AAASM-4547/fix/register_grpc
Jul 13, 2026
Merged

[AAASM-4547] 🐛 (python-sdk): Register targets gRPC endpoint + loud unregistered warning#250
Chisanan232 merged 4 commits into
masterfrom
v0.0.1/AAASM-4547/fix/register_grpc

Conversation

@Chisanan232

@Chisanan232 Chisanan232 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes the Python SDK portion of AAASM-4547 (cross-repo bug; node = AAASM-4468, go = docs). Two scoped changes to the agent-registration path:

  1. Registration targets the gateway gRPC endpoint (:50051), not the REST URL (:7391). Agent registration is the SDK's one direct gateway gRPC call (AgentLifecycleService.Register via aa-sdk-client, ADR 0004), which must reach the gateway's gRPC port — distinct from the REST gateway_url. A new resolve_gateway_grpc_endpoint() derives it from AA_GATEWAY_ENDPOINT → the resolved REST host with the gRPC port substituted → the loopback default, and init_assembly threads it into register. Previously the endpoint was left unset (native default 127.0.0.1:50051), so a non-loopback gateway host would never register against the right host.

  2. Loud unregistered warning + registered flag instead of a silent None fallback. When registration cannot run — native agent_assembly._core absent (pure-Python / unsupported-platform install) or the gateway gRPC endpoint unreachable/rejecting — the SDK previously returned a clean-looking context for an agent that never reached the gateway. It now emits a prominent sys.stderr warning (mirroring the Node SDK's warnAgentUnregistered, citing AAASM-4547) and surfaces ctx.registered so callers can detect the gap programmatically. Init still proceeds (proxy / eBPF stay authoritative); enforce still fails init closed on a register error.

Type of Change

  • 🔧 Bug fix

Breaking Changes

  • No

AssemblyContext gains a registered: bool field (defaults True) — additive.

Related Issues

Testing

  • Unit tests added/updated
  • Manual testing performed

resolve_gateway_grpc_endpoint unit tests (env override, REST→gRPC port swap, non-loopback host preserved, loopback default); loud-warn path tests (native absent, native-present-no-client, register-failure-under-observe all warn + set registered=False; successful register sets registered=True). Existing register-wiring tests updated to expect the derived endpoint. Full suite: 790 passed, 16 skipped. ruff check/ruff format/mypy clean on changed files.

Live check: booted aa-gateway on 127.0.0.1:50051 and ran init_assembly(gateway_url="http://127.0.0.1:7391") with the native _core present. Registration correctly dialed the derived :50051 endpoint (the gRPC service responded with an application-level rejection — proving connectivity to the right port, vs the "unreachable" error when nothing listens), and the loud warning + ctx.registered=False fired end-to-end. The full "agent appears in GET /api/v1/agents" assertion could not be completed in-env: aa-api-server (REST :7391) is not built locally, and the only available aa-gateway binary (Jun-25) rejects the newer _core registration handshake (version skew) — both environmental, not defects in this change.

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • All tests passing

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rk7iwwAuGv6HbwK8hY8Fbr

Chisanan232 and others added 4 commits July 13, 2026 21:46
Registration is the SDK's only direct gateway gRPC call and must target the
gateway's gRPC port (:50051), not the REST gateway_url (:7391). Add a resolver
that derives the gRPC endpoint from AA_GATEWAY_ENDPOINT, else the resolved REST
host with the gRPC port substituted, else the loopback default.

Refs AAASM-4547

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rk7iwwAuGv6HbwK8hY8Fbr
Agent registration is the SDK's one direct gateway gRPC call and must reach the
gateway's gRPC port (:50051). init_assembly now resolves that endpoint from the
gateway host (via resolve_gateway_grpc_endpoint) and threads it into the native
register instead of leaving it unset — so a non-loopback gateway host registers
against that host's gRPC port rather than always 127.0.0.1, and the REST
gateway_url (:7391) is never dialed for registration.

Refs AAASM-4547

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rk7iwwAuGv6HbwK8hY8Fbr
… gap

connect_runtime_client returning None (native _core absent on a pure-Python
install) or a register failure was previously swallowed silently, so init
returned a clean-looking context for an agent that never reached the gateway and
will never appear in the dashboard. Emit a loud stderr warning (mirroring the
Node SDK's warnAgentUnregistered) and surface a `registered` flag on the
AssemblyContext so callers can detect the gap programmatically. Init still
proceeds (proxy / eBPF stay authoritative); enforce still fails init closed on a
register error.

Refs AAASM-4547

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rk7iwwAuGv6HbwK8hY8Fbr
Cover resolve_gateway_grpc_endpoint (env override, REST->gRPC port swap,
non-loopback host preserved, loopback default) and the loud unregistered path:
native absent, native-present-no-client, and register-failure-under-observe all
warn to stderr and set ctx.registered False; a successful register sets it True.

Refs AAASM-4547

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rk7iwwAuGv6HbwK8hY8Fbr
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Chisanan232

Copy link
Copy Markdown
Contributor Author

Review — AAASM-4547 (python-sdk portion) · Claude Code

Reviewed against the 4-point checklist. Verdict: APPROVE for the python scope (not merging/approving — human sign-off required).

1. CI — GREEN

All 26 check runs pass or are skipped; no RED. CI Success, SonarCloud, CodeQL, codecov/patch, unit/integration/contract suites, pip-audit, docs-build all green. No fixes needed.

2. Scope vs ticket — delivers the python interim AC

  • (a) Register targets gRPC :50051, not REST :7391 — new resolve_gateway_grpc_endpoint() (precedence: AA_GATEWAY_ENDPOINT → REST host with gRPC port substituted → 127.0.0.1:50051 loopback), threaded through init_assembly_register_agent_with_gateway(gateway_endpoint=…)register_agent(...). Previously the endpoint was left unset (native default), so a non-loopback host never registered against the right host. ✅
  • (b) Loud warning + registered flag replaces silent None_warn_agent_unregistered() writes straight to sys.stderr (unsilenceable by logging), mirroring the Node SDK; AssemblyContext.registered: bool (defaults True, additive) surfaces the state programmatically. Fires on native-absent, native-present-but-no-client, and register-failure-under-observe. ✅
  • (c) Testsresolve_gateway_grpc_endpoint (env override / port-swap / non-loopback preserved / loopback default) + loud-warn/registered paths + enforce-fails-closed + endpoint-wiring assertions. ✅

This satisfies the ticket's minimum python AC bullet — "Python's silent None fallback is replaced with a Node-style explicit warning at minimum, even if the full fix lands later." The ticket's fuller AC (Option A/B: auto-manage/ship aa-runtime so the agent actually lands in GET /api/v1/agents end-to-end) is intentionally out of scope here — it requires aa-runtime distribution work in the agent-assembly repo, not the SDK. Correctly scoped as the interim posture. Ready to merge for the python portion.

3. Side effects — none

  • enforce still fails closed: the if enforcement_mode == "enforce": raise path is preserved (register failure aborts init before the warning); covered by test_enforce_mode_propagates_register_failure.
  • REST gateway_url still drives the HTTP client unchanged — the new resolver only reads its host; existing callers are not rerouted.
  • register_agent already accepted gateway_endpoint on master (runtime_interceptor.py is not in this diff) — the PR only wires the resolved value through, no misroute. Team/parent lineage forwarding intact (asserted in the updated wiring tests).
  • Diff is exactly the 4 intended files (assembly.py, gateway_resolver.py, test_gateway_resolver.py, test_init_registration.py), +251/-20. No aaasm4434 stash leakage — working tree clean, diff-stat matches.
  • Local validation on the branch: 790 passed, 16 skipped; ruff check, ruff format --check, and mypy all clean on the 4 changed files. (Repo-wide ruff/mypy noise in untouched files — pre-existing; native _core not built locally — CI green confirms.)

4. Front-end — N/A

python-sdk is a library; no front-end surface. No FE change.


APPROVE (advisory — not merging/approving per review mandate).

🤖 Generated with Claude Code

@Chisanan232
Chisanan232 merged commit 54377b2 into master Jul 13, 2026
26 checks passed
@Chisanan232
Chisanan232 deleted the v0.0.1/AAASM-4547/fix/register_grpc branch July 13, 2026 14:37
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