@lmcl/ailo-mcp-feishu 0.0.8 → 0.0.9

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.
@@ -309,30 +309,30 @@ export class FeishuHandler {
309
309
  this.onMessageRead = handler;
310
310
  }
311
311
  buildBridgeMessage(opts) {
312
- const { chatId, text, chatType, senderId = "", senderName = "", chatName, mentionsSelf, timestamp, attachments } = opts;
312
+ const { chatId, text, chatType, senderId = "", senderName = "", chatName, attachments } = opts;
313
313
  const isPrivate = chatType === "私聊";
314
+ // 新 ContextTag 格式(kind/streamKey/routing):
315
+ // - TagChannel 由网关根据 displayName 自动注入,飞书不重复添加
316
+ // - chat_id 参与 stream_key 推导(streamKey=true),仅路由(routing=true)
317
+ // - 私聊:stream_key = feishu:{ou_xxx}(用户 ID)
318
+ // - 群聊:stream_key = feishu:{oc_xxx}(群 ID)
319
+ // - "@我" 是内容语义不是时空场,不放 contextTags
320
+ // - "时间" 由框架在接收时自动渲染,不由通道传入
314
321
  const tags = [
315
- { desc: "类型", value: chatType, core: true },
316
- { desc: "会话", value: chatId, core: true },
322
+ { kind: "conv_type", value: chatType, streamKey: false },
323
+ { kind: "chat_id", value: chatId, streamKey: true, routing: true },
317
324
  ];
318
- if (!isPrivate && chatName) {
319
- tags.push({ desc: "群名", value: chatName, core: true });
325
+ if (!isPrivate) {
326
+ // 群聊:群名作为 stream_key 语义补充,group 标签不参与 stream_key(chat_id 已足够)
327
+ const groupName = chatName || `群${chatId.slice(-8)}`;
328
+ tags.push({ kind: "group", value: groupName, streamKey: false });
320
329
  }
321
- else if (!isPrivate && chatId) {
322
- tags.push({ desc: "群名", value: `群${chatId.slice(-8)}`, core: true });
330
+ if (senderName) {
331
+ tags.push({ kind: "participant", value: senderName, streamKey: false });
323
332
  }
324
- tags.push({ desc: "昵称", value: senderName, core: isPrivate }, { desc: "用户", value: senderId, core: isPrivate });
325
- if (mentionsSelf) {
326
- tags.push({ desc: "@我", value: "是", core: isPrivate });
327
- }
328
- if (timestamp != null && timestamp > 0) {
329
- const d = new Date(timestamp);
330
- const pad = (n) => String(n).padStart(2, "0");
331
- tags.push({
332
- desc: "时间",
333
- value: `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`,
334
- core: false,
335
- });
333
+ if (senderId) {
334
+ // sender_id 仅路由备用(recall agent 按参与者查询时使用),不展示在历史邮戳
335
+ tags.push({ kind: "sender_id", value: senderId, streamKey: false, routing: true });
336
336
  }
337
337
  return { text, contextTags: tags, attachments };
338
338
  }
package/dist/index.js CHANGED
@@ -25,6 +25,8 @@ function feishuBuildChannelPrompt() {
25
25
  const mcpServer = createFeishuMcpServer(handler);
26
26
  runMcpChannel({
27
27
  handler,
28
+ displayName: "飞书",
29
+ defaultRequiresResponse: true,
28
30
  buildChannelPrompt: feishuBuildChannelPrompt,
29
31
  mcpServer,
30
32
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lmcl/ailo-mcp-feishu",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "Ailo 飞书/Lark 通道 MCP",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@larksuiteoapi/node-sdk": "^1.56.1",
17
- "@lmcl/ailo-mcp-sdk": "^0.0.3",
17
+ "@lmcl/ailo-mcp-sdk": "^0.0.4",
18
18
  "@modelcontextprotocol/sdk": "^1.26.0",
19
19
  "dotenv": "^16.4.5",
20
20
  "form-data": "^4.0.0",
@@ -381,33 +381,36 @@ export class FeishuHandler implements BridgeHandler {
381
381
  timestamp?: number;
382
382
  attachments?: Array<{ type: string; path?: string; url?: string; base64?: string; mime?: string; name?: string }>;
383
383
  }): BridgeMessage {
384
- const { chatId, text, chatType, senderId = "", senderName = "", chatName, mentionsSelf, timestamp, attachments } = opts;
384
+ const { chatId, text, chatType, senderId = "", senderName = "", chatName, attachments } = opts;
385
385
  const isPrivate = chatType === "私聊";
386
+
387
+ // 新 ContextTag 格式(kind/streamKey/routing):
388
+ // - TagChannel 由网关根据 displayName 自动注入,飞书不重复添加
389
+ // - chat_id 参与 stream_key 推导(streamKey=true),仅路由(routing=true)
390
+ // - 私聊:stream_key = feishu:{ou_xxx}(用户 ID)
391
+ // - 群聊:stream_key = feishu:{oc_xxx}(群 ID)
392
+ // - "@我" 是内容语义不是时空场,不放 contextTags
393
+ // - "时间" 由框架在接收时自动渲染,不由通道传入
386
394
  const tags: ContextTag[] = [
387
- { desc: "类型", value: chatType, core: true },
388
- { desc: "会话", value: chatId, core: true },
395
+ { kind: "conv_type", value: chatType, streamKey: false },
396
+ { kind: "chat_id", value: chatId, streamKey: true, routing: true },
389
397
  ];
390
- if (!isPrivate && chatName) {
391
- tags.push({ desc: "群名", value: chatName, core: true });
392
- } else if (!isPrivate && chatId) {
393
- tags.push({ desc: "群名", value: `群${chatId.slice(-8)}`, core: true });
398
+
399
+ if (!isPrivate) {
400
+ // 群聊:群名作为 stream_key 语义补充,group 标签不参与 stream_key(chat_id 已足够)
401
+ const groupName = chatName || `群${chatId.slice(-8)}`;
402
+ tags.push({ kind: "group", value: groupName, streamKey: false });
394
403
  }
395
- tags.push(
396
- { desc: "昵称", value: senderName, core: isPrivate },
397
- { desc: "用户", value: senderId, core: isPrivate }
398
- );
399
- if (mentionsSelf) {
400
- tags.push({ desc: "@我", value: "是", core: isPrivate });
404
+
405
+ if (senderName) {
406
+ tags.push({ kind: "participant", value: senderName, streamKey: false });
401
407
  }
402
- if (timestamp != null && timestamp > 0) {
403
- const d = new Date(timestamp);
404
- const pad = (n: number) => String(n).padStart(2, "0");
405
- tags.push({
406
- desc: "时间",
407
- value: `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`,
408
- core: false,
409
- });
408
+
409
+ if (senderId) {
410
+ // sender_id 仅路由备用(recall agent 按参与者查询时使用),不展示在历史邮戳
411
+ tags.push({ kind: "sender_id", value: senderId, streamKey: false, routing: true });
410
412
  }
413
+
411
414
  return { text, contextTags: tags, attachments };
412
415
  }
413
416
 
package/src/index.ts CHANGED
@@ -32,6 +32,8 @@ const mcpServer = createFeishuMcpServer(handler);
32
32
 
33
33
  runMcpChannel({
34
34
  handler,
35
+ displayName: "飞书",
36
+ defaultRequiresResponse: true,
35
37
  buildChannelPrompt: feishuBuildChannelPrompt,
36
38
  mcpServer,
37
39
  });