Skip to content

[AAASM-3683] 🔒 (python-sdk): Pass language-SDK package version through the FFI into the handshake#175

Merged
Chisanan232 merged 5 commits into
masterfrom
v0.0.1/AAASM-3683/sdk_version_passthrough
Jun 24, 2026
Merged

[AAASM-3683] 🔒 (python-sdk): Pass language-SDK package version through the FFI into the handshake#175
Chisanan232 merged 5 commits into
masterfrom
v0.0.1/AAASM-3683/sdk_version_passthrough

Conversation

@Chisanan232

Copy link
Copy Markdown
Contributor

Description

Follow-up to agent-assembly AAASM-3683. AAASM-3666 signs an sdk_version into the IPC handshake, but it was sourced from the shared aa-sdk-client crate version. This PR makes the Python SDK forward its PyPI package version through the FFI so the version signed into the handshake reflects the installed SDK release, giving AAASM-3571 accurate downgrade detection.

  • Re-pins aa-core/aa-proto/aa-sdk-client to agent-assembly AAASM-3683 (adds sdk_version to AssemblyConfig + threads it through spawn_ipc_thread). Must be re-pinned to the squash-merge SHA once agent-assembly PR #1226 lands.
  • RuntimeClient.connect now accepts optional agent_id and sdk_version and passes them into spawn_ipc_thread (the agent id is also signed into the handshake per AAASM-3587).
  • connect_runtime_client resolves the installed version via importlib.metadata.version("agent-assembly") (falling back to agent_assembly.__version__) and forwards it. None falls back to the crate version (no regression vs 3666). An older native connect is retried with the legacy positional signature.

Type of Change

  • ✨ New feature

Breaking Changes

  • No

connect's new params are optional; the Python layer retries the legacy signature against an older native build.

Related Issues

  • Related JIRA ticket: AAASM-3683
  • Depends on agent-assembly PR #1226 (re-pin to merge SHA before merge)

