Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@reaatech/a2a-reference-client": patch
"@reaatech/a2a-reference-mcp-bridge": patch
"@reaatech/a2a-reference-observability": patch
"@reaatech/a2a-reference-persistence": patch
"@reaatech/a2a-reference-server": patch
---

Fix: Tighten type usage: replace lazy any/unknown with true types

Closes #27
16 changes: 9 additions & 7 deletions packages/client/src/client-unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ describe('A2AClient unit tests', () => {
);
const client = new A2AClient({ baseUrl: 'http://localhost:3000', fetchImpl: mockFetch });

const events: unknown[] = [];
const events: Array<Record<string, unknown>> = [];
for await (const event of client.sendSubscribe({
messageId: '1',
role: 'user',
Expand Down Expand Up @@ -206,7 +206,7 @@ describe('A2AClient unit tests', () => {
);
const client = new A2AClient({ baseUrl: 'http://localhost:3000', fetchImpl: mockFetch });

const events: unknown[] = [];
const events: Array<Record<string, unknown>> = [];
for await (const event of client.subscribe('t1')) {
events.push(event);
}
Expand All @@ -221,13 +221,15 @@ describe('A2AClient unit tests', () => {
const read = vi.fn().mockRejectedValue(new Error('Stream error'));
const mockBody = {
getReader: () => ({ read, releaseLock }),
} as unknown as ReadableStream<Uint8Array>;
} as unknown as {
getReader: () => { read: ReturnType<typeof vi.fn>; releaseLock: ReturnType<typeof vi.fn> };
};

const mockResponse = {
ok: true,
body: mockBody,
headers: new Headers({ 'content-type': 'text/event-stream' }),
} as unknown as Response;
} as unknown as { ok: boolean; body: unknown; headers: Headers };

const mockFetch = vi
.fn()
Expand Down Expand Up @@ -310,7 +312,7 @@ describe('A2AClient unit tests', () => {
ok: true,
body: null,
headers: new Headers({ 'content-type': 'text/event-stream' }),
} as unknown as Response;
} as unknown as { ok: boolean; body: null; headers: Headers };

const mockFetch = vi
.fn()
Expand Down Expand Up @@ -362,7 +364,7 @@ describe('A2AClient unit tests', () => {
);
const client = new A2AClient({ baseUrl: 'http://localhost:3000', fetchImpl: mockFetch });

const events: unknown[] = [];
const events: Array<Record<string, unknown>> = [];
for await (const event of client.sendSubscribe({
messageId: '1',
role: 'user',
Expand Down Expand Up @@ -505,7 +507,7 @@ describe('A2AClient unit tests', () => {
ok: true,
body: null,
headers: new Headers({ 'content-type': 'text/event-stream' }),
} as unknown as Response;
} as unknown as { ok: boolean; body: null; headers: Headers };

const mockFetch = vi
.fn()
Expand Down
50 changes: 29 additions & 21 deletions packages/mcp-bridge/src/a2a-to-mcp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import type { AgentCard, Skill } from '@reaatech/a2a-reference-core';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { A2aAsMcpServer } from './a2a-to-mcp.js';

const mockHandlers = new Map<string, (request: unknown) => Promise<unknown>>();
const mockHandlers = new Map<
string,
(request: Record<string, unknown>) => Promise<Record<string, unknown>>
>();

// Mutable mock state for A2AClient
const mockA2AState = vi.hoisted(() => ({
Expand All @@ -21,23 +24,19 @@ const mockA2AState = vi.hoisted(() => ({
{ url: 'http://localhost:3000', protocolBinding: 'a2a', protocolVersion: '0.3.0' },
],
} as AgentCard,
sendMessageResult: { id: 'task-1', status: { state: 'submitted' } } as unknown,
sendMessageResult: { id: 'task-1', status: { state: 'submitted' } } as Record<string, unknown>,
getTaskResult: {
id: 'task-1',
status: { state: 'completed' },
artifacts: [{ name: 'result', parts: [{ kind: 'text', text: '42' }] }],
} as unknown,
} as Record<string, unknown>,
subscribeEvents: [] as Array<unknown>,
}));

// Mutable mock state for MCP Server
const mockServerState = vi.hoisted(() => ({
clientCapabilities: undefined as { sampling?: unknown } | undefined,
createMessageResult: {
model: 'test-model',
role: 'assistant',
content: { type: 'text', text: 'User input' },
} as unknown,
clientCapabilities: undefined as { sampling?: Record<string, unknown> } | undefined,
createMessageResult: undefined as Record<string, unknown> | Promise<never> | undefined,
}));

// Mock the A2AClient
Expand All @@ -59,15 +58,20 @@ vi.mock('@modelcontextprotocol/sdk/server/index.js', () => ({
Server: vi.fn().mockImplementation(() => ({
setRequestHandler: vi
.fn()
.mockImplementation((schema: unknown, handler: (req: unknown) => Promise<unknown>) => {
const key =
schema === ListToolsRequestSchema
? 'listTools'
: schema === CallToolRequestSchema
? 'callTool'
: 'unknown';
mockHandlers.set(key, handler);
}),
.mockImplementation(
(
schema: unknown,
handler: (req: Record<string, unknown>) => Promise<Record<string, unknown>>,
) => {
const key =
schema === ListToolsRequestSchema
? 'listTools'
: schema === CallToolRequestSchema
? 'callTool'
: 'unknown';
mockHandlers.set(key, handler);
},
),
connect: vi.fn().mockResolvedValue(undefined),
close: vi.fn().mockResolvedValue(undefined),
getClientCapabilities: vi.fn().mockImplementation(() => mockServerState.clientCapabilities),
Expand Down Expand Up @@ -155,7 +159,9 @@ describe('A2aAsMcpServer', () => {
await server.initialize();
const listHandler = mockHandlers.get('listTools');
if (!listHandler) throw new Error('Missing listTools handler');
const result = (await listHandler({} as never)) as { tools: Array<{ inputSchema: unknown }> };
const result = (await listHandler({} as never)) as {
tools: Array<{ inputSchema: Record<string, unknown> | undefined }>;
};
expect(result.tools[0].inputSchema).toEqual({
type: 'object',
properties: { expression: { type: 'string' } },
Expand All @@ -170,7 +176,9 @@ describe('A2aAsMcpServer', () => {
await server.initialize();
const listHandler = mockHandlers.get('listTools');
if (!listHandler) throw new Error('Missing listTools handler');
const result = (await listHandler({} as never)) as { tools: Array<{ inputSchema: unknown }> };
const result = (await listHandler({} as never)) as {
tools: Array<{ inputSchema: Record<string, unknown> | undefined }>;
};
expect(result.tools[0].inputSchema).toEqual({
type: 'object',
properties: {
Expand Down Expand Up @@ -263,7 +271,7 @@ describe('A2aAsMcpServer', () => {
id: 'task-1',
status: { state: 'completed' },
artifacts: [{ name: 'result', parts: [{ kind: 'text', text: 'Hello, User' }] }],
} as unknown;
} as Record<string, unknown>;

mockServerState.clientCapabilities = { sampling: {} };

Expand Down
28 changes: 14 additions & 14 deletions packages/mcp-bridge/src/mcp-to-a2a.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('McpToolAdapter', () => {
});

// Replace the internal client with our mock
(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

const card = adapter.getAgentCard();
Expand Down Expand Up @@ -94,7 +94,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

const card = adapter.getAgentCard();
Expand Down Expand Up @@ -133,7 +133,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

const artifacts = await adapter.executeTask(
Expand Down Expand Up @@ -182,7 +182,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

await adapter.executeTask(
Expand Down Expand Up @@ -228,7 +228,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

await adapter.executeTask(
Expand Down Expand Up @@ -274,7 +274,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

const artifacts = await adapter.executeTask(
Expand Down Expand Up @@ -317,7 +317,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

await expect(
Expand Down Expand Up @@ -360,7 +360,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

await expect(
Expand Down Expand Up @@ -399,7 +399,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.disconnect();
expect(mockClient.close).toHaveBeenCalled();
});
Expand Down Expand Up @@ -428,7 +428,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

await expect(
Expand Down Expand Up @@ -466,7 +466,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

await expect(
Expand Down Expand Up @@ -503,7 +503,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

const artifacts = await adapter.executeTask(
Expand Down Expand Up @@ -540,7 +540,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

await adapter.executeTask(
Expand Down Expand Up @@ -574,7 +574,7 @@ describe('McpToolAdapter', () => {
},
});

(adapter as unknown as Record<string, unknown>).client = mockClient;
(adapter as unknown as { client: typeof mockClient }).client = mockClient;
await adapter.initialize();

await adapter.executeTask(
Expand Down
21 changes: 16 additions & 5 deletions packages/observability/src/telemetry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ describe('setTelemetryProvider', () => {
startSpan() {
return new NoopSpan();
},
async startActiveSpan(_name: string, ...args: unknown[]) {
async startActiveSpan(
_name: string,
...args: [Record<string, unknown> | TelemetrySpan, ...unknown[]]
) {
const fn = args.length === 2 ? args[1] : args[0];
const result = await (fn as (span: TelemetrySpan) => Promise<unknown>)(new NoopSpan());
return result;
Expand Down Expand Up @@ -147,7 +150,8 @@ describe('getTracer', () => {
});

it('passes name and version to provider', () => {
const spy = vi.fn<(...args: unknown[]) => ReturnType<TelemetryProvider['getTracer']>>();
const spy =
vi.fn<(...args: [string?, string?]) => ReturnType<TelemetryProvider['getTracer']>>();
const provider: TelemetryProvider = {
getTracer: spy,
getMeter() {
Expand Down Expand Up @@ -183,14 +187,17 @@ describe('getMeter', () => {
});

it('passes name and version to provider', () => {
const spy = vi.fn<(...args: unknown[]) => ReturnType<TelemetryProvider['getMeter']>>();
const spy = vi.fn<(...args: [string?, string?]) => ReturnType<TelemetryProvider['getMeter']>>();
const provider: TelemetryProvider = {
getTracer() {
return {
startSpan() {
return new NoopSpan();
},
async startActiveSpan(_name: string, ...args: unknown[]) {
async startActiveSpan(
_name: string,
...args: [Record<string, unknown> | TelemetrySpan, ...unknown[]]
) {
const fn = args.length === 2 ? args[1] : args[0];
return (fn as (span: TelemetrySpan) => Promise<unknown>)(new NoopSpan());
},
Expand Down Expand Up @@ -300,7 +307,11 @@ describe('withTaskSpan', () => {

it('includes task attributes in the span options', async () => {
const startActiveSpanSpy = vi.fn(
async (_name: string, _options: unknown, fn: (span: TelemetrySpan) => Promise<unknown>) => {
async (
_name: string,
_options: Record<string, unknown>,
fn: (span: TelemetrySpan) => Promise<unknown>,
) => {
return fn(new NoopSpan());
},
);
Expand Down
Loading
Loading