Skip to content

feat: migrate mesh transport from vendored @agentmesh/sdk to @microsoft/agentmesh-sdk (AGT)#27

Closed
imran-siddique wants to merge 5 commits into
Azure:mainfrom
imran-siddique:feat/agt-mesh-migration
Closed

feat: migrate mesh transport from vendored @agentmesh/sdk to @microsoft/agentmesh-sdk (AGT)#27
imran-siddique wants to merge 5 commits into
Azure:mainfrom
imran-siddique:feat/agt-mesh-migration

Conversation

@imran-siddique

@imran-siddique imran-siddique commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Replace vendored @agentmesh/sdk with @microsoft/agentmesh-sdk

Completes migration from vendored amitayks @agentmesh/sdk to Microsoft's @microsoft/agentmesh-sdk (AGT).

Changes

Identity (identity.ts) — Rewritten with Node.js crypto, no external SDK. Supports legacy schema-2 + new schema-3 with auto-migration preserving AMID/keys.

Transport (agt-transport.ts) — Full IMeshTransport using AGT's MeshClient + X3DHKeyManager for Signal E2E. Discovery via registry REST API.

Connection (connection.ts) — doConnect() uses AgtTransport. App-layer code unchanged.

CLI — Dependency + imports updated to @microsoft/agentmesh-sdk.

Vendor removal — Deleted vendor/agentmesh-sdk, vendor/agentmesh-relay, vendor/agentmesh-registry (57K+ lines).

Tests

44 tests pass across 5 files. New agt-transport.test.ts (8 tests). Updated identity/connection/federation tests.

Imran Siddique and others added 3 commits April 21, 2026 17:10
…microsoft/agentmesh-sdk

BREAKING: Removes vendored amitayks @agentmesh/sdk and replaces it
with Microsoft's @microsoft/agentmesh-sdk for all mesh operations.

Migration scope:
- identity.ts: Rewritten to use Node.js crypto directly (no SDK dep).
  Supports schema-2 (legacy) and schema-3 (new) identity files with
  automatic migration preserving AMID and signing keys.
- connection.ts: doConnect() now uses AgtTransport instead of
  dynamically importing @agentmesh/sdk. All app-layer code (chunking,
  inbox, waiters, file transfer, ping, discovery) unchanged.
- agt-transport.ts: Full IMeshTransport implementation with discovery
  via registry REST API, KNOCK handler support, plaintext peer tracking.
- transport-interface.ts: Extended with onKnock, getPlaintextPeers,
  search, and connect options (capabilities, displayName).
- cli/package.json + plugin.ts: Updated to @microsoft/agentmesh-sdk.
- Removed vendor/agentmesh-sdk, vendor/agentmesh-relay,
  vendor/agentmesh-registry (57K+ lines deleted).

All 44 tests pass (5 test files, 0 failures).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@imran-siddique
imran-siddique marked this pull request as ready for review April 22, 2026 05:20
@pallakatos

Copy link
Copy Markdown
Collaborator

Review — request changes, do not merge yet

Thanks for the push on this. I went through the PR against the refreshed AGT
main (microsoft/agent-governance-toolkit) and our docs/agt-mesh-migration-analysis.md.
The direction is right and the upstream crypto work (X3DH / Double Ratchet /
SecureChannel / MeshClient in AGT main) looks genuinely solid. But this PR as
it stands is not mergeable — it doesn't build, the encrypted send path
cannot work at runtime, and deleting vendor/agentmesh-relay + vendor/agentmesh-registry
breaks deployment in several places.

Below is the full gap list. Happy to pair on any of this.


🔴 Hard blockers

