@kodelyth/feishu 2026.5.39 → 2026.5.42

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.
Files changed (238) hide show
  1. package/api.ts +32 -0
  2. package/channel-entry.ts +20 -0
  3. package/channel-plugin-api.ts +1 -0
  4. package/contract-api.ts +16 -0
  5. package/dist/accounts-D0ow-lRb.js +429 -0
  6. package/dist/api.js +2308 -0
  7. package/dist/app-registration-DBSnysKJ.js +184 -0
  8. package/dist/audio-preflight.runtime-Dpjbn-7r.js +7 -0
  9. package/dist/channel-13WQvQ0u.js +2115 -0
  10. package/dist/channel-entry.js +22 -0
  11. package/dist/channel-plugin-api.js +2 -0
  12. package/dist/channel.runtime-JMJonrJ4.js +729 -0
  13. package/dist/client-D1pzbBGo.js +157 -0
  14. package/dist/contract-api.js +9 -0
  15. package/dist/conversation-id-_58ecqlx.js +139 -0
  16. package/dist/drive-CgHOluXx.js +883 -0
  17. package/dist/index.js +68 -0
  18. package/dist/monitor-oWptK0zL.js +60 -0
  19. package/dist/monitor.account-DHaWlslg.js +5207 -0
  20. package/dist/monitor.state-C211a4tX.js +100 -0
  21. package/dist/probe-CF4duEpK.js +149 -0
  22. package/dist/rolldown-runtime-DUslC3ob.js +14 -0
  23. package/dist/runtime-DSh5rL_d.js +8 -0
  24. package/dist/runtime-api.js +14 -0
  25. package/dist/secret-contract-NSee-WzN.js +119 -0
  26. package/dist/secret-contract-api.js +2 -0
  27. package/dist/security-audit-DWVC0vSK.js +11 -0
  28. package/dist/security-audit-shared-Dpcwxeft.js +38 -0
  29. package/dist/security-contract-api.js +2 -0
  30. package/dist/send-DfZuV4Fi.js +1212 -0
  31. package/dist/session-conversation-Duaukbnl.js +27 -0
  32. package/dist/session-key-api.js +2 -0
  33. package/dist/setup-api.js +2 -0
  34. package/dist/setup-entry.js +15 -0
  35. package/dist/subagent-hooks-Dtegs0kh.js +235 -0
  36. package/dist/subagent-hooks-api.js +23 -0
  37. package/dist/targets-DFskxX4p.js +48 -0
  38. package/dist/thread-bindings-DI7lVSOE.js +222 -0
  39. package/index.ts +82 -0
  40. package/klaw.plugin.json +47 -1712
  41. package/package.json +4 -4
  42. package/runtime-api.ts +52 -0
  43. package/secret-contract-api.ts +5 -0
  44. package/security-contract-api.ts +1 -0
  45. package/session-key-api.ts +1 -0
  46. package/setup-api.ts +3 -0
  47. package/setup-entry.test.ts +19 -0
  48. package/setup-entry.ts +13 -0
  49. package/src/accounts.test.ts +480 -0
  50. package/src/accounts.ts +333 -0
  51. package/src/agent-config.ts +21 -0
  52. package/src/app-registration.ts +331 -0
  53. package/src/approval-auth.test.ts +24 -0
  54. package/src/approval-auth.ts +25 -0
  55. package/src/async.test.ts +35 -0
  56. package/src/async.ts +104 -0
  57. package/src/audio-preflight.runtime.ts +9 -0
  58. package/src/bitable.test.ts +136 -0
  59. package/src/bitable.ts +762 -0
  60. package/src/bot-content.ts +485 -0
  61. package/src/bot-group-name.test.ts +116 -0
  62. package/src/bot-runtime-api.ts +12 -0
  63. package/src/bot-sender-name.ts +125 -0
  64. package/src/bot.broadcast.test.ts +523 -0
  65. package/src/bot.card-action.test.ts +552 -0
  66. package/src/bot.checkBotMentioned.test.ts +265 -0
  67. package/src/bot.helpers.test.ts +135 -0
  68. package/src/bot.stripBotMention.test.ts +126 -0
  69. package/src/bot.test.ts +3671 -0
  70. package/src/bot.ts +1703 -0
  71. package/src/card-action.ts +447 -0
  72. package/src/card-interaction.test.ts +131 -0
  73. package/src/card-interaction.ts +159 -0
  74. package/src/card-test-helpers.ts +54 -0
  75. package/src/card-ux-approval.ts +65 -0
  76. package/src/card-ux-launcher.test.ts +106 -0
  77. package/src/card-ux-launcher.ts +121 -0
  78. package/src/card-ux-shared.ts +33 -0
  79. package/src/channel-runtime-api.ts +16 -0
  80. package/src/channel.runtime.ts +47 -0
  81. package/src/channel.test.ts +1151 -0
  82. package/src/channel.ts +1423 -0
  83. package/src/chat-schema.ts +25 -0
  84. package/src/chat.test.ts +240 -0
  85. package/src/chat.ts +188 -0
  86. package/src/client-timeout.ts +42 -0
  87. package/src/client.test.ts +447 -0
  88. package/src/client.ts +262 -0
  89. package/src/comment-dispatcher-runtime-api.ts +6 -0
  90. package/src/comment-dispatcher.test.ts +185 -0
  91. package/src/comment-dispatcher.ts +107 -0
  92. package/src/comment-handler-runtime-api.ts +3 -0
  93. package/src/comment-handler.test.ts +592 -0
  94. package/src/comment-handler.ts +303 -0
  95. package/src/comment-reaction.test.ts +138 -0
  96. package/src/comment-reaction.ts +259 -0
  97. package/src/comment-shared.test.ts +183 -0
  98. package/src/comment-shared.ts +406 -0
  99. package/src/comment-target.ts +44 -0
  100. package/src/config-schema.test.ts +326 -0
  101. package/src/config-schema.ts +335 -0
  102. package/src/conversation-id.test.ts +18 -0
  103. package/src/conversation-id.ts +199 -0
  104. package/src/dedup-runtime-api.ts +1 -0
  105. package/src/dedup.ts +141 -0
  106. package/src/dedupe-key.ts +72 -0
  107. package/src/directory.static.ts +61 -0
  108. package/src/directory.test.ts +141 -0
  109. package/src/directory.ts +124 -0
  110. package/src/doc-schema.ts +182 -0
  111. package/src/docx-batch-insert.test.ts +116 -0
  112. package/src/docx-batch-insert.ts +223 -0
  113. package/src/docx-color-text.ts +154 -0
  114. package/src/docx-table-ops.test.ts +53 -0
  115. package/src/docx-table-ops.ts +316 -0
  116. package/src/docx-types.ts +38 -0
  117. package/src/docx.account-selection.test.ts +95 -0
  118. package/src/docx.test.ts +701 -0
  119. package/src/docx.ts +1596 -0
  120. package/src/drive-schema.ts +92 -0
  121. package/src/drive.test.ts +1237 -0
  122. package/src/drive.ts +829 -0
  123. package/src/dynamic-agent.test.ts +155 -0
  124. package/src/dynamic-agent.ts +143 -0
  125. package/src/event-types.ts +45 -0
  126. package/src/external-keys.test.ts +20 -0
  127. package/src/external-keys.ts +19 -0
  128. package/src/lifecycle.test-support.ts +220 -0
  129. package/src/media.test.ts +955 -0
  130. package/src/media.ts +1105 -0
  131. package/src/mention-target.types.ts +5 -0
  132. package/src/mention.ts +114 -0
  133. package/src/message-action-contract.ts +13 -0
  134. package/src/monitor-state-runtime-api.ts +7 -0
  135. package/src/monitor-transport-runtime-api.ts +10 -0
  136. package/src/monitor.account.ts +492 -0
  137. package/src/monitor.acp-init-failure.lifecycle.test-support.ts +219 -0
  138. package/src/monitor.bot-identity.ts +86 -0
  139. package/src/monitor.bot-menu-handler.ts +165 -0
  140. package/src/monitor.bot-menu.lifecycle.test-support.ts +224 -0
  141. package/src/monitor.bot-menu.test.ts +188 -0
  142. package/src/monitor.broadcast.reply-once.lifecycle.test-support.ts +264 -0
  143. package/src/monitor.card-action.lifecycle.test-support.ts +421 -0
  144. package/src/monitor.cleanup.test.ts +383 -0
  145. package/src/monitor.comment-notice-handler.ts +105 -0
  146. package/src/monitor.comment.test.ts +967 -0
  147. package/src/monitor.comment.ts +1386 -0
  148. package/src/monitor.lifecycle.test.ts +4 -0
  149. package/src/monitor.message-handler.ts +350 -0
  150. package/src/monitor.reaction.lifecycle.test-support.ts +68 -0
  151. package/src/monitor.reaction.test.ts +739 -0
  152. package/src/monitor.startup.test.ts +213 -0
  153. package/src/monitor.startup.ts +74 -0
  154. package/src/monitor.state.defaults.test.ts +46 -0
  155. package/src/monitor.state.ts +170 -0
  156. package/src/monitor.synthetic-error.ts +18 -0
  157. package/src/monitor.test-mocks.ts +46 -0
  158. package/src/monitor.transport.ts +451 -0
  159. package/src/monitor.ts +100 -0
  160. package/src/monitor.webhook-e2e.test.ts +279 -0
  161. package/src/monitor.webhook-security.test.ts +389 -0
  162. package/src/monitor.webhook.test-helpers.ts +116 -0
  163. package/src/outbound-runtime-api.ts +1 -0
  164. package/src/outbound.test.ts +1118 -0
  165. package/src/outbound.ts +785 -0
  166. package/src/perm-schema.ts +52 -0
  167. package/src/perm.ts +170 -0
  168. package/src/pins.ts +108 -0
  169. package/src/policy.test.ts +223 -0
  170. package/src/policy.ts +318 -0
  171. package/src/post.test.ts +105 -0
  172. package/src/post.ts +275 -0
  173. package/src/probe.test.ts +283 -0
  174. package/src/probe.ts +166 -0
  175. package/src/processing-claims.ts +59 -0
  176. package/src/qr-terminal.ts +1 -0
  177. package/src/reactions.ts +123 -0
  178. package/src/reasoning-preview.test.ts +113 -0
  179. package/src/reasoning-preview.ts +28 -0
  180. package/src/reply-dispatcher-runtime-api.ts +7 -0
  181. package/src/reply-dispatcher.test.ts +1513 -0
  182. package/src/reply-dispatcher.ts +748 -0
  183. package/src/runtime.ts +9 -0
  184. package/src/secret-contract.ts +145 -0
  185. package/src/secret-input.ts +1 -0
  186. package/src/security-audit-shared.ts +69 -0
  187. package/src/security-audit.test.ts +59 -0
  188. package/src/security-audit.ts +1 -0
  189. package/src/send-result.ts +80 -0
  190. package/src/send-target.test.ts +86 -0
  191. package/src/send-target.ts +35 -0
  192. package/src/send.reply-fallback.test.ts +417 -0
  193. package/src/send.test.ts +621 -0
  194. package/src/send.ts +861 -0
  195. package/src/sequential-key.test.ts +72 -0
  196. package/src/sequential-key.ts +25 -0
  197. package/src/sequential-queue.test.ts +165 -0
  198. package/src/sequential-queue.ts +86 -0
  199. package/src/session-conversation.ts +42 -0
  200. package/src/session-route.ts +48 -0
  201. package/src/setup-core.ts +51 -0
  202. package/src/setup-surface.test.ts +484 -0
  203. package/src/setup-surface.ts +618 -0
  204. package/src/streaming-card.test.ts +397 -0
  205. package/src/streaming-card.ts +571 -0
  206. package/src/subagent-hooks.test.ts +627 -0
  207. package/src/subagent-hooks.ts +413 -0
  208. package/src/targets.ts +97 -0
  209. package/src/test-support/lifecycle-test-support.ts +454 -0
  210. package/src/thread-bindings.test.ts +180 -0
  211. package/src/thread-bindings.ts +331 -0
  212. package/src/tool-account-routing.test.ts +250 -0
  213. package/src/tool-account.test.ts +44 -0
  214. package/src/tool-account.ts +93 -0
  215. package/src/tool-factory-test-harness.ts +79 -0
  216. package/src/tool-result.test.ts +32 -0
  217. package/src/tool-result.ts +16 -0
  218. package/src/tools-config.test.ts +21 -0
  219. package/src/tools-config.ts +22 -0
  220. package/src/types.ts +106 -0
  221. package/src/typing.test.ts +144 -0
  222. package/src/typing.ts +214 -0
  223. package/src/wiki-schema.ts +69 -0
  224. package/src/wiki.ts +270 -0
  225. package/subagent-hooks-api.ts +31 -0
  226. package/tsconfig.json +16 -0
  227. package/api.js +0 -7
  228. package/channel-entry.js +0 -7
  229. package/channel-plugin-api.js +0 -7
  230. package/contract-api.js +0 -7
  231. package/index.js +0 -7
  232. package/runtime-api.js +0 -7
  233. package/secret-contract-api.js +0 -7
  234. package/security-contract-api.js +0 -7
  235. package/session-key-api.js +0 -7
  236. package/setup-api.js +0 -7
  237. package/setup-entry.js +0 -7
  238. package/subagent-hooks-api.js +0 -7
