Skip to content

Phase3 sdk bump - #89

Open
psifunctiondev wants to merge 12 commits into
win4r:masterfrom
psifunctiondev:phase3-sdk-bump
Open

psifunctiondev wants to merge 12 commits into
win4r:masterfrom
psifunctiondev:phase3-sdk-bump

Conversation

@psifunctiondev

Copy link
Copy Markdown

No description provided.

phronesis and others added 12 commits August 6, 2026 11:20
Boots a v1.0 SDK server, exercises the canonical v1.0 wire format end to end:
- agent card with protocolVersion=1.0 and supportedInterfaces[JSONRPC]
- method 'SendMessage' is accepted; v0.3 'message/send' is rejected
- full round-trip via ClientFactory

Currently FAILS at import time because the fork is pinned to
@a2a-js/sdk ^0.3.13 which does not export ClientFactory /
DefaultRequestHandler / jsonRpcHandler from the top-level entry.
Phase 3 bumps the SDK to ^1.0.1 and this test should go green.

Baseline (pre-insertion): 513 passing, 0 failing, 5 cancelled
Post-insertion:           513 passing, 1 failing, 5 cancelled
The single failure is this test file — no collateral damage.
TAP outputs of:
- tests/wire-v1.0.test.ts alone (the new contract test)
- the full 27-file suite

Both show the v0.3 SDK cannot export v1.0 symbols, which is exactly
the contract violation the phase 3 SDK bump must resolve.

Phase 3 will land matching green artifacts in test_artifacts/phase3/.
Dependency-only change, isolated from the actual wire-format port. Doxa
will use this SDK version when she ports the v0.3 server-side wire
format to v1.0 (per the dual-stack plan in
docs/v1.0-port-plan.md + her addendum in the SharedVault migration
brief).

No source files changed in this commit. The fork's src/ still
imports the v0.3 shapes and will fail to typecheck until the
matching port commits land on top of this SDK bump. Expected state.
Two changes that go together:

1. tests/compat-v0_3-part-shape.test.ts (new, 4 tests, all GREEN)

   Verifies the v1.0 SDK's legacyCompat server-side translation:
   - v1.0 client → executor sees v1.0 Part shape (same shape)
   - v0.3 client → SDK translates inbound Parts to v1.0
     before executor sees them
   - v0.3 client receives v1.0 executor reply translated to
     v0.3 Part shape on the way out
   - v1.0 client receives v1.0 executor reply as-is

   KEY FINDING documented in the harness comments: the SDK's
   compat layer translates inbound v0.3 Parts to v1.0 Parts
   before the executor sees them, BUT does NOT translate
   outbound reply Parts. The executor must emit v1.0 Parts
   going forward (even when the inbound was v0.3-shaped).
   Doxa's existing v0.3 executor will need its reply Part
   shape updated as part of Phase 1, not deferred.

2. tests/wire-v1.0.test.ts (fix imports)

   The committed version imported ClientFactory, DefaultRequestHandler,
   InMemoryTaskStore, jsonRpcHandler, agentCardHandler, and UserBuilder
   all from '@a2a-js/sdk' top-level. v1.0 split exports across subpaths
   so the test failed to import. Fixed to import from the right subpaths:
     - @a2a-js/sdk              (types, constants, errors)
     - @a2a-js/sdk/server        (DefaultRequestHandler, InMemoryTaskStore)
     - @a2a-js/sdk/server/express (jsonRpcHandler, agentCardHandler, UserBuilder)
     - @a2a-js/sdk/client       (ClientFactory)

   Also: card URL is now patched at boot to point at the actual bound
   port (v1.0 client reads URL directly from supportedInterfaces[].url).
   Added explicit A2A-Version: 1.0 header to the positive probe (SDK
   defaults to '0.3' when header is absent — a v0.3 back-compat default
   that a v1.0-only server rejects). Updated negative-probe assertion
   to accept either -32601 (method-not-found) or -32009
   (version-not-supported) as valid rejection signals.

Run order per Doxa:
  node --import tsx --test tests/wire-v1.0.test.ts
  node --import tsx --test tests/compat-v0_3-part-shape.test.ts
Both GREEN (7 tests, 0 failures).

