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

Commit 61a3d5a9

61a3d5a92277Merged

aryaamin <[email protected]> · 2 months ago · 3 files · ~3 modified

Description

Bundle font for Agent Card previews

Details

Commit
61a3d5a92277
Parent
922a6b480fb8

apps/api/src/agent-card-image.tsmodifiedView file

@@ -1,6 +1,28 @@
1-import sharp from 'sharp';
1+import { createRequire } from 'node:module';
2+import { dirname, join } from 'node:path';
3+import { mkdirSync, writeFileSync } from 'node:fs';
24 import type { PublicAgentCard } from '../../../packages/protocol/src/index.js';
35
6+let sharpModule: Promise<typeof import('sharp')> | undefined;
7+
8+function loadSharp() {
9+ if (sharpModule) return sharpModule;
10+ const require = createRequire(import.meta.url);
11+ const fontDirectory = join(dirname(require.resolve('geist/font/sans')), 'fonts/geist-sans');
12+ const configDirectory = '/tmp/openclasp-fontconfig';
13+ const cacheDirectory = join(configDirectory, 'cache');
14+ const configFile = join(configDirectory, 'fonts.conf');
15+ mkdirSync(cacheDirectory, { recursive: true });
16+ writeFileSync(
17+ configFile,
18+ `<?xml version="1.0"?><!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"><fontconfig><dir>${fontDirectory}</dir><cachedir>${cacheDirectory}</cachedir></fontconfig>`,
19+ );
20+ process.env.FONTCONFIG_FILE = configFile;
21+ process.env.FONTCONFIG_PATH = configDirectory;
22+ sharpModule = import('sharp');
23+ return sharpModule;
24+}
25+
426 const shorten = (value: string, length: number) =>
527 value.length > length ? `${value.slice(0, length - 1).trimEnd()}…` : value;
628
@@ -74,23 +96,25 @@
7496 <rect width="1200" height="630" fill="url(#background)"/>
7597 <rect width="1200" height="630" fill="url(#glow)"/>
7698 <path d="M64 66h18l10 10-10 10H64l-10-10 10-10Z" fill="none" stroke="#f04b2d" stroke-width="4"/>
77- <text x="108" y="84" fill="#f04b2d" font-family="Inter,Arial,sans-serif" font-size="27" font-weight="700" letter-spacing="-1">OpenClasp</text>
99+ <text x="108" y="84" fill="#f04b2d" font-family="Geist" font-size="27" font-weight="700" letter-spacing="-1">OpenClasp</text>
78100 <g transform="translate(936 58)">
79101 <rect width="200" height="42" rx="21" fill="#44d37e0d" stroke="#44d37e88"/>
80- <text x="20" y="27" fill="#44d37e" font-family="Inter,Arial,sans-serif" font-size="16">✓ Publisher verified</text>
102+ <path d="M18 21l5 5 9-11" fill="none" stroke="#44d37e" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
103+ <text x="42" y="27" fill="#44d37e" font-family="Geist" font-size="16">Publisher verified</text>
81104 </g>
82105 <g transform="translate(64 165)">
83106 <rect width="122" height="122" rx="28" fill="#f04b2d1a" stroke="#f04b2d80"/>
84- <text x="61" y="78" text-anchor="middle" fill="#ff8068" font-family="Inter,Arial,sans-serif" font-size="42" font-weight="700">${escapeXml(initials || 'AI')}</text>
107+ <text x="61" y="78" text-anchor="middle" fill="#ff8068" font-family="Geist" font-size="42" font-weight="700">${escapeXml(initials || 'AI')}</text>
85108 </g>
86- <text x="220" y="176" fill="#a99e99" font-family="Inter,Arial,sans-serif" font-size="18" letter-spacing="2">${escapeXml(shorten(card.framework, 44).toUpperCase())} · AGENT CARD</text>
87- <text x="220" y="246" fill="#f7f2ef" font-family="Inter,Arial,sans-serif" font-size="${nameSize}" font-weight="700" letter-spacing="-2">${escapeXml(name)}</text>
88- <text x="220" y="308" fill="#c7bdb8" font-family="Inter,Arial,sans-serif" font-size="24">${descriptionLines(description)}</text>
89- <g font-family="Inter,Arial,sans-serif">${capabilityChips(card.capabilities)}</g>
109+ <text x="220" y="176" fill="#a99e99" font-family="Geist" font-size="18" letter-spacing="2">${escapeXml(shorten(card.framework, 44).toUpperCase())} · AGENT CARD</text>
110+ <text x="220" y="246" fill="#f7f2ef" font-family="Geist" font-size="${nameSize}" font-weight="700" letter-spacing="-2">${escapeXml(name)}</text>
111+ <text x="220" y="308" fill="#c7bdb8" font-family="Geist" font-size="24">${descriptionLines(description)}</text>
112+ <g font-family="Geist">${capabilityChips(card.capabilities)}</g>
90113 <line x1="64" y1="540" x2="1136" y2="540" stroke="#ffffff21"/>
91- <text x="64" y="582" fill="#8f8580" font-family="Inter,Arial,sans-serif" font-size="16">${escapeXml(publicReference)}</text>
92- <text x="1136" y="582" text-anchor="end" fill="#8f8580" font-family="Inter,Arial,sans-serif" font-size="16">Capabilities are self-declared</text>
114+ <text x="64" y="582" fill="#8f8580" font-family="Geist" font-size="16">${escapeXml(publicReference)}</text>
115+ <text x="1136" y="582" text-anchor="end" fill="#8f8580" font-family="Geist" font-size="16">Capabilities are self-declared</text>
93116 </svg>`;
94117
118+ const { default: sharp } = await loadSharp();
95119 return sharp(Buffer.from(svg)).png().toBuffer();
96120 }