1. Build fails — SDK symbols aren't published on npm yet
cli/package.json and mesh-plugin/package.json depend on @microsoft/agentmesh-sdk@^3.2.0.
The published 3.2.0 on npm is governance-only — it exports only
AgentIdentity, TrustManager, PolicyEngine, AuditLogger, AgentMeshClient,
GovernanceMetrics, McpSecurityScanner, LifecycleManager. The encryption
symbols this PR imports (X3DHKeyManager, MeshClient, SecureChannel,
DoubleRatchet) exist only on AGT main (PRs #1278 and #1301), unreleased.

Reproduce:

cli $ npm run build
src/plugin.ts(1753,26): error TS2307: Cannot find module '@microsoft/agentmesh-sdk'...
src/plugin.ts(1945,36): error TS2307: Cannot find module '@microsoft/agentmesh-sdk'...
mesh-plugin $ npm run build
src/agt-transport.ts(13,27): error TS2307: Cannot find module '@microsoft/agentmesh-sdk'...

Action: AGT needs to cut a real npm release (3.3.0 / 4.0.0) that actually
exports the encryption module. We should then pin to that exact version, not ^3.2.0.

2. Encrypted send path will throw on first call to any non-plaintext peer
AgtTransport.send() calls MeshClient.send(peerId, payload). In AGT main:

// mesh-client.ts line ~150
if (!session || !session.channel) {
  throw new Error(`No encrypted session with ${peerId}. Call establishSession() first.`);
}

AgtTransport:

  • never calls MeshClient.establishSession()
  • never publishes our own prekey bundle to the registry
  • never fetches a peer's PreKeyBundle from the registry

The only reason the 44 mesh-plugin tests pass is that none of them exercise
an actual relay. Any real session will throw on the first send.

Action: wire up the prekey lifecycle:
a. on connect: keyManager.generateSignedPreKey() / generateOneTimePreKeys(n) → publish to registry
b. on first send to peer X: fetch X's bundle from registry → client.establishSession(X, bundle) → then send
c. on inbound KNOCK carrying an establishment payload: call client.acceptSession(peer, establishment)

3. vendor/agentmesh-relay + vendor/agentmesh-registry deletion breaks deployment
Still referenced by:

  • Makefile targets image-relay, image-registry, push (points at vendor/agentmesh-{relay,registry}/Dockerfile)
  • cli/src/commands/push.ts:66-68 (relay + registry build entries)
  • cli/src/commands/dev.ts:222-225 (dev-mode build of agentmesh-relay:dev)
  • deploy/agentmesh.yaml:112,212 (deploys agentmesh-relay:latest + agentmesh-registry:latest images)

After this PR, make images, azureclaw up, azureclaw push, and azureclaw dev
all fail on a clean clone, and the existing deployed images are unrebuildable.

Action: whichever relay/registry replaces them has to (a) actually exist in
this repo or another vendor/ entry, and (b) be wired into Makefile / push.ts /
dev.ts / deploy/agentmesh.yaml in the same PR.

4. Wire-format mismatch with the Rust relay that's actually deployed
AGT MeshClient sends {v:1, type:"connect"|"message"|"knock"|"ack"|...} frames.
The vendored Rust relay's tagged enum uses "send" (not "message"), has no
v:1, and doesn't know knock / knock_accept / knock_reject types as
emitted by AGT. This is a protocol mismatch, not a patch-level bug.

Action: depends on #3. Either ship a new relay that speaks the AGT wire
shape, or teach AGT MeshClient our existing wire shape. Without this, the
deployed Rust relay and a new AGT TS client cannot talk to each other at all.

5. No production store-and-forward relay
packages/agent-mesh/src/agentmesh/relay/store.py provides only InMemoryInboxStore
— explicitly labeled "for development," state is lost on restart. The vendored
Rust relay we're deleting had 72h TTL durable inbox (Duration::hours(72)).
Losing durability regresses offload + handoff.

Action: AGT should ship a real relay (Postgres/Redis-backed, container image,
Helm manifest) before this PR can land — or we keep the Rust relay.


🟡 Correctness / security gaps in AGT upstream (please fix upstream before we adopt)

6. X3DHKeyManager.verifyBundle doesn't verify the signed-prekey signature
packages/agent-mesh/sdks/typescript/src/encryption/x3dh.ts:210-220:

function verifyBundle(bundle: PreKeyBundle): void {
  if (bundle.signedPreKeySignature.length !== 64) throw ...
  if (bundle.signedPreKey.length !== 32) throw ...
  if (bundle.identityKey.length !== 32) throw ...
}

Only checks lengths; no Ed25519 verification. Also, PreKeyBundle.identityKey is
the X25519 key — the Ed25519 public key needed to verify the signature isn't in
the bundle schema. The vendored SDK did verify this. Adopting AGT as-is is a
real crypto-binding regression.

Action: AGT fix — add identityKeyEd to PreKeyBundle, call ed25519.verify(sig, signedPreKey, identityKeyEd) in verifyBundle.

7. No prekey REST on the AGT registry
AgtTransport.discover() calls GET /agents?capability=X. There is no
POST /prekeys / GET /prekeys/{id} endpoint surface, and no TS client code
for one. Section 4 of the migration analysis flagged this as blocking — still
blocking.

8. No delivery-on-reconnect handshake in MeshClient
Even once a durable relay exists, MeshClient.connect() sends {type:"connect"}
and then waits for incoming frames. There's no fetch_pending / inbox_replay
call. A sub-agent that was offline during a send won't receive the message on
reconnect.


🟡 Smaller issues in this PR

9. mesh-plugin/src/agt-identity.ts is dead code. Referenced only via
Symbol.for("agt-identity") in cli/src/plugin.ts:3179, never meaningfully
consumed. Either wire it up or remove.

10. KNOCK is hardcoded {accept: true} in connection.ts:180. Same
behavior as before, but KNOCK was supposed to carry intent — no hook is
plumbed through to policy.

11. No real integration test. The 44 mesh-plugin tests cover construction
and disconnected state only. We need at minimum a two-AgtTransport test
against a live relay process doing an encrypted round-trip — that would have
caught issue #2 immediately.


🟢 What's good — let's keep this

These changes are independently useful and could land as a standalone "phase 2"
PR (per docs/agt-mesh-migration-analysis.md §10 phased plan) while the above
is sorted out upstream:

  • mesh-plugin/src/transport-interface.ts — the IMeshTransport abstraction is
    exactly the behavior-preserving refactor we wanted before any swap.
  • mesh-plugin/src/identity.ts rewrite onto Node crypto with schema-2 →
    schema-3 migration preserving AMID and keys. Clean and correct.
  • AGT upstream MeshClient preserving plaintextPeers + wsFactory — thanks
    for pulling those two patch hooks into the upstream design.

Recommendation

Request changes — block merge until (1)–(5) are addressed.

Suggested path forward:

  1. Now: split this PR. Land the IMeshTransport abstraction + identity.ts
    rewrite as a separate, mergeable PR. That's low-risk and gives us the
    abstraction the eventual swap needs.
  2. AGT side: cut an npm release that exports the encryption module; fix
    the prekey signature verification + bundle schema (feat: persistent trust store across pod recreations #6); ship a durable
    relay + registry (or decide we keep the Rust ones and extend AGT
    MeshClient to speak the existing wire shape); add a prekey REST surface
    (security: inference requests bypass policy evaluation entirely (CRITICAL) #7); implement delivery-on-reconnect (security: sub-agent spawn not gated by policy or trust score #8).
  3. AzureClaw side, once 2 is done: revive this PR with prekey lifecycle
    wired through (chore(deps): bump rustls-webpki from 0.103.9 to 0.103.10 #2), deployment references updated (fix(entrypoint): pre-create OpenClaw temp dirs and fix router log redirect #3), and a real
    two-peer encrypted-round-trip integration test.

Happy to help scope any of the AGT-side work and contribute tests / repro cases.

/cc the analysis in docs/agt-mesh-migration-analysis.md — §5 and §11 list the exact gaps this PR needs to close.

Imran Siddique and others added 2 commits April 22, 2026 12:00
Also picks up randomBytes import fix from AGT v3.2.1.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Picks up .js extension fix for @noble subpath exports.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@imran-siddique

Copy link
Copy Markdown
Contributor Author

Thanks @pallakatos for the thorough review. You're right on all 5 hard blockers and the 3 upstream issues. Here's the plan:

Phase 1 (this PR, split): Land the safe parts only:

  • IMeshTransport abstraction (transport-interface.ts)
  • identity.ts rewrite onto Node crypto with schema-2 to schema-3 migration
  • These are independently useful and low-risk

Phase 2 (AGT upstream fixes): Created tracking issues:

Phase 3 (this repo): Once AGT upstream is fixed:

  • Revive full migration with prekey lifecycle wired through
  • Keep vendor/relay + vendor/registry until AGT ships durable relay
  • Wire format alignment (AGT MeshClient to speak existing Rust relay shape OR ship new relay)
  • Real two-peer encrypted round-trip integration test

I'll split this PR now. The identity rewrite + transport abstraction can land immediately.

@imran-siddique

Copy link
Copy Markdown
Contributor Author

Superseded by #29 (Phase 1 only — transport abstraction + identity rewrite). The full migration will resume once AGT upstream issues are resolved (microsoft/agent-governance-toolkit#1404–#1407).

pallakatos added a commit that referenced this pull request Apr 27, 2026
refactor: extract IMeshTransport abstraction + rewrite identity onto Node crypto (Phase 1 of #27)
pallakatos pushed a commit that referenced this pull request May 12, 2026
…ction code

Adds transport-interface.ts defining the IMeshTransport contract between
the mesh-plugin's application-level code (chunking, file transfer, inbox)
and the underlying transport layer.

This enables swapping transport implementations (vendored SDK → AGT SDK)
without changing connection logic. Phase 1 of AGT migration per #27.

Identity rewrite deferred to Phase 2 (needs connection.ts updates).

No existing code changes. No new dependencies. Zero new TS errors
(upstream has 2 pre-existing @agentmesh/sdk type declaration errors).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
pallakatos added a commit that referenced this pull request May 12, 2026
refactor: extract IMeshTransport abstraction + rewrite identity onto Node crypto (Phase 1 of #27)
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.

2 participants