Testing

  • Unit tests added/updated

  • .venv/bin/python -m pytest test/ → 667 passed, 16 skipped (native/optional-dep skips). New tests assert connect_runtime_client forwards the resolved package version (and None when unresolvable), and that _sdk_version reads importlib.metadata.

  • ruff check clean on all changed files (the 77 pre-existing errors are all in generated agent_assembly/proto/*_pb2*.py).

  • mypy agent_assembly + pre-commit mypy (incl. tests) clean; the remaining _core import errors are pre-existing (native extension not built locally).

  • Needs CI: the native-core integration tests (test_native_core_runtime.py, maturin build) are gated behind AAASM_RUN_NATIVE_CORE_TESTS=1 and were not run locally — the end-to-end signed-handshake-version path needs CI (or a maturin build) to exercise.

Checklist

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

🤖 Generated with Claude Code

Chisanan232 and others added 4 commits June 24, 2026 16:54
…ough SHA

Re-pin aa-core/aa-proto/aa-sdk-client to agent-assembly AAASM-3683, which adds
the sdk_version field to AssemblyConfig and threads it through spawn_ipc_thread
into the signed handshake. Re-pin to the squash-merge commit once PR #1226 lands.

Refs AAASM-3683.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extend RuntimeClient.connect to accept optional agent_id and sdk_version and
pass them into spawn_ipc_thread, so the agent identity is signed into the
session handshake (AAASM-3587) and the user-facing PyPI package version is the
one signed into the handshake proof (AAASM-3683). None falls back to the crate
version via resolved_sdk_version.

Refs AAASM-3683.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
connect_runtime_client now resolves the installed agent-assembly version via
importlib.metadata (falling back to agent_assembly.__version__) and forwards it
plus the agent id into the native RuntimeClient.connect, so the language-package
version is signed into the handshake for accurate downgrade detection
(AAASM-3683). An older native connect (without the new params) is retried with
the legacy positional signature.

Refs AAASM-3683.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extend the fake native core's connect to capture the agent_id/sdk_version args
and add tests asserting connect_runtime_client forwards the resolved package
version (and None when unresolvable, so the shim falls back to the crate
version), plus that _sdk_version reads importlib.metadata.

Refs AAASM-3683.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 24, 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-3683 (python-sdk #175)

CI: Authoritative gates green. CI Success ✅, CodeQL ✅, Analyze (python) ✅, Dependency advisory audit (pip-audit) ✅, all unit/integration/contract test jobs ✅, build-native-core ✅, aa-* crates share one git rev ✅. The two reds — SonarCloud Code Analysis and codecov/patch — are acceptance-class (quality gate / patch-coverage) and non-blocking.

Scope: Matches the ticket. _sdk_version() reads the user-facing PyPI package version via importlib.metadata.version("agent-assembly") (with an in-tree __version__ fallback), and connect_runtime_client forwards it (plus agent_id) through RuntimeClient.connect(socket_path, agent_id, sdk_version)AssemblyConfig.sdk_versionspawn_ipc_thread → signed handshake. A TypeError fallback preserves the legacy positional signature against an older core. register's config correctly sets sdk_version: None (version is signed at IPC handshake, not on gateway register), giving the AAASM-3666 crate-version fallback. No tokens/secrets/hard-coded crypto introduced.

Tests: Covered — test_connect_forwards_agent_id_and_installed_package_version asserts the resolved package version reaches connect; test_connect_passes_none_version_when_unresolvable asserts the None fallback; test_sdk_version_reads_installed_distribution_metadata pins importlib.metadata.version.

Verdict: READY ✅ (merge-blocked only by the acceptance-class SonarCloud/codecov checks per project policy).

— Claude Code

…3683)

Add install_fake_core_with_connect helper to drive the native connect path
against builds that raise, plus tests for the previously-uncovered new lines:
- connect() legacy single-arg fallback on TypeError (older native build)
- None returned when the legacy retry also fails and on generic connect failure
- _sdk_version fallback to agent_assembly.__version__ when distribution metadata
  is missing, and None when neither source resolves

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Chisanan232

Copy link
Copy Markdown
Contributor Author

Added test coverage for the previously-uncovered new-code paths flagged by codecov/patch + SonarCloud (commit ac04a5f):

  • connect TypeError → legacy single-arg fallback: against an older native build whose connect predates the agent_id/sdk_version parameters, the 3-arg call raises TypeError and the SDK retries with the legacy connect(socket_path) signature, returning the legacy client.
  • None on legacy-retry failure: when the legacy retry also raises (unreachable socket), connect_runtime_client returns None.
  • None on generic connect failure: a non-TypeError failure (e.g. OSError) yields None rather than propagating.
  • _sdk_version __version__ fallback: when importlib.metadata.version('agent-assembly') raises PackageNotFoundError (editable checkout never installed), it falls back to agent_assembly.__version__.
  • _sdk_version returns None: when neither metadata nor __version__ resolves, returns None so the native shim falls back to the crate version.

Added a reusable install_fake_core_with_connect helper to _fake_core.py to drive these connect paths. Each test asserts real behavior (the value forwarded / the client returned / None), not just absence of a crash.

Local: full suite 677 passed / 16 skipped (env-gated); the 5 new tests cover all changed lines in the diff range (runtime_interceptor.py lines 289-332 no longer appear in the term-missing report). black/isort/autoflake/mypy pre-commit hooks pass.

— Claude Code

``agent_assembly.__version__`` rather than returning ``None`` (AAASM-3683)."""
import importlib.metadata

import agent_assembly
to the crate version instead of raising (AAASM-3683)."""
import importlib.metadata

import agent_assembly
@sonarqubecloud

Copy link
Copy Markdown

@Chisanan232 Chisanan232 merged commit 5639440 into master Jun 24, 2026
26 checks passed
@Chisanan232 Chisanan232 deleted the v0.0.1/AAASM-3683/sdk_version_passthrough branch June 24, 2026 10:23
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