Full suite baseline: 505 passing, 15 failing, 5 cancelled.
The 15 failures are pre-existing test mocks that exercise the
v0.3 plugin's outbound against mocked peers. With the SDK now at
1.0.1 but the plugin source still v0.3-shaped, those mocks see a
version mismatch and time out. They're orthogonal to this commit
and are part of the actual port work (Phases 2a-d in the
dual-stack addendum). They should not block Phase 1.
- src/agent-card.ts: supportedInterfaces[] (v0.3 + v1.0 JSONRPC entries), keep additionalInterfaces populated
- index.ts:514-521: legacyCompat on jsonRpcHandler
- src/client.ts:126-128: legacyCompat on transport factories
- src/executor.ts, src/queueing-executor.ts, src/task-recovery.ts: Part shapes v0.3 -> v1.0

Phase 1 acceptance: wire-v1.0.test.ts + compat-v0_3-part-shape.test.ts both GREEN.
Phases 2a-2d deferred to follow-up PRs.
Quinn flagged in his review of #1 that the PR body referenced a
'legacyCompat-removal TODO at index.ts:520' that wasn't actually
in the diff. Adding the breadcrumb here so future-us knows the
flag is transitional, what to remove, and where to find the
related flags (src/client.ts:126-128 transport factories).

Pure comment addition. No code change.
feat(a2a): Phase 1 — wire-only v1.0 migration + Part shape updates
The v1.0 SDK's ResultManager.processEvent requires events in the
{kind, data} wrapper format. Phase 1's wire-only migration missed the
eventBus publish wrapper format — v0.3 SDK was lenient about it, v1.0
SDK requires AgentEvent.task(taskObject) / AgentEvent.message(messageObject)
helpers which produce the {kind, data} wrapper.

Without the wrapper, event.kind === 'task' matched the discriminator but
event.data was undefined → crash at ResultManager.processEvent L2103
on taskEvent.id read.

Sites: 6 in src/executor.ts (working/rejected/heartbeat/failed/completed/
canceled Tasks), 3 in src/queueing-executor.ts (rejected-queue, submitted-
queue, canceled-while-queued). L70 in queueing-executor.ts is a passthrough
wrapper for the observed event bus — receives already-wrapped events
from the delegate executor, no double-wrap. src/task-recovery.ts has no
eventBus.publish sites.

Acceptance: tests/wire-v1.0.test.ts + tests/compat-v0_3-part-shape.test.ts
both GREEN. /opt/data/a2a_ping_doxa.py against http://100.106.127.88:18800
should return a real Doxa reply post-merge.
fix(a2a): wrap executor publishes in AgentEvent.task/.message (Phase 2a)
The v1.0 SDK's taskStateToJSON / roleToJSON only recognize
uppercase enum-prefixed strings ('TASK_STATE_COMPLETED', 'ROLE_AGENT')
or integer values. Our executor was publishing lowercase v0.3 strings
('completed', 'agent'), which hit the default → 'UNRECOGNIZED' branch
on the wire.

Confirmed via byte-exact raw response from Phronesis's ping: the wire
output had 'state':'UNRECOGNIZED' and 'role':'UNRECOGNIZED' for what
should have been a completed task with an agent role.

9 line changes in src/executor.ts (state: 6 sites, role: 3 sites),
including the heartbeat publish site added in Phase 2a. Single file,
no architectural changes. Phase 2a wire-format fix landed in PR #4;
this is Phase 2b.
…ings

fix(a2a-gateway): use v1.0 enum-prefixed state/role strings (Phase 2b)
@doxapsifunction
doxapsifunction deleted the phase3-sdk-bump branch August 9, 2026 22:43

@AliceLJY AliceLJY left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static review against @a2a-js/sdk@1.0.1:

  1. legacyCompat is enabled on jsonRpcHandler but not on agentCardHandler, so v0.3 peers receive the v1 card with no url.
  2. Outbound, doSendMessage (client.ts:277-286) still builds the transport list from agentCard.url / preferredTransport / additionalInterfaces. A v1 card carries supportedInterfaces instead, so v1 peers yield an endpoint with an undefined URL. agentId is still set as a top-level field (client.ts:245), which the v1 serializer drops, so peer-side agent routing is lost.
  3. The branch also carries #90's commits, the test_artifacts/ TAP dumps (~4.2k lines) and fork-internal merge commits. Please trim it to just the port.

This overlaps with #96; @win4r should choose which migration continues.

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.

3 participants