/**
* LAX — Linked Agent eXchange
* Smoke test — offer creation, validation, registry, A2A export
* Run: npx tsx smoke.test.ts
*/
import { strict as assert } from 'node:assert';
import {
createOffer,
createCapability,
validateOffer,
RegistryClient,
A2AExporter,
LAX_VERSION,
LAX_WELL_KNOWN_PATH,
A2A_WELL_KNOWN_PATH,
} from './src/index.js';
import type {
LaxOffer,
LaxCapability,
LaxPricing,
OfferValidationResult,
A2AAgentCard,
} from './src/types.js';
let passed = 0;
// --- Version ---
assert.equal(LAX_VERSION, '1.0');
passed++;
console.log('OK LAX_VERSION is 1.0');
// --- Well-known paths ---
assert.equal(LAX_WELL_KNOWN_PATH, '/.well-known/lax-offer.json');
assert.equal(A2A_WELL_KNOWN_PATH, '/.well-known/agent.json');
passed++;
console.log('OK Well-known paths are correct');
// --- createCapability ---
const cap = createCapability({
skill_id: 'create_invoice',
description: 'Create a new invoice',
pricing: { model: 'per_call', amount: '0.01', currency: 'USDC', rail: 'x402' },
});
assert.equal(cap.skill_id, 'create_invoice');
assert.equal(cap.description, 'Create a new invoice');
assert.deepEqual(cap.input_schema, {});
assert.deepEqual(cap.output_schema, {});
assert.equal(cap.pricing.model, 'per_call');
assert.equal(cap.pricing.amount, '0.01');
assert.equal(cap.pricing.currency, 'USDC');
assert.equal(cap.pricing.rail, 'x402');
passed++;
console.log('OK createCapability: basic creation with defaults');
const capWithSchemas = createCapability({
skill_id: 'send_reminder',
description: 'Send a payment reminder',
input_schema: { type: 'object', properties: { invoice_id: { type: 'string' } } },
output_schema: { type: 'object', properties: { sent: { type: 'boolean' } } },
pricing: { model: 'per_call', amount: '0.005', currency: 'USDC', rail: 'x402' },
});
assert.deepEqual(capWithSchemas.input_schema, {
type: 'object',
properties: { invoice_id: { type: 'string' } },
});
passed++;
console.log('OK createCapability: with explicit schemas');
// --- createOffer ---
const offer = createOffer({
agent_did: 'did:kognai:invoica-ceo',
erc8004_identity: '0x2458cBd0FEdC4fAcf6C1313938a19b35fB41bC0b',
soul_uri: 'https://invoica.kognai.ai/.well-known/soul.md',
capabilities: [cap, capWithSchemas],
constitutional_constraints: ['khaldunian-commitment', 'five-immutable-laws'],
acp_score: 92,
acp_attestation_uid: '0xabc123def456',
pact_endpoint: 'https://invoica.kognai.ai/pact',
payment_rails: ['x402', 'usdc-base'],
});
assert.equal(offer.lax_version, '1.0');
assert.equal(offer.agent_did, 'did:kognai:invoica-ceo');
assert.equal(offer.capabilities.length, 2);
assert.equal(offer.acp_score, 92);
assert.ok(offer.updated_at);
passed++;
console.log('OK createOffer: full offer creation');
// --- validateOffer: valid ---
const validResult = validateOffer(offer);
assert.equal(validResult.valid, true);
assert.equal(validResult.errors.length, 0);
passed++;
console.log('OK validateOffer: valid offer passes');
// --- validateOffer: warnings for empty constraints ---
const noConstraintsOffer = createOffer({
agent_did: 'did:kognai:test',
erc8004_identity: '0x1234',
soul_uri: 'https://test.com/soul.md',
capabilities: [cap],
constitutional_constraints: [],
acp_score: 50,
acp_attestation_uid: '0xdef789',
pact_endpoint: 'https://test.com/pact',
payment_rails: ['x402'],
});
const warnResult = validateOffer(noConstraintsOffer);
assert.equal(warnResult.valid, true);
assert.ok(warnResult.warnings.length > 0);
passed++;
console.log('OK validateOffer: warns on empty constitutional_constraints');
// --- validateOffer: invalid offer ---
const badOffer: LaxOffer = {
lax_version: '1.0',
agent_did: '',
erc8004_identity: '',
soul_uri: '',
capabilities: [],
constitutional_constraints: [],
acp_score: -5,
acp_attestation_uid: '',
pact_endpoint: '',
payment_rails: [],
updated_at: '',
};
const badResult = validateOffer(badOffer);
assert.equal(badResult.valid, false);
assert.ok(badResult.errors.length > 0);
passed++;
console.log('OK validateOffer: rejects invalid offer with multiple errors');
// --- validateOffer: wrong version ---
const wrongVersionOffer = { ...offer, lax_version: '2.0' as any };
const versionResult = validateOffer(wrongVersionOffer);
assert.equal(versionResult.valid, false);
assert.ok(versionResult.errors.some((e: string) => e.includes('lax_version')));
passed++;
console.log('OK validateOffer: rejects wrong lax_version');
// --- validateOffer: ACP score out of range ---
const highAcpOffer = { ...offer, acp_score: 150 };
const acpResult = validateOffer(highAcpOffer);
assert.equal(acpResult.valid, false);
assert.ok(acpResult.errors.some((e: string) => e.includes('acp_score')));
passed++;
console.log('OK validateOffer: rejects acp_score > 100');
// --- RegistryClient: instantiation ---
const registry = new RegistryClient();
assert.equal(registry.config.registry_url, 'https://lax.kognai.ai/registry');
assert.equal(registry.config.timeout_ms, 10_000);
passed++;
console.log('OK RegistryClient: default config');
const customRegistry = new RegistryClient({
registry_url: 'https://custom.registry.io',
x402_token: 'tok_test',
timeout_ms: 5000,
});
assert.equal(customRegistry.config.registry_url, 'https://custom.registry.io');
assert.equal(customRegistry.config.x402_token, 'tok_test');
assert.equal(customRegistry.config.timeout_ms, 5000);
passed++;
console.log('OK RegistryClient: custom config');
// --- RegistryClient: real HTTP transport against a mock registry (v0.4.0) ---
const { createServer } = await import('node:http');
let lastPath = '';
let lastPayment: string | undefined;
const mock = createServer((req, res) => {
lastPath = req.url || '';
lastPayment = req.headers['x-payment'] as string | undefined;
if (req.method === 'POST' && (req.url || '').startsWith('/offers')) {
let body = '';
req.on('data', (c) => { body += c; });
req.on('end', () => {
const submitted = JSON.parse(body || '{}');
res.setHeader('content-type', 'application/json');
res.end(JSON.stringify({ ...submitted, acp_attestation_uid: 'srv-uid-123' }));
});
return;
}
if (req.method === 'GET' && (req.url || '').startsWith('/search')) {
res.setHeader('content-type', 'application/json');
res.end(JSON.stringify({ results: [{ offer, relevance: 0.91 }] }));
return;
}
res.statusCode = 404;
res.end('not found');
});
await new Promise<void>((resolve) => mock.listen(0, resolve));
const mockPort = (mock.address() as { port: number }).port;
const liveRegistry = new RegistryClient({
registry_url: `http://127.0.0.1:${mockPort}`,
x402_token: 'tok_test',
});
// register: POSTs /offers with the x402 header, returns the server-populated offer
const registered = await liveRegistry.register(offer);
assert.equal(registered.agent_did, offer.agent_did);
assert.equal(registered.acp_attestation_uid, 'srv-uid-123');
assert.equal(lastPath, '/offers');
assert.equal(lastPayment, 'tok_test');
passed++;
console.log('OK RegistryClient.register: POSTs offer with x402 header, returns server offer');
// search: GETs /search with query params, parses { results: [...] }
const searchResults = await liveRegistry.search({ query: 'invoice', skill_ids: ['build'], min_acp_score: 80 });
assert.equal(searchResults.length, 1);
assert.equal(searchResults[0].relevance, 0.91);
assert.ok(lastPath.startsWith('/search?'));
assert.ok(lastPath.includes('query=invoice'));
assert.ok(lastPath.includes('min_acp_score=80'));
passed++;
console.log('OK RegistryClient.search: GETs /search, parses results');
await new Promise<void>((resolve) => mock.close(() => resolve()));
// --- RegistryClient: register rejects invalid (before any network call) ---
try {
await registry.register(badOffer);
assert.fail('should throw');
} catch (e: any) {
assert.ok(e.message.includes('validation failed'));
}
passed++;
console.log('OK RegistryClient.register: rejects invalid offer');
// --- RegistryClient: search is best-effort — unreachable registry → [] ---
const offline = new RegistryClient({ registry_url: 'http://127.0.0.1:1', timeout_ms: 1000 });
const emptyResults = await offline.search({ query: 'invoice' });
assert.ok(Array.isArray(emptyResults) && emptyResults.length === 0);
passed++;
console.log('OK RegistryClient.search: unreachable registry → [] (no throw)');
// --- RegistryClient: register surfaces failure when the registry is unreachable ---
try {
await offline.register(offer);
assert.fail('should throw');
} catch (e: any) {
assert.ok(/unreachable|HTTP|payment/i.test(e.message));
}
passed++;
console.log('OK RegistryClient.register: unreachable registry → throws');
// --- RegistryClient: validate (structural) ---
const validateResult = await registry.validate(offer);
assert.equal(validateResult.valid, true);
passed++;
console.log('OK RegistryClient.validate: valid offer passes');
// --- A2AExporter: export ---
const a2aCard = A2AExporter.export(
offer,
'Invoica CEO',
'https://invoica.kognai.ai',
{ organization: 'Kognai' }
);
assert.equal(a2aCard.name, 'Invoica CEO');
assert.equal(a2aCard.url, 'https://invoica.kognai.ai');
assert.equal(a2aCard.skills.length, 2);
assert.equal(a2aCard.skills[0]!.id, 'create_invoice');
assert.equal(a2aCard.skills[1]!.id, 'send_reminder');
assert.equal(a2aCard.provider?.organization, 'Kognai');
assert.equal(a2aCard.version, '1.0');
passed++;
console.log('OK A2AExporter.export: converts offer to A2A card');
// --- A2AExporter: serialize ---
const json = A2AExporter.serialize(a2aCard);
assert.ok(json.startsWith('{'));
const parsed = JSON.parse(json) as A2AAgentCard;
assert.equal(parsed.name, 'Invoica CEO');
assert.equal(parsed.skills.length, 2);
passed++;
console.log('OK A2AExporter.serialize: produces valid JSON');
// --- A2AExporter: without provider ---
const noProviderCard = A2AExporter.export(offer, 'Test Agent', 'https://test.com');
assert.equal(noProviderCard.provider, undefined);
passed++;
console.log('OK A2AExporter.export: works without provider');
console.log(`\nAll ${passed} LAX smoke tests passed`);
agentgate-source: code mirror on Cloudflare Pages. All repos