agentlink-sdk
v1.1.0
Published
AgentLink client SDK for cross-domain data synchronization via URL hash
Maintainers
Readme
AgentLink SDK
AgentLink 客户端 SDK,用于跨域数据同步,通过 URL hash 传递数据,支持 Token 验证和白名单机制。同时提供 Base64 隔离、Schema 推断等工具函数,便于与 LLM 流程集成。
安装
npm
npm install agentlink-sdkyarn
yarn add agentlink-sdkpnpm
pnpm add agentlink-sdkCDN
<script type="module">
import { AgentLinkClient } from 'https://cdn.jsdelivr.net/npm/agentlink-sdk@latest/dist/index.mjs';
</script>快速开始
基本使用
SDK 默认使用服务端地址 https://www.mixlab.top,可直接创建客户端;如需使用自建或其它服务端,可传入 serverUrl 覆盖默认值。
import { AgentLinkClient } from 'agentlink-sdk';
// 使用默认地址 https://www.mixlab.top
const client = new AgentLinkClient();
// 或指定自定义服务端地址
const client = new AgentLinkClient({
serverUrl: 'https://your-agentlink-server.com'
});
// 发送数据
await client.sendData(
'https://target-domain.com/page',
{ message: 'Hello from AgentLink' },
'greeting'
);
// 接收数据
client.receiveData((data, type, senderInfo) => {
console.log('收到数据:', data);
console.log('数据类型:', type);
console.log('发送方信息:', senderInfo);
});跨域与白名单说明
在任意域名的网页(例如 https://your-site.com)中接入 SDK 并发送数据时:
跨域(CORS):AgentLink 服务端已对相关 API 配置 CORS,会正确返回
Access-Control-Allow-Origin等响应头。因此从你的站点向服务端发起的fetch请求不会被浏览器以跨域为由拦截,无需额外配置。白名单:发送数据前,你的当前页面所在域名必须在 AgentLink 服务端的域名白名单中。若未加入白名单,服务端将拒绝签发 Token,
sendData会报错。- 使用默认服务端(如
https://www.mixlab.top)时,需在对应后台将你的域名加入白名单。 - 使用自建服务端时,请在自己的 AgentLink 管理后台添加域名。
- 使用默认服务端(如
能力接口:
fetchCapabilities、fetchStructureData调用服务端的/api/capabilities、/api/structureData时,服务端会校验请求的 Origin/Referer,仅白名单域名或 server 自身可调用;非白名单会返回 403(域名不在白名单中)。
总结:只要你的域名已在所用 AgentLink 服务端的白名单中,即可正常跨域调用、发送数据及使用能力接口,无需担心浏览器跨域限制。
API 文档
AgentLinkClient
构造函数
new AgentLinkClient(options: AgentLinkClientOptions)参数:
options.serverUrl(string, 可选): 服务端验证地址。不传时使用默认地址https://www.mixlab.top;可传入自定义地址如'https://your-server.com'
方法
sendData
发送数据到目标应用。
async sendData(
targetUrl: string,
data: any,
type: string,
windowName?: string
): Promise<void>参数:
targetUrl(string, 必需): 目标应用的完整 URLdata(any, 必需): 要发送的数据对象type(string, 必需): 数据类型标识windowName(string, 可选): 窗口名称,用于复用窗口,默认为'agentlink-window'
示例:
await client.sendData(
'https://example.com/receive',
{
message: 'Hello',
timestamp: Date.now(),
user: { id: 123, name: '张三' }
},
'user-message'
);prepareSendData(预编码)
在用户点击前完成 Token、白名单校验与 URL 编码,返回可用于打开的 URL。适用于 iOS Safari 等会拦截“异步后再 window.open”的环境:在点击前调用 prepareSendData,在点击回调中同步调用 openEncodedUrl,避免弹窗被拦截。
prepareSendData(
targetUrl: string,
data: any,
type: string,
windowName?: string
): Promise<string>参数: 与 sendData 相同。
返回值: 编码后的完整 URL(可传入 openEncodedUrl 或 window.open(url, windowName))。
示例(iOS Safari 推荐):
let encodedUrl: string | null = null;
// 在页面加载或 hover 时预编码(可提前调用)
client.prepareSendData(targetUrl, data, type).then((url) => {
encodedUrl = url;
}).catch(console.error);
// 在点击处理器中同步打开,不包含 await
sendButton.addEventListener('click', () => {
if (encodedUrl) client.openEncodedUrl(encodedUrl);
});openEncodedUrl(同步打开)
使用 prepareSendData 返回的 URL 同步打开目标窗口。必须在用户手势的同步回调中调用(如 click 内直接调用),否则可能被弹窗拦截。
openEncodedUrl(encodedUrl: string, windowName?: string): voidencodedUrl: 由prepareSendData返回的 URLwindowName: 与prepareSendData时一致,默认为DEFAULT_WINDOW_NAME('agentlink-window')
receiveData
监听来自 URL hash 的数据。
receiveData(
callback: (
data: any,
type: string,
senderInfo?: SenderInfo,
verification?: string
) => void
): () => void参数:
callback(function, 必需): 接收到数据时的回调函数data: 接收到的数据type: 数据类型senderInfo: 发送方信息(包含 domain 和 description)verification: 验证状态信息
返回值:
返回一个取消监听的函数。
示例:
const unsubscribe = client.receiveData((data, type, senderInfo, verification) => {
console.log('收到数据:', data);
console.log('数据类型:', type);
if (senderInfo) {
console.log('发送方域名:', senderInfo.domain);
console.log('发送方描述:', senderInfo.description);
}
console.log('验证状态:', verification);
});
// 取消监听
unsubscribe();getDataFromUrl
从当前 URL 或指定 URL 获取数据并验证发送方。
async getDataFromUrl(url?: string): Promise<{
data: any;
type: string;
senderInfo?: SenderInfo;
verification?: string;
} | null>参数:
url(string, 可选): 要解析的 URL,默认为当前页面的 URL
返回值:
如果 URL 中包含数据,返回包含 data、type、senderInfo 和 verification 的对象;否则返回 null。
示例:
const result = await client.getDataFromUrl();
if (result) {
console.log('数据:', result.data);
console.log('类型:', result.type);
console.log('发送方:', result.senderInfo);
console.log('验证状态:', result.verification);
}getWhitelistInfo
获取白名单信息。
async getWhitelistInfo(includeAll?: boolean): Promise<WhitelistResponse>参数:
includeAll(boolean, 可选): 是否获取所有白名单信息,默认为false(仅获取当前域名)
返回值:
{
whitelist: WhitelistInfo | WhitelistInfo[] | null;
origin: string | null;
}示例:
// 获取当前域名的白名单信息
const info = await client.getWhitelistInfo(false);
console.log('当前域名白名单:', info.whitelist);
// 获取所有白名单信息
const allInfo = await client.getWhitelistInfo(true);
console.log('所有白名单:', allInfo.whitelist);类型定义
AgentLinkClientOptions
interface AgentLinkClientOptions {
serverUrl?: string; // 可选,默认 'https://www.mixlab.top'
}DEFAULT_SERVER_URL
const DEFAULT_SERVER_URL = 'https://www.mixlab.top';如需与默认地址保持一致(例如在配置中引用),可从 SDK 导入:import { DEFAULT_SERVER_URL } from 'agentlink-sdk'。
SenderInfo
interface SenderInfo {
domain: string;
description: string | null;
}WhitelistInfo
interface WhitelistInfo {
domain: string;
description?: string | null;
}WhitelistResponse
interface WhitelistResponse {
whitelist: WhitelistInfo | WhitelistInfo[] | null;
origin: string | null;
}工具函数(LLM 相关)
以下函数可从 agentlink-sdk 直接导入,用于在发送给 LLM 前处理数据(如替换 base64、生成精简 schema)。
inferSchema
从原始数据推断出体积受控的 schema(先替换 base64 为占位符,再按深度/长度/项数截断),便于作为 LLM 输入。
import { inferSchema, type InferredSchema, type InferSchemaOptions } from 'agentlink-sdk';
const schema = inferSchema(rawData, {
maxDepth: 5, // 最大递归深度,默认 5
maxStringLength: 500, // 单段字符串最大字符数,默认 500
maxTotalTextLength: 3000, // 所有字符串总字符数上限,默认 3000
maxArrayItems: 5, // 数组最多保留项数,默认 5
maxKeys: 20, // 对象每层最多键数,默认 20
});extractAndReplaceBase64 / restoreBase64
将数据中的 base64 图片替换为占位符(如 _IMG_0_),或根据映射表恢复。
import { extractAndReplaceBase64, restoreBase64 } from 'agentlink-sdk';
const { processedData, replacements } = extractAndReplaceBase64(rawData);
// 将 processedData 发给 LLM,replacements 用于后续恢复
const restored = restoreBase64(processedData, replacements);extractImages
从数据中递归提取所有 base64 图片(data URL),去重后返回数组。
import { extractImages } from 'agentlink-sdk';
const images = extractImages(rawData);
// 可与 inferSchema 配合:先发 schema 给 LLM,再在结果中回填 imagesfetchCapabilities
请求服务端的 GET /api/capabilities,返回当前实例是否提供 structureData 等能力。不传 serverUrl 时使用默认地址 https://www.mixlab.top。白名单:服务端会校验请求的 Origin/Referer,仅白名单域名或 server 自身可调用,否则返回 403。
import { fetchCapabilities } from 'agentlink-sdk';
// 使用默认 server
const cap = await fetchCapabilities();
if (cap.structureData) {
// 可调用 fetchStructureData
}
// 或指定 serverUrl
const cap2 = await fetchCapabilities('https://your-agentlink-server.com');fetchStructureData
请求服务端的 POST /api/structureData,传入 schema,由服务端 LLM 返回结构化结果(source、category、content、tags 等)。第一个参数 serverUrl 可选,不传时使用默认地址 https://www.mixlab.top;同源时可传 ''。白名单:服务端会校验请求的 Origin/Referer,仅白名单域名或 server 自身可调用,否则返回 403。
可选参数(第三个参数 options):
- systemPrompt(可选):自定义系统提示词。传入后,服务端会将该字符串作为 LLM 的 system 消息,用于控制结构化方式(如正文压缩程度、概括风格、输出语言等)。不传则使用服务端默认提示词。
- temperature(可选):LLM 采样温度,默认由服务端决定(如 0.7)。
- stream(可选,默认
false):为true时按 SSE 流式消费,需同时传 onChunk,每收到一段 LLM 输出会调用onChunk(chunk, accumulated),最终仍返回StructureDataResult。 - onChunk(可选):
stream: true时必传,用于流式展示或预览。
自定义 prompt 的典型用法:在已加入白名单的外部站点中,可直接调用 fetchStructureData 并传入 systemPrompt,让服务端按你的要求生成正文与分类,例如要求「正文压缩到 300 字以内」「用英文输出」等。注意:通过 sendData 把数据发往接收方时,结构化由接收方(如 Memory)用其自身设置完成,发送方无法指定 prompt;只有在当前页面自己调用 fetchStructureData 时才能使用自定义 prompt。
import { inferSchema, fetchStructureData, extractImages } from 'agentlink-sdk';
const schema = inferSchema(rawData);
// 非流式,使用自定义 prompt
const result = await fetchStructureData(undefined, schema, {
systemPrompt: '你是一个信息整理助手。请将正文压缩、概括、精简到 300 字以内,并提炼要点。',
temperature: 0.5,
});
// 流式:边收边回调,最后仍返回完整结果
const resultStream = await fetchStructureData(undefined, schema, {
systemPrompt: '可选:自定义系统提示词',
stream: true,
onChunk(chunk, accumulated) {
console.log('增量:', chunk, '已累积:', accumulated);
},
});
// 可选:用 extractImages(rawData) 回填图片开发与测试
本包使用 Vitest 做单元测试。
| 命令 | 说明 |
|------|------|
| npm run test | 以 watch 模式运行单元测试 |
| npm run test:run | 单次运行全部单元测试 |
| npm run test:llm-schema | 运行 Schema + LLM 集成测试(需配置 AGENTLINK_SERVER_URL 或 LLM_API_URL + LLM_API_KEY) |
- 单元测试:覆盖
base64、schema、compression、url等工具,无需网络,可直接执行npm run test:run。 - LLM Schema 测试:脚本位于
scripts/test-llm-schema.ts,会调用真实 LLM 验证「inferSchema + 回填 images」的端到端流程,适合手动或 CI 可选执行。
特性
- ✅ 跨域数据同步: 通过 URL hash 实现跨域数据传输
- ✅ Token 验证: 自动获取和验证 Token,确保数据来源可信
- ✅ 白名单机制: 支持域名白名单验证
- ✅ 数据压缩: 自动压缩大型数据,优化 URL 长度
- ✅ 缓存优化: Token 和白名单验证结果缓存,减少服务器请求
- ✅ LLM 工具:
inferSchema、extractAndReplaceBase64、restoreBase64、extractImages便于与 LLM 流程集成 - ✅ 服务端能力:
fetchCapabilities、fetchStructureData调用 AgentLink 服务端的 /api/capabilities、/api/structureData(不传 serverUrl 时使用默认https://www.mixlab.top;仅白名单域名或 server 自身可调用) - ✅ 自定义 prompt: 调用
fetchStructureData时可传options.systemPrompt,由服务端按你的提示词进行结构化(如正文压缩、概括风格等);仅在你当前页面直接调用时生效,通过sendData发往接收方时由接收方设置决定 - ✅ 自动化测试: Vitest 单元测试(base64 / schema / compression / url / capabilities / structureData),可选 LLM Schema 集成测试
- ✅ TypeScript 支持: 完整的 TypeScript 类型定义
- ✅ 窗口复用: 支持复用窗口,避免频繁打开新窗口
工作原理
发送数据:
- SDK 自动从服务器获取当前域名的 Token
- 将数据编码到 URL hash 中(包含 Token 和验证信息)
- 通过
window.open打开目标页面并传递数据
接收数据:
- 监听
hashchange事件 - 从 URL hash 中解码数据
- 验证发送方的 Token 和 Origin
- 返回数据及发送方信息
- 监听
安全机制:
- Token 验证:确保数据来自已注册的域名
- 白名单验证:检查域名是否在白名单中
- 缓存机制:减少重复验证请求
示例
完整示例请参考 example.html
发送数据示例
// 使用默认地址
const client = new AgentLinkClient();
// 发送复杂数据
await client.sendData(
'https://target-app.com/receive',
{
action: 'update',
payload: {
userId: 123,
items: ['item1', 'item2', 'item3']
}
},
'user-action'
);接收数据示例
// 使用默认地址,也可传入 serverUrl 使用自建服务端
const client = new AgentLinkClient();
// 监听数据
client.receiveData((data, type, senderInfo, verification) => {
if (senderInfo) {
console.log(`来自 ${senderInfo.domain} 的数据`);
}
switch (type) {
case 'user-action':
handleUserAction(data);
break;
case 'greeting':
handleGreeting(data);
break;
default:
console.log('未知数据类型:', type);
}
});注意事项
- 域名白名单: 发送数据前,请确认当前站点域名已在 AgentLink 服务端的白名单中,否则无法获取 Token;
fetchCapabilities、fetchStructureData同样仅对白名单域名或 server 自身有效。详见上文「跨域与白名单说明」。 - 弹窗拦截: 某些浏览器(尤其 iOS Safari)会拦截在
await之后才执行的window.open。推荐在 iOS 上使用 预编码:在点击前调用prepareSendData,在点击回调中同步调用openEncodedUrl(encodedUrl);或在桌面端确保在用户点击等交互中直接调用sendData。 - URL 长度限制: 虽然 SDK 会自动压缩数据,但过大的数据仍可能超出浏览器 URL 长度限制
- HTTPS 要求: 生产环境建议使用 HTTPS,确保数据传输安全
- Token 缓存: Token 在实例级别缓存,同一实例的多次调用会复用 Token
浏览器支持
- Chrome/Edge (最新版本)
- Firefox (最新版本)
- Safari (最新版本)
许可证
MIT
相关链接
- 示例文件
- 单元测试(
*.test.ts) - LLM Schema 集成测试脚本
- GitHub 仓库