@@ -0,0 +1,157 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-DUslC3ob.js";
2
+ import { createRequire } from "node:module";
3
+ import * as Lark from "@larksuiteoapi/node-sdk";
4
+ import { readPluginPackageVersion, resolveAmbientNodeProxyAgent } from "klaw/plugin-sdk/extension-shared";
5
+ //#region extensions/feishu/src/client-timeout.ts
6
+ /** Default HTTP timeout for Feishu API requests (30 seconds). */
7
+ const FEISHU_HTTP_TIMEOUT_MS = 3e4;
8
+ const FEISHU_HTTP_TIMEOUT_MAX_MS = 3e5;
9
+ const FEISHU_HTTP_TIMEOUT_ENV_VAR = "KLAW_FEISHU_HTTP_TIMEOUT_MS";
10
+ function resolveConfiguredHttpTimeoutMs(creds) {
11
+ const clampTimeout = (value) => {
12
+ return Math.min(Math.max(Math.floor(value), 1), FEISHU_HTTP_TIMEOUT_MAX_MS);
13
+ };
14
+ const fromDirectField = creds.httpTimeoutMs;
15
+ if (typeof fromDirectField === "number" && Number.isFinite(fromDirectField) && fromDirectField > 0) return clampTimeout(fromDirectField);
16
+ const envRaw = process.env[FEISHU_HTTP_TIMEOUT_ENV_VAR];
17
+ if (envRaw) {
18
+ const envValue = Number(envRaw);
19
+ if (Number.isFinite(envValue) && envValue > 0) return clampTimeout(envValue);
20
+ }
21
+ const timeout = creds.config?.httpTimeoutMs;
22
+ if (typeof timeout !== "number" || !Number.isFinite(timeout) || timeout <= 0) return FEISHU_HTTP_TIMEOUT_MS;
23
+ return clampTimeout(timeout);
24
+ }
25
+ //#endregion
26
+ //#region extensions/feishu/src/client.ts
27
+ var client_exports = /* @__PURE__ */ __exportAll({
28
+ FEISHU_HTTP_TIMEOUT_ENV_VAR: () => FEISHU_HTTP_TIMEOUT_ENV_VAR,
29
+ FEISHU_HTTP_TIMEOUT_MAX_MS: () => FEISHU_HTTP_TIMEOUT_MAX_MS,
30
+ FEISHU_HTTP_TIMEOUT_MS: () => FEISHU_HTTP_TIMEOUT_MS,
31
+ FEISHU_USER_AGENT: () => FEISHU_USER_AGENT,
32
+ createEventDispatcher: () => createEventDispatcher,
33
+ createFeishuClient: () => createFeishuClient,
34
+ createFeishuWSClient: () => createFeishuWSClient,
35
+ getFeishuUserAgent: () => getFeishuUserAgent,
36
+ pluginVersion: () => pluginVersion
37
+ });
38
+ const pluginVersion = readPluginPackageVersion({ require: createRequire(import.meta.url) });
39
+ const FEISHU_USER_AGENT = `klaw-feishu-builtin/${pluginVersion}/${process.platform}`;
40
+ const FEISHU_WS_CONFIG = {
41
+ PingInterval: 30,
42
+ PingTimeout: 3
43
+ };
44
+ /** User-Agent header value for all Feishu API requests. */
45
+ function getFeishuUserAgent() {
46
+ return FEISHU_USER_AGENT;
47
+ }
48
+ let feishuClientSdk = {
49
+ AppType: Lark.AppType,
50
+ Client: Lark.Client,
51
+ defaultHttpInstance: Lark.defaultHttpInstance,
52
+ Domain: Lark.Domain,
53
+ EventDispatcher: Lark.EventDispatcher,
54
+ LoggerLevel: Lark.LoggerLevel,
55
+ WSClient: Lark.WSClient
56
+ };
57
+ {
58
+ const inst = Lark.defaultHttpInstance;
59
+ if (inst.interceptors?.request) {
60
+ inst.interceptors.request.handlers = [];
61
+ inst.interceptors.request.use((req) => {
62
+ const r = req;
63
+ if (r.headers) r.headers["User-Agent"] = getFeishuUserAgent();
64
+ return req;
65
+ });
66
+ }
67
+ }
68
+ async function getWsProxyAgent() {
69
+ return resolveAmbientNodeProxyAgent();
70
+ }
71
+ const clientCache = /* @__PURE__ */ new Map();
72
+ function resolveDomain(domain) {
73
+ if (domain === "lark") return feishuClientSdk.Domain.Lark;
74
+ if (domain === "feishu" || !domain) return feishuClientSdk.Domain.Feishu;
75
+ return domain.replace(/\/+$/, "");
76
+ }
77
+ /**
78
+ * Create an HTTP instance that delegates to the Lark SDK's default instance
79
+ * but injects a default request timeout and User-Agent header to prevent
80
+ * indefinite hangs and set a standardized User-Agent per OAPI best practices.
81
+ */
82
+ function createTimeoutHttpInstance(defaultTimeoutMs) {
83
+ const base = feishuClientSdk.defaultHttpInstance;
84
+ function injectTimeout(opts) {
85
+ return {
86
+ timeout: defaultTimeoutMs,
87
+ ...opts
88
+ };
89
+ }
90
+ return {
91
+ request: (opts) => base.request(injectTimeout(opts)),
92
+ get: (url, opts) => base.get(url, injectTimeout(opts)),
93
+ post: (url, data, opts) => base.post(url, data, injectTimeout(opts)),
94
+ put: (url, data, opts) => base.put(url, data, injectTimeout(opts)),
95
+ patch: (url, data, opts) => base.patch(url, data, injectTimeout(opts)),
96
+ delete: (url, opts) => base.delete(url, injectTimeout(opts)),
97
+ head: (url, opts) => base.head(url, injectTimeout(opts)),
98
+ options: (url, opts) => base.options(url, injectTimeout(opts))
99
+ };
100
+ }
101
+ /**
102
+ * Create or get a cached Feishu client for an account.
103
+ * Accepts any object with appId, appSecret, and optional domain/accountId.
104
+ */
105
+ function createFeishuClient(creds) {
106
+ const { accountId = "default", appId, appSecret, domain } = creds;
107
+ const defaultHttpTimeoutMs = resolveConfiguredHttpTimeoutMs(creds);
108
+ if (!appId || !appSecret) throw new Error(`Feishu credentials not configured for account "${accountId}"`);
109
+ const cached = clientCache.get(accountId);
110
+ if (cached && cached.config.appId === appId && cached.config.appSecret === appSecret && cached.config.domain === domain && cached.config.httpTimeoutMs === defaultHttpTimeoutMs) return cached.client;
111
+ const client = new feishuClientSdk.Client({
112
+ appId,
113
+ appSecret,
114
+ appType: feishuClientSdk.AppType.SelfBuild,
115
+ domain: resolveDomain(domain),
116
+ httpInstance: createTimeoutHttpInstance(defaultHttpTimeoutMs)
117
+ });
118
+ clientCache.set(accountId, {
119
+ client,
120
+ config: {
121
+ appId,
122
+ appSecret,
123
+ domain,
124
+ httpTimeoutMs: defaultHttpTimeoutMs
125
+ }
126
+ });
127
+ return client;
128
+ }
129
+ /**
130
+ * Create a Feishu WebSocket client for an account.
131
+ * Note: WSClient is not cached since each call creates a new connection.
132
+ */
133
+ async function createFeishuWSClient(account, callbacks = {}) {
134
+ const { accountId, appId, appSecret, domain } = account;
135
+ if (!appId || !appSecret) throw new Error(`Feishu credentials not configured for account "${accountId}"`);
136
+ const agent = await getWsProxyAgent();
137
+ return new feishuClientSdk.WSClient({
138
+ appId,
139
+ appSecret,
140
+ domain: resolveDomain(domain),
141
+ ...callbacks,
142
+ loggerLevel: feishuClientSdk.LoggerLevel.info,
143
+ wsConfig: FEISHU_WS_CONFIG,
144
+ ...agent ? { agent } : {}
145
+ });
146
+ }
147
+ /**
148
+ * Create an event dispatcher for an account.
149
+ */
150
+ function createEventDispatcher(account) {
151
+ return new feishuClientSdk.EventDispatcher({
152
+ encryptKey: account.encryptKey,
153
+ verificationToken: account.verificationToken
154
+ });
155
+ }
156
+ //#endregion
157
+ export { getFeishuUserAgent as a, createFeishuWSClient as i, createEventDispatcher as n, createFeishuClient as r, client_exports as t };
@@ -0,0 +1,9 @@
1
+ import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-_58ecqlx.js";
2
+ import { r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-DI7lVSOE.js";
3
+ import { t as messageActionTargetAliases } from "./security-audit-DWVC0vSK.js";
4
+ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-NSee-WzN.js";
5
+ import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-Dpcwxeft.js";
6
+ //#region extensions/feishu/contract-api.ts
7
+ const feishuSessionBindingAdapterChannels = ["feishu"];
8
+ //#endregion
9
+ export { buildFeishuConversationId, collectFeishuSecurityAuditFindings, collectRuntimeConfigAssignments, createFeishuThreadBindingManager, feishuSessionBindingAdapterChannels, testing as feishuThreadBindingTesting, messageActionTargetAliases, parseFeishuConversationId, parseFeishuDirectConversationId, parseFeishuTargetId, secretTargetRegistryEntries };
@@ -0,0 +1,139 @@
1
+ import { normalizeLowercaseStringOrEmpty } from "klaw/plugin-sdk/string-coerce-runtime";
2
+ //#region extensions/feishu/src/conversation-id.ts
3
+ function normalizeText(value) {
4
+ if (typeof value !== "string") return;
5
+ return value.trim() || void 0;
6
+ }
7
+ function buildFeishuConversationId(params) {
8
+ const chatId = normalizeText(params.chatId) ?? "unknown";
9
+ const senderOpenId = normalizeText(params.senderOpenId);
10
+ const topicId = normalizeText(params.topicId);
11
+ switch (params.scope) {
12
+ case "group_sender": return senderOpenId ? `${chatId}:sender:${senderOpenId}` : chatId;
13
+ case "group_topic": return topicId ? `${chatId}:topic:${topicId}` : chatId;
14
+ case "group_topic_sender":
15
+ if (topicId && senderOpenId) return `${chatId}:topic:${topicId}:sender:${senderOpenId}`;
16
+ if (topicId) return `${chatId}:topic:${topicId}`;
17
+ return senderOpenId ? `${chatId}:sender:${senderOpenId}` : chatId;
18
+ default: return chatId;
19
+ }
20
+ }
21
+ function parseFeishuTargetId(raw) {
22
+ const target = normalizeText(raw);
23
+ if (!target) return;
24
+ const withoutProvider = target.replace(/^(feishu|lark):/i, "").trim();
25
+ if (!withoutProvider) return;
26
+ const lowered = normalizeLowercaseStringOrEmpty(withoutProvider);
27
+ for (const prefix of [
28
+ "chat:",
29
+ "group:",
30
+ "channel:",
31
+ "user:",
32
+ "dm:",
33
+ "open_id:"
34
+ ]) if (lowered.startsWith(prefix)) return normalizeText(withoutProvider.slice(prefix.length));
35
+ return withoutProvider;
36
+ }
37
+ function parseFeishuDirectConversationId(raw) {
38
+ const target = normalizeText(raw);
39
+ if (!target) return;
40
+ const withoutProvider = target.replace(/^(feishu|lark):/i, "").trim();
41
+ if (!withoutProvider) return;
42
+ const lowered = normalizeLowercaseStringOrEmpty(withoutProvider);
43
+ for (const prefix of [
44
+ "user:",
45
+ "dm:",
46
+ "open_id:"
47
+ ]) if (lowered.startsWith(prefix)) return normalizeText(withoutProvider.slice(prefix.length));
48
+ const id = parseFeishuTargetId(target);
49
+ if (!id) return;
50
+ if (id.startsWith("ou_") || id.startsWith("on_")) return id;
51
+ }
52
+ function parseFeishuConversationId(params) {
53
+ const conversationId = normalizeText(params.conversationId);
54
+ const parentConversationId = normalizeText(params.parentConversationId);
55
+ if (!conversationId) return null;
56
+ const topicSenderMatch = conversationId.match(/^(.+):topic:([^:]+):sender:([^:]+)$/i);
57
+ if (topicSenderMatch) {
58
+ const [, chatId, topicId, senderOpenId] = topicSenderMatch;
59
+ return {
60
+ canonicalConversationId: buildFeishuConversationId({
61
+ chatId,
62
+ scope: "group_topic_sender",
63
+ topicId,
64
+ senderOpenId
65
+ }),
66
+ chatId,
67
+ topicId,
68
+ senderOpenId,
69
+ scope: "group_topic_sender"
70
+ };
71
+ }
72
+ const topicMatch = conversationId.match(/^(.+):topic:([^:]+)$/i);
73
+ if (topicMatch) {
74
+ const [, chatId, topicId] = topicMatch;
75
+ return {
76
+ canonicalConversationId: buildFeishuConversationId({
77
+ chatId,
78
+ scope: "group_topic",
79
+ topicId
80
+ }),
81
+ chatId,
82
+ topicId,
83
+ scope: "group_topic"
84
+ };
85
+ }
86
+ const senderMatch = conversationId.match(/^(.+):sender:([^:]+)$/i);
87
+ if (senderMatch) {
88
+ const [, chatId, senderOpenId] = senderMatch;
89
+ return {
90
+ canonicalConversationId: buildFeishuConversationId({
91
+ chatId,
92
+ scope: "group_sender",
93
+ senderOpenId
94
+ }),
95
+ chatId,
96
+ senderOpenId,
97
+ scope: "group_sender"
98
+ };
99
+ }
100
+ if (parentConversationId) return {
101
+ canonicalConversationId: buildFeishuConversationId({
102
+ chatId: parentConversationId,
103
+ scope: "group_topic",
104
+ topicId: conversationId
105
+ }),
106
+ chatId: parentConversationId,
107
+ topicId: conversationId,
108
+ scope: "group_topic"
109
+ };
110
+ return {
111
+ canonicalConversationId: conversationId,
112
+ chatId: conversationId,
113
+ scope: "group"
114
+ };
115
+ }
116
+ function buildFeishuModelOverrideParentCandidates(parentConversationId) {
117
+ const rawId = normalizeText(parentConversationId);
118
+ if (!rawId) return [];
119
+ const topicSenderMatch = rawId.match(/^(.+):topic:([^:]+):sender:([^:]+)$/i);
120
+ if (topicSenderMatch) {
121
+ const chatId = normalizeLowercaseStringOrEmpty(topicSenderMatch[1]);
122
+ const topicId = normalizeLowercaseStringOrEmpty(topicSenderMatch[2]);
123
+ if (chatId && topicId) return [`${chatId}:topic:${topicId}`, chatId];
124
+ return [];
125
+ }
126
+ const topicMatch = rawId.match(/^(.+):topic:([^:]+)$/i);
127
+ if (topicMatch) {
128
+ const chatId = normalizeLowercaseStringOrEmpty(topicMatch[1]);
129
+ return chatId ? [chatId] : [];
130
+ }
131
+ const senderMatch = rawId.match(/^(.+):sender:([^:]+)$/i);
132
+ if (senderMatch) {
133
+ const chatId = normalizeLowercaseStringOrEmpty(senderMatch[1]);
134
+ return chatId ? [chatId] : [];
135
+ }
136
+ return [];
137
+ }
138
+ //#endregion
139
+ export { parseFeishuTargetId as a, parseFeishuDirectConversationId as i, buildFeishuModelOverrideParentCandidates as n, parseFeishuConversationId as r, buildFeishuConversationId as t };