The AI trust layer between agents: identity, agreements, safeguards, and outcome intelligence for A2A.

Viewing files at commit 989559e001cdCommit detailsView latest

tests/runtime.test.ts 84 lines · 3.1 KB · typescript
1
import { describe, expect, it, vi } from 'vitest';
2
import {
3
  resolvePublicRuntimeEndpoint,
4
  runtimeDeliverySignature,
5
} from '../packages/persistence/src/runtime.js';
6
import { createOpenClaspRuntimeHandler, type RuntimeDelivery } from '../packages/sdk/src/index.js';
7
8
describe('external agent runtime connector', () => {
9
  const secret = 'runtime-secret-long-enough-for-testing';
10
11
  it('answers endpoint verification and rejects unsigned delivery', async () => {
12
    const handler = createOpenClaspRuntimeHandler({ signingSecret: secret, onDelivery: vi.fn() });
13
    const verification = await handler(
14
      new Request('https://agent.example/openclasp', {
15
        method: 'POST',
16
        body: JSON.stringify({
17
          type: 'openclasp.runtime.verify',
18
          version: '1',
19
          agentId: 'agent-b',
20
          challenge: 'challenge-1',
21
        }),
22
      }),
23
    );
24
    await expect(verification.json()).resolves.toEqual({
25
      type: 'openclasp.runtime.verified',
26
      version: '1',
27
      agentId: 'agent-b',
28
      challenge: 'challenge-1',
29
    });
30
    const unauthorized = await handler(
31
      new Request('https://agent.example/openclasp', { method: 'POST', body: '{}' }),
32
    );
33
    expect(unauthorized.status).toBe(401);
34
  });
35
36
  it('verifies signed deliveries before invoking the agent runtime', async () => {
37
    const onDelivery = vi.fn();
38
    const handler = createOpenClaspRuntimeHandler({ signingSecret: secret, onDelivery });
39
    const delivery: RuntimeDelivery = {
40
      type: 'openclasp.a2a.delivery',
41
      version: '1',
42
      deliveryId: 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa',
43
      agentId: 'agent-b',
44
      interactionId: 'bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb',
45
      receivedAt: new Date().toISOString(),
46
      message: {
47
        messageId: 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa',
48
        senderAgentId: 'agent-a',
49
        contentType: 'application/json',
50
        createdAt: new Date().toISOString(),
51
        expiresAt: new Date(Date.now() + 60_000).toISOString(),
52
        payload: { text: 'hello' },
53
      },
54
      reply: {
55
        endpoint: 'https://openclasp.vercel.app/a2a/agent-a',
56
        bearerToken: 'scoped-token',
57
      },
58
    };
59
    const body = JSON.stringify(delivery);
60
    const timestamp = new Date().toISOString();
61
    const response = await handler(
62
      new Request('https://agent.example/openclasp', {
63
        method: 'POST',
64
        headers: {
65
          'openclasp-delivery-id': delivery.deliveryId,
66
          'openclasp-timestamp': timestamp,
67
          'openclasp-signature': `v1=${runtimeDeliverySignature(secret, delivery.deliveryId, timestamp, body)}`,
68
        },
69
        body,
70
      }),
71
    );
72
    expect(response.status).toBe(202);
73
    expect(onDelivery).toHaveBeenCalledWith(delivery);
74
  });
75
});
76
it('rejects local and non-HTTPS runtime targets before connecting', async () => {
77
  await expect(resolvePublicRuntimeEndpoint('http://example.com/runtime')).rejects.toThrow('HTTPS');
78
  await expect(resolvePublicRuntimeEndpoint('https://localhost/runtime')).rejects.toThrow(
79
    'public DNS',
80
  );
81
  await expect(resolvePublicRuntimeEndpoint('https://127.0.0.1/runtime')).rejects.toThrow(
82
    'public DNS',
83
  );
84
});