agentlink-sdk 1.0.10 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -71,7 +71,9 @@ client.receiveData((data, type, senderInfo) => {
71
71
  - 使用默认服务端(如 `https://www.mixlab.top`)时,需在对应后台将你的域名加入白名单。
72
72
  - 使用自建服务端时,请在自己的 AgentLink 管理后台添加域名。
73
73
 
74
- 总结:只要你的域名已在所用 AgentLink 服务端的白名单中,即可正常跨域调用、发送数据,无需担心浏览器跨域限制。
74
+ - **能力接口**:`fetchCapabilities`、`fetchStructureData` 调用服务端的 `/api/capabilities`、`/api/structureData` 时,服务端会校验请求的 **Origin/Referer**,仅**白名单域名**或 **server 自身**可调用;非白名单会返回 403(域名不在白名单中)。
75
+
76
+ 总结:只要你的域名已在所用 AgentLink 服务端的白名单中,即可正常跨域调用、发送数据及使用能力接口,无需担心浏览器跨域限制。
75
77
 
76
78
  ## API 文档
77
79
 
@@ -123,6 +125,50 @@ await client.sendData(
123
125
  );
124
126
  ```
125
127
 
128
+ ##### prepareSendData(预编码)
129
+
130
+ 在用户点击前完成 Token、白名单校验与 URL 编码,返回可用于打开的 URL。适用于 **iOS Safari** 等会拦截“异步后再 `window.open`”的环境:在点击前调用 `prepareSendData`,在点击回调中**同步**调用 `openEncodedUrl`,避免弹窗被拦截。
131
+
132
+ ```typescript
133
+ prepareSendData(
134
+ targetUrl: string,
135
+ data: any,
136
+ type: string,
137
+ windowName?: string
138
+ ): Promise<string>
139
+ ```
140
+
141
+ **参数:** 与 `sendData` 相同。
142
+
143
+ **返回值:** 编码后的完整 URL(可传入 `openEncodedUrl` 或 `window.open(url, windowName)`)。
144
+
145
+ **示例(iOS Safari 推荐):**
146
+
147
+ ```typescript
148
+ let encodedUrl: string | null = null;
149
+
150
+ // 在页面加载或 hover 时预编码(可提前调用)
151
+ client.prepareSendData(targetUrl, data, type).then((url) => {
152
+ encodedUrl = url;
153
+ }).catch(console.error);
154
+
155
+ // 在点击处理器中同步打开,不包含 await
156
+ sendButton.addEventListener('click', () => {
157
+ if (encodedUrl) client.openEncodedUrl(encodedUrl);
158
+ });
159
+ ```
160
+
161
+ ##### openEncodedUrl(同步打开)
162
+
163
+ 使用 `prepareSendData` 返回的 URL 同步打开目标窗口。**必须在用户手势的同步回调中调用**(如 click 内直接调用),否则可能被弹窗拦截。
164
+
165
+ ```typescript
166
+ openEncodedUrl(encodedUrl: string, windowName?: string): void
167
+ ```
168
+
169
+ - `encodedUrl`: 由 `prepareSendData` 返回的 URL
170
+ - `windowName`: 与 `prepareSendData` 时一致,默认为 `DEFAULT_WINDOW_NAME`(`'agentlink-window'`)
171
+
126
172
  ##### receiveData
127
173
 
128
174
  监听来自 URL hash 的数据。
@@ -324,7 +370,7 @@ const images = extractImages(rawData);
324
370
 
325
371
  ### fetchCapabilities
326
372
 
327
- 请求服务端的 GET /api/capabilities,返回当前实例是否提供 structureData 等能力。不传 `serverUrl` 时使用默认地址 `https://www.mixlab.top`。
373
+ 请求服务端的 GET /api/capabilities,返回当前实例是否提供 structureData 等能力。不传 `serverUrl` 时使用默认地址 `https://www.mixlab.top`。**白名单**:服务端会校验请求的 Origin/Referer,仅白名单域名或 server 自身可调用,否则返回 403。
328
374
 
329
375
  ```typescript
330
376
  import { fetchCapabilities } from 'agentlink-sdk';
@@ -341,24 +387,31 @@ const cap2 = await fetchCapabilities('https://your-agentlink-server.com');
341
387
 
342
388
  ### fetchStructureData
343
389
 
344
- 请求服务端的 POST /api/structureData,传入 schema,由服务端 LLM 返回结构化结果(source、category、content、tags 等)。第一个参数 `serverUrl` 可选,不传时使用默认地址 `https://www.mixlab.top`;同源时可传 `''`。
390
+ 请求服务端的 POST /api/structureData,传入 schema,由服务端 LLM 返回结构化结果(source、category、content、tags 等)。第一个参数 `serverUrl` 可选,不传时使用默认地址 `https://www.mixlab.top`;同源时可传 `''`。**白名单**:服务端会校验请求的 Origin/Referer,仅白名单域名或 server 自身可调用,否则返回 403。
391
+
392
+ **可选参数(第三个参数 `options`):**
345
393
 
394
+ - **systemPrompt**(可选):自定义系统提示词。传入后,服务端会将该字符串作为 LLM 的 system 消息,用于控制结构化方式(如正文压缩程度、概括风格、输出语言等)。不传则使用服务端默认提示词。
395
+ - **temperature**(可选):LLM 采样温度,默认由服务端决定(如 0.7)。
346
396
  - **stream**(可选,默认 `false`):为 `true` 时按 SSE 流式消费,需同时传 **onChunk**,每收到一段 LLM 输出会调用 `onChunk(chunk, accumulated)`,最终仍返回 `StructureDataResult`。
347
397
  - **onChunk**(可选):`stream: true` 时必传,用于流式展示或预览。
348
398
 
399
+ **自定义 prompt 的典型用法**:在已加入白名单的外部站点中,可直接调用 `fetchStructureData` 并传入 `systemPrompt`,让服务端按你的要求生成正文与分类,例如要求「正文压缩到 300 字以内」「用英文输出」等。注意:通过 `sendData` 把数据发往接收方时,结构化由接收方(如 Memory)用其自身设置完成,发送方无法指定 prompt;只有在**当前页面自己调用** `fetchStructureData` 时才能使用自定义 prompt。
400
+
349
401
  ```typescript
350
402
  import { inferSchema, fetchStructureData, extractImages } from 'agentlink-sdk';
351
403
 
352
404
  const schema = inferSchema(rawData);
353
405
 
354
- // 非流式(默认)
406
+ // 非流式,使用自定义 prompt
355
407
  const result = await fetchStructureData(undefined, schema, {
356
- systemPrompt: '可选',
357
- temperature: 0.7,
408
+ systemPrompt: '你是一个信息整理助手。请将正文压缩、概括、精简到 300 字以内,并提炼要点。',
409
+ temperature: 0.5,
358
410
  });
359
411
 
360
412
  // 流式:边收边回调,最后仍返回完整结果
361
413
  const resultStream = await fetchStructureData(undefined, schema, {
414
+ systemPrompt: '可选:自定义系统提示词',
362
415
  stream: true,
363
416
  onChunk(chunk, accumulated) {
364
417
  console.log('增量:', chunk, '已累积:', accumulated);
@@ -389,7 +442,8 @@ const resultStream = await fetchStructureData(undefined, schema, {
389
442
  - ✅ **数据压缩**: 自动压缩大型数据,优化 URL 长度
390
443
  - ✅ **缓存优化**: Token 和白名单验证结果缓存,减少服务器请求
391
444
  - ✅ **LLM 工具**: `inferSchema`、`extractAndReplaceBase64`、`restoreBase64`、`extractImages` 便于与 LLM 流程集成
392
- - ✅ **服务端能力**: `fetchCapabilities`、`fetchStructureData` 调用 AgentLink 服务端的 /api/capabilities、/api/structureData(不传 serverUrl 时使用默认 `https://www.mixlab.top`)
445
+ - ✅ **服务端能力**: `fetchCapabilities`、`fetchStructureData` 调用 AgentLink 服务端的 /api/capabilities、/api/structureData(不传 serverUrl 时使用默认 `https://www.mixlab.top`;仅白名单域名或 server 自身可调用)
446
+ - ✅ **自定义 prompt**: 调用 `fetchStructureData` 时可传 `options.systemPrompt`,由服务端按你的提示词进行结构化(如正文压缩、概括风格等);仅在你当前页面直接调用时生效,通过 `sendData` 发往接收方时由接收方设置决定
393
447
  - ✅ **自动化测试**: Vitest 单元测试(base64 / schema / compression / url / capabilities / structureData),可选 LLM Schema 集成测试
394
448
  - ✅ **TypeScript 支持**: 完整的 TypeScript 类型定义
395
449
  - ✅ **窗口复用**: 支持复用窗口,避免频繁打开新窗口
@@ -463,8 +517,8 @@ client.receiveData((data, type, senderInfo, verification) => {
463
517
 
464
518
  ## 注意事项
465
519
 
466
- 1. **域名白名单**: 发送数据前,请确认当前站点域名已在 AgentLink 服务端的白名单中,否则无法获取 Token。详见上文「跨域与白名单说明」。
467
- 2. **弹窗拦截**: 某些浏览器可能会拦截 `window.open`,确保在用户交互事件(如点击)中调用 `sendData`
520
+ 1. **域名白名单**: 发送数据前,请确认当前站点域名已在 AgentLink 服务端的白名单中,否则无法获取 Token;`fetchCapabilities`、`fetchStructureData` 同样仅对白名单域名或 server 自身有效。详见上文「跨域与白名单说明」。
521
+ 2. **弹窗拦截**: 某些浏览器(尤其 **iOS Safari**)会拦截在 `await` 之后才执行的 `window.open`。推荐在 iOS 上使用 **预编码**:在点击前调用 `prepareSendData`,在点击回调中**同步**调用 `openEncodedUrl(encodedUrl)`;或在桌面端确保在用户点击等交互中直接调用 `sendData`。
468
522
  3. **URL 长度限制**: 虽然 SDK 会自动压缩数据,但过大的数据仍可能超出浏览器 URL 长度限制
469
523
  4. **HTTPS 要求**: 生产环境建议使用 HTTPS,确保数据传输安全
470
524
  5. **Token 缓存**: Token 在实例级别缓存,同一实例的多次调用会复用 Token
package/dist/index.d.mts CHANGED
@@ -23,6 +23,8 @@ interface SenderInfo {
23
23
  /**
24
24
  * AgentLink 客户端 SDK (URL Hash + Token 方案)
25
25
  */
26
+ /** 默认窗口名称,用于 sendData / openEncodedUrl 复用同一窗口 */
27
+ declare const DEFAULT_WINDOW_NAME = "agentlink-window";
26
28
  declare class AgentLinkClient {
27
29
  private serverUrl;
28
30
  private static DEFAULT_WINDOW_NAME;
@@ -48,6 +50,23 @@ declare class AgentLinkClient {
48
50
  * 验证发送端的 Token 和 Origin
49
51
  */
50
52
  private verifySender;
53
+ /**
54
+ * 预编码:完成 Token、白名单校验与 URL 编码,返回可用于 window.open 的 URL。
55
+ * 用于 iOS Safari 等严格限制弹窗的环境:在用户点击前调用此方法,在点击回调中同步执行 openEncodedUrl(url)。
56
+ * @param targetUrl 目标应用的地址
57
+ * @param data 要发送的数据
58
+ * @param type 数据类型标识
59
+ * @param windowName 窗口名称,与 openEncodedUrl 一致以便复用窗口(默认: DEFAULT_WINDOW_NAME)
60
+ * @returns 编码后的完整 URL,可直接传入 openEncodedUrl 或 window.open(encodedUrl, windowName)
61
+ */
62
+ prepareSendData(targetUrl: string, data: any, type: string, windowName?: string): Promise<string>;
63
+ /**
64
+ * 使用预编码的 URL 同步打开目标窗口(不包含任何 await)。
65
+ * 必须在用户手势的同步回调中调用(如 click 处理器内直接调用),否则可能被弹窗拦截。
66
+ * @param encodedUrl 由 prepareSendData 返回的 URL
67
+ * @param windowName 与 prepareSendData 时使用的窗口名一致,默认: DEFAULT_WINDOW_NAME
68
+ */
69
+ openEncodedUrl(encodedUrl: string, windowName?: string): void;
51
70
  /**
52
71
  * 发送数据到目标应用
53
72
  * @param targetUrl 目标应用的地址
@@ -171,6 +190,13 @@ interface StructureDataResult {
171
190
  images?: string[];
172
191
  metadata?: Record<string, unknown>;
173
192
  }
193
+ /** 可选:传给服务端 /api/structureData 的 body.llm,有则用设置 LLM,无则用内置 */
194
+ interface RequestLlm {
195
+ apiUrl: string;
196
+ apiKey: string;
197
+ model?: string;
198
+ temperature?: number;
199
+ }
174
200
  interface FetchStructureDataOptions {
175
201
  systemPrompt?: string;
176
202
  temperature?: number;
@@ -181,6 +207,8 @@ interface FetchStructureDataOptions {
181
207
  stream?: boolean;
182
208
  /** stream 为 true 时,每收到一段 LLM 输出会调用 onChunk(chunk, accumulated) */
183
209
  onChunk?: (chunk: string, accumulated: string) => void;
210
+ /** 可选:服务端有则用该 LLM,无则用内置 */
211
+ llm?: RequestLlm;
184
212
  }
185
213
  /**
186
214
  * 从 SSE 响应文本中解析最后一条 result 或 error
@@ -219,4 +247,4 @@ declare function restoreBase64(data: any, replacements: Map<string, string>): an
219
247
  */
220
248
  declare function extractImages(data: any): string[];
221
249
 
222
- export { AgentLinkClient, type AgentLinkClientOptions, type CapabilitiesResponse, DEFAULT_SERVER_URL, type FetchStructureDataOptions, type InferSchemaOptions, type InferredSchema, type SenderInfo, type StructureDataResult, type URLData, type WhitelistInfo, type WhitelistResponse, base64ToUint8Array, compress, decodeDataFromUrl, decompress, encodeDataToUrl, extractAndReplaceBase64, extractImages, fetchCapabilities, fetchStructureData, fetchWhitelistInfo, inferSchema, parseSSEResult, restoreBase64, uint8ArrayToBase64, verifyWhitelist };
250
+ export { AgentLinkClient, type AgentLinkClientOptions, type CapabilitiesResponse, DEFAULT_SERVER_URL, DEFAULT_WINDOW_NAME, type FetchStructureDataOptions, type InferSchemaOptions, type InferredSchema, type RequestLlm, type SenderInfo, type StructureDataResult, type URLData, type WhitelistInfo, type WhitelistResponse, base64ToUint8Array, compress, decodeDataFromUrl, decompress, encodeDataToUrl, extractAndReplaceBase64, extractImages, fetchCapabilities, fetchStructureData, fetchWhitelistInfo, inferSchema, parseSSEResult, restoreBase64, uint8ArrayToBase64, verifyWhitelist };
package/dist/index.d.ts CHANGED
@@ -23,6 +23,8 @@ interface SenderInfo {
23
23
  /**
24
24
  * AgentLink 客户端 SDK (URL Hash + Token 方案)
25
25
  */
26
+ /** 默认窗口名称,用于 sendData / openEncodedUrl 复用同一窗口 */
27
+ declare const DEFAULT_WINDOW_NAME = "agentlink-window";
26
28
  declare class AgentLinkClient {
27
29
  private serverUrl;
28
30
  private static DEFAULT_WINDOW_NAME;
@@ -48,6 +50,23 @@ declare class AgentLinkClient {
48
50
  * 验证发送端的 Token 和 Origin
49
51
  */
50
52
  private verifySender;
53
+ /**
54
+ * 预编码:完成 Token、白名单校验与 URL 编码,返回可用于 window.open 的 URL。
55
+ * 用于 iOS Safari 等严格限制弹窗的环境:在用户点击前调用此方法,在点击回调中同步执行 openEncodedUrl(url)。
56
+ * @param targetUrl 目标应用的地址
57
+ * @param data 要发送的数据
58
+ * @param type 数据类型标识
59
+ * @param windowName 窗口名称,与 openEncodedUrl 一致以便复用窗口(默认: DEFAULT_WINDOW_NAME)
60
+ * @returns 编码后的完整 URL,可直接传入 openEncodedUrl 或 window.open(encodedUrl, windowName)
61
+ */
62
+ prepareSendData(targetUrl: string, data: any, type: string, windowName?: string): Promise<string>;
63
+ /**
64
+ * 使用预编码的 URL 同步打开目标窗口(不包含任何 await)。
65
+ * 必须在用户手势的同步回调中调用(如 click 处理器内直接调用),否则可能被弹窗拦截。
66
+ * @param encodedUrl 由 prepareSendData 返回的 URL
67
+ * @param windowName 与 prepareSendData 时使用的窗口名一致,默认: DEFAULT_WINDOW_NAME
68
+ */
69
+ openEncodedUrl(encodedUrl: string, windowName?: string): void;
51
70
  /**
52
71
  * 发送数据到目标应用
53
72
  * @param targetUrl 目标应用的地址
@@ -171,6 +190,13 @@ interface StructureDataResult {
171
190
  images?: string[];
172
191
  metadata?: Record<string, unknown>;
173
192
  }
193
+ /** 可选:传给服务端 /api/structureData 的 body.llm,有则用设置 LLM,无则用内置 */
194
+ interface RequestLlm {
195
+ apiUrl: string;
196
+ apiKey: string;
197
+ model?: string;
198
+ temperature?: number;
199
+ }
174
200
  interface FetchStructureDataOptions {
175
201
  systemPrompt?: string;
176
202
  temperature?: number;
@@ -181,6 +207,8 @@ interface FetchStructureDataOptions {
181
207
  stream?: boolean;
182
208
  /** stream 为 true 时,每收到一段 LLM 输出会调用 onChunk(chunk, accumulated) */
183
209
  onChunk?: (chunk: string, accumulated: string) => void;
210
+ /** 可选:服务端有则用该 LLM,无则用内置 */
211
+ llm?: RequestLlm;
184
212
  }
185
213
  /**
186
214
  * 从 SSE 响应文本中解析最后一条 result 或 error
@@ -219,4 +247,4 @@ declare function restoreBase64(data: any, replacements: Map<string, string>): an
219
247
  */
220
248
  declare function extractImages(data: any): string[];
221
249
 
222
- export { AgentLinkClient, type AgentLinkClientOptions, type CapabilitiesResponse, DEFAULT_SERVER_URL, type FetchStructureDataOptions, type InferSchemaOptions, type InferredSchema, type SenderInfo, type StructureDataResult, type URLData, type WhitelistInfo, type WhitelistResponse, base64ToUint8Array, compress, decodeDataFromUrl, decompress, encodeDataToUrl, extractAndReplaceBase64, extractImages, fetchCapabilities, fetchStructureData, fetchWhitelistInfo, inferSchema, parseSSEResult, restoreBase64, uint8ArrayToBase64, verifyWhitelist };
250
+ export { AgentLinkClient, type AgentLinkClientOptions, type CapabilitiesResponse, DEFAULT_SERVER_URL, DEFAULT_WINDOW_NAME, type FetchStructureDataOptions, type InferSchemaOptions, type InferredSchema, type RequestLlm, type SenderInfo, type StructureDataResult, type URLData, type WhitelistInfo, type WhitelistResponse, base64ToUint8Array, compress, decodeDataFromUrl, decompress, encodeDataToUrl, extractAndReplaceBase64, extractImages, fetchCapabilities, fetchStructureData, fetchWhitelistInfo, inferSchema, parseSSEResult, restoreBase64, uint8ArrayToBase64, verifyWhitelist };
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  AgentLinkClient: () => AgentLinkClient,
24
24
  DEFAULT_SERVER_URL: () => DEFAULT_SERVER_URL,
25
+ DEFAULT_WINDOW_NAME: () => DEFAULT_WINDOW_NAME,
25
26
  base64ToUint8Array: () => base64ToUint8Array,
26
27
  compress: () => compress,
27
28
  decodeDataFromUrl: () => decodeDataFromUrl,
@@ -182,6 +183,7 @@ async function fetchWhitelistInfo(serverUrl, includeAll = false) {
182
183
 
183
184
  // src/client.ts
184
185
  var DEFAULT_SERVER_URL = "https://www.mixlab.top";
186
+ var DEFAULT_WINDOW_NAME = "agentlink-window";
185
187
  var _AgentLinkClient = class _AgentLinkClient {
186
188
  constructor(options = {}) {
187
189
  // 发送端 Token 缓存(实例级别)
@@ -259,24 +261,45 @@ var _AgentLinkClient = class _AgentLinkClient {
259
261
  return { domain: data.domain, description: data.description };
260
262
  }
261
263
  /**
262
- * 发送数据到目标应用
264
+ * 预编码:完成 Token、白名单校验与 URL 编码,返回可用于 window.open 的 URL。
265
+ * 用于 iOS Safari 等严格限制弹窗的环境:在用户点击前调用此方法,在点击回调中同步执行 openEncodedUrl(url)。
263
266
  * @param targetUrl 目标应用的地址
264
267
  * @param data 要发送的数据
265
268
  * @param type 数据类型标识
266
- * @param windowName 窗口名称,用于复用(默认: 'agentlink-window'
269
+ * @param windowName 窗口名称,与 openEncodedUrl 一致以便复用窗口(默认: DEFAULT_WINDOW_NAME
270
+ * @returns 编码后的完整 URL,可直接传入 openEncodedUrl 或 window.open(encodedUrl, windowName)
267
271
  */
268
- async sendData(targetUrl, data, type, windowName = _AgentLinkClient.DEFAULT_WINDOW_NAME) {
272
+ async prepareSendData(targetUrl, data, type, windowName = _AgentLinkClient.DEFAULT_WINDOW_NAME) {
269
273
  const token = await this.ensureToken();
270
274
  const origin = window.location.origin;
271
275
  const isWhitelisted = await this.checkWhitelist(origin);
272
276
  const verification = isWhitelisted ? "mixlab launchpad\u52A0\u901F\u8BA1\u5212" : "\u672A\u9A8C\u8BC1";
273
- const encodedUrl = await encodeDataToUrl(data, type, token, origin, targetUrl, verification);
277
+ return encodeDataToUrl(data, type, token, origin, targetUrl, verification);
278
+ }
279
+ /**
280
+ * 使用预编码的 URL 同步打开目标窗口(不包含任何 await)。
281
+ * 必须在用户手势的同步回调中调用(如 click 处理器内直接调用),否则可能被弹窗拦截。
282
+ * @param encodedUrl 由 prepareSendData 返回的 URL
283
+ * @param windowName 与 prepareSendData 时使用的窗口名一致,默认: DEFAULT_WINDOW_NAME
284
+ */
285
+ openEncodedUrl(encodedUrl, windowName = _AgentLinkClient.DEFAULT_WINDOW_NAME) {
274
286
  const targetWindow = window.open(encodedUrl, windowName);
275
287
  if (!targetWindow) {
276
288
  throw new Error("[AgentLink] Failed to open target window. It might be blocked by a popup blocker.");
277
289
  }
278
290
  targetWindow.focus();
279
291
  }
292
+ /**
293
+ * 发送数据到目标应用
294
+ * @param targetUrl 目标应用的地址
295
+ * @param data 要发送的数据
296
+ * @param type 数据类型标识
297
+ * @param windowName 窗口名称,用于复用(默认: 'agentlink-window')
298
+ */
299
+ async sendData(targetUrl, data, type, windowName = _AgentLinkClient.DEFAULT_WINDOW_NAME) {
300
+ const encodedUrl = await this.prepareSendData(targetUrl, data, type, windowName);
301
+ this.openEncodedUrl(encodedUrl, windowName);
302
+ }
280
303
  /**
281
304
  * 监听来自 URL 的数据
282
305
  * @param callback 接收到数据时的回调函数,现在包含验证信息
@@ -338,7 +361,7 @@ var _AgentLinkClient = class _AgentLinkClient {
338
361
  return fetchWhitelistInfo(this.serverUrl, includeAll);
339
362
  }
340
363
  };
341
- _AgentLinkClient.DEFAULT_WINDOW_NAME = "agentlink-window";
364
+ _AgentLinkClient.DEFAULT_WINDOW_NAME = DEFAULT_WINDOW_NAME;
342
365
  // 接收端验证结果缓存(静态,跨实例共享)
343
366
  _AgentLinkClient.tokenCache = /* @__PURE__ */ new Map();
344
367
  // 白名单验证缓存(避免重复请求)
@@ -394,6 +417,7 @@ async function fetchStructureData(serverUrl = DEFAULT_SERVER_URL, schema, option
394
417
  const body = { schema };
395
418
  if (options?.systemPrompt != null) body.systemPrompt = options.systemPrompt;
396
419
  if (options?.temperature != null) body.temperature = options.temperature;
420
+ if (options?.llm != null) body.llm = options.llm;
397
421
  const res = await fetch(`${base}/api/structureData`, {
398
422
  method: "POST",
399
423
  headers: { "Content-Type": "application/json" },
package/dist/index.mjs CHANGED
@@ -140,6 +140,7 @@ async function fetchWhitelistInfo(serverUrl, includeAll = false) {
140
140
 
141
141
  // src/client.ts
142
142
  var DEFAULT_SERVER_URL = "https://www.mixlab.top";
143
+ var DEFAULT_WINDOW_NAME = "agentlink-window";
143
144
  var _AgentLinkClient = class _AgentLinkClient {
144
145
  constructor(options = {}) {
145
146
  // 发送端 Token 缓存(实例级别)
@@ -217,24 +218,45 @@ var _AgentLinkClient = class _AgentLinkClient {
217
218
  return { domain: data.domain, description: data.description };
218
219
  }
219
220
  /**
220
- * 发送数据到目标应用
221
+ * 预编码:完成 Token、白名单校验与 URL 编码,返回可用于 window.open 的 URL。
222
+ * 用于 iOS Safari 等严格限制弹窗的环境:在用户点击前调用此方法,在点击回调中同步执行 openEncodedUrl(url)。
221
223
  * @param targetUrl 目标应用的地址
222
224
  * @param data 要发送的数据
223
225
  * @param type 数据类型标识
224
- * @param windowName 窗口名称,用于复用(默认: 'agentlink-window'
226
+ * @param windowName 窗口名称,与 openEncodedUrl 一致以便复用窗口(默认: DEFAULT_WINDOW_NAME
227
+ * @returns 编码后的完整 URL,可直接传入 openEncodedUrl 或 window.open(encodedUrl, windowName)
225
228
  */
226
- async sendData(targetUrl, data, type, windowName = _AgentLinkClient.DEFAULT_WINDOW_NAME) {
229
+ async prepareSendData(targetUrl, data, type, windowName = _AgentLinkClient.DEFAULT_WINDOW_NAME) {
227
230
  const token = await this.ensureToken();
228
231
  const origin = window.location.origin;
229
232
  const isWhitelisted = await this.checkWhitelist(origin);
230
233
  const verification = isWhitelisted ? "mixlab launchpad\u52A0\u901F\u8BA1\u5212" : "\u672A\u9A8C\u8BC1";
231
- const encodedUrl = await encodeDataToUrl(data, type, token, origin, targetUrl, verification);
234
+ return encodeDataToUrl(data, type, token, origin, targetUrl, verification);
235
+ }
236
+ /**
237
+ * 使用预编码的 URL 同步打开目标窗口(不包含任何 await)。
238
+ * 必须在用户手势的同步回调中调用(如 click 处理器内直接调用),否则可能被弹窗拦截。
239
+ * @param encodedUrl 由 prepareSendData 返回的 URL
240
+ * @param windowName 与 prepareSendData 时使用的窗口名一致,默认: DEFAULT_WINDOW_NAME
241
+ */
242
+ openEncodedUrl(encodedUrl, windowName = _AgentLinkClient.DEFAULT_WINDOW_NAME) {
232
243
  const targetWindow = window.open(encodedUrl, windowName);
233
244
  if (!targetWindow) {
234
245
  throw new Error("[AgentLink] Failed to open target window. It might be blocked by a popup blocker.");
235
246
  }
236
247
  targetWindow.focus();
237
248
  }
249
+ /**
250
+ * 发送数据到目标应用
251
+ * @param targetUrl 目标应用的地址
252
+ * @param data 要发送的数据
253
+ * @param type 数据类型标识
254
+ * @param windowName 窗口名称,用于复用(默认: 'agentlink-window')
255
+ */
256
+ async sendData(targetUrl, data, type, windowName = _AgentLinkClient.DEFAULT_WINDOW_NAME) {
257
+ const encodedUrl = await this.prepareSendData(targetUrl, data, type, windowName);
258
+ this.openEncodedUrl(encodedUrl, windowName);
259
+ }
238
260
  /**
239
261
  * 监听来自 URL 的数据
240
262
  * @param callback 接收到数据时的回调函数,现在包含验证信息
@@ -296,7 +318,7 @@ var _AgentLinkClient = class _AgentLinkClient {
296
318
  return fetchWhitelistInfo(this.serverUrl, includeAll);
297
319
  }
298
320
  };
299
- _AgentLinkClient.DEFAULT_WINDOW_NAME = "agentlink-window";
321
+ _AgentLinkClient.DEFAULT_WINDOW_NAME = DEFAULT_WINDOW_NAME;
300
322
  // 接收端验证结果缓存(静态,跨实例共享)
301
323
  _AgentLinkClient.tokenCache = /* @__PURE__ */ new Map();
302
324
  // 白名单验证缓存(避免重复请求)
@@ -352,6 +374,7 @@ async function fetchStructureData(serverUrl = DEFAULT_SERVER_URL, schema, option
352
374
  const body = { schema };
353
375
  if (options?.systemPrompt != null) body.systemPrompt = options.systemPrompt;
354
376
  if (options?.temperature != null) body.temperature = options.temperature;
377
+ if (options?.llm != null) body.llm = options.llm;
355
378
  const res = await fetch(`${base}/api/structureData`, {
356
379
  method: "POST",
357
380
  headers: { "Content-Type": "application/json" },
@@ -612,6 +635,7 @@ function inferSchema(rawData, options) {
612
635
  export {
613
636
  AgentLinkClient,
614
637
  DEFAULT_SERVER_URL,
638
+ DEFAULT_WINDOW_NAME,
615
639
  base64ToUint8Array,
616
640
  compress,
617
641
  decodeDataFromUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentlink-sdk",
3
- "version": "1.0.10",
3
+ "version": "1.1.0",
4
4
  "description": "AgentLink client SDK for cross-domain data synchronization via URL hash",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",