Skip to content

Commit 8fa6237

Browse files
authored
fix(version): default to legacy 0.3 when protocolVersion is missing (#552)
# Description Fixes part of version checking method Fixes #474 🦕
1 parent fbc049c commit 8fa6237

4 files changed

Lines changed: 20 additions & 20 deletions

File tree

src/version_utils.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ function compareVersions(a: NumericVersion, b: NumericVersion): number {
4646
}
4747

4848
/**
49-
* Returns `true` when `version` is a non-empty, parseable string that falls
50-
* inside the legacy range `[0.3, 1.0)`.
51-
*
52-
* Empty / nullish / unparseable inputs return `false`.
49+
* Returns `true` when `version` is in the legacy range `[0.3, 1.0)`.
50+
* Empty, whitespace-only, or nullish inputs are treated as legacy ('0.3'),
51+
* matching the spec rule that clients without an explicit version are v0.3.
52+
* Unparseable, non-empty inputs return `false`.
5353
*/
5454
export function isLegacyVersion(version: string | null | undefined): boolean {
55-
if (!version) return false;
55+
if (!version || version.trim() === '') return true;
5656
const v = parseVersion(version);
5757
if (!v) return false;
5858

test/client/transports/json_rpc_transport.spec.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,7 @@ describe('JsonRpcTransportFactory', () => {
262262
expect(transport).not.toBeInstanceOf(LegacyJsonRpcTransport);
263263
});
264264

265-
// TODO: It should default to v0.3 when protocolVersion is missing and legacyCompat is enabled
266-
// after https://github.com/a2aproject/a2a-js/issues/474
267-
it('produces JsonRpcTransport when matched interface has empty protocolVersion', async () => {
265+
it('produces LegacyJsonRpcTransport when matched interface has empty protocolVersion (defaults to 0.3)', async () => {
268266
const card = baseAgentCard();
269267
card.supportedInterfaces = [
270268
{
@@ -276,8 +274,7 @@ describe('JsonRpcTransportFactory', () => {
276274
];
277275
const factory = new JsonRpcTransportFactory({ legacyCompat: { enabled: true } });
278276
const transport = await factory.create('https://a.example/rpc', card);
279-
expect(transport).toBeInstanceOf(JsonRpcTransport);
280-
expect(transport).not.toBeInstanceOf(LegacyJsonRpcTransport);
277+
expect(transport).toBeInstanceOf(LegacyJsonRpcTransport);
281278
});
282279

283280
it('disambiguates by URL when multiple JSON-RPC interfaces are present', async () => {

test/client/transports/rest_transport.spec.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -546,9 +546,7 @@ describe('legacyCompat enabled', () => {
546546
expect(transport).not.toBeInstanceOf(LegacyRestTransport);
547547
});
548548

549-
// TODO: It should default to v0.3 when protocolVersion is missing and legacyCompat is enabled
550-
// after https://github.com/a2aproject/a2a-js/issues/474
551-
it('produces RestTransport when matched interface has empty protocolVersion', async () => {
549+
it('produces LegacyRestTransport when matched interface has empty protocolVersion (defaults to 0.3)', async () => {
552550
const card = createMockAgentCard({
553551
supportedInterfaces: [
554552
{
@@ -561,8 +559,7 @@ describe('legacyCompat enabled', () => {
561559
});
562560
const factory = new RestTransportFactory({ legacyCompat: { enabled: true } });
563561
const transport = await factory.create('https://a.example/rest', card);
564-
expect(transport).toBeInstanceOf(RestTransport);
565-
expect(transport).not.toBeInstanceOf(LegacyRestTransport);
562+
expect(transport).toBeInstanceOf(LegacyRestTransport);
566563
});
567564

568565
it('disambiguates by URL when multiple HTTP+JSON interfaces are present', async () => {

test/compat/v0_3/translate/versions.spec.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,19 @@ describe('versions', () => {
4444
expect(isLegacyVersion('0.0')).toBe(false);
4545
});
4646

47-
it('returns false for an empty string', () => {
48-
expect(isLegacyVersion('')).toBe(false);
47+
it('returns true for an empty string (defaults to 0.3)', () => {
48+
expect(isLegacyVersion('')).toBe(true);
4949
});
5050

51-
it('returns false for null/undefined', () => {
52-
expect(isLegacyVersion(null)).toBe(false);
53-
expect(isLegacyVersion(undefined)).toBe(false);
51+
it('returns true for whitespace-only strings (defaults to 0.3)', () => {
52+
expect(isLegacyVersion(' ')).toBe(true);
53+
expect(isLegacyVersion(' ')).toBe(true);
54+
expect(isLegacyVersion('\t\n')).toBe(true);
55+
});
56+
57+
it('returns true for null/undefined (defaults to 0.3)', () => {
58+
expect(isLegacyVersion(null)).toBe(true);
59+
expect(isLegacyVersion(undefined)).toBe(true);
5460
});
5561

5662
it('returns false for unparseable strings', () => {

0 commit comments

Comments
 (0)