@soimy/dingtalk 3.6.11 → 3.7.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.
Files changed (161) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +11684 -10583
  3. package/dist/src/{ack-reaction-service.d.ts → ack-reaction/ack-reaction-service.d.ts} +1 -1
  4. package/dist/src/ack-reaction/dynamic-ack-reaction-controller.d.ts +3 -3
  5. package/dist/src/card/ask-user-question-context.d.ts +1 -1
  6. package/dist/src/card/ask-user-question-store.d.ts +1 -1
  7. package/dist/src/card/ask-user-question.d.ts +1 -1
  8. package/dist/src/card/card-action-handler.d.ts +2 -2
  9. package/dist/src/{card-draft-controller.d.ts → card/card-draft-controller.d.ts} +5 -1
  10. package/dist/src/card/card-run-registry.d.ts +2 -2
  11. package/dist/src/{card-service.d.ts → card/card-service.d.ts} +1 -1
  12. package/dist/src/card/card-stop-handler.d.ts +1 -1
  13. package/dist/src/card/card-streaming-mode.d.ts +1 -1
  14. package/dist/src/card/card-task-progress.d.ts +60 -0
  15. package/dist/src/channel.d.ts +6 -6
  16. package/dist/src/command/card-stop-command.d.ts +1 -1
  17. package/dist/src/{feedback-learning-service.d.ts → command/feedback-learning-service.d.ts} +1 -1
  18. package/dist/src/command/inbound-command-dispatch-service.d.ts +2 -2
  19. package/dist/src/{learning-command-service.d.ts → command/learning-command-service.d.ts} +1 -1
  20. package/dist/src/gateway/channel-gateway.d.ts +1 -1
  21. package/dist/src/{connection-manager.d.ts → gateway/connection-manager.d.ts} +1 -1
  22. package/dist/src/{docs-service.d.ts → gateway/docs-service.d.ts} +1 -1
  23. package/dist/src/{inbound-handler.d.ts → gateway/inbound-handler.d.ts} +1 -1
  24. package/dist/src/gateway/inbound-session-queue-dispatcher.d.ts +1 -1
  25. package/dist/src/messaging/attachment-text-extractor.d.ts +1 -1
  26. package/dist/src/messaging/btw-deliver.d.ts +1 -1
  27. package/dist/src/messaging/channel-outbound.d.ts +1 -1
  28. package/dist/src/{media-utils.d.ts → messaging/media-utils.d.ts} +1 -1
  29. package/dist/src/{message-context-store.d.ts → messaging/message-context-store.d.ts} +7 -1
  30. package/dist/src/{message-utils.d.ts → messaging/message-utils.d.ts} +1 -1
  31. package/dist/src/messaging/quoted-context.d.ts +2 -2
  32. package/dist/src/messaging/quoted-file-service.d.ts +1 -1
  33. package/dist/src/messaging/quoted-ref.d.ts +2 -2
  34. package/dist/src/{reply-strategy-card.d.ts → messaging/reply-strategy-card.d.ts} +1 -1
  35. package/dist/src/{reply-strategy-types.d.ts → messaging/reply-strategy-types.d.ts} +10 -1
  36. package/dist/src/{reply-strategy-with-reaction.d.ts → messaging/reply-strategy-with-reaction.d.ts} +1 -1
  37. package/dist/src/{reply-strategy.d.ts → messaging/reply-strategy.d.ts} +1 -1
  38. package/dist/src/{send-service.d.ts → messaging/send-service.d.ts} +1 -1
  39. package/dist/src/platform/channel-status.d.ts +1 -1
  40. package/dist/src/platform/config.d.ts +110 -0
  41. package/dist/src/platform/runtime-events.d.ts +67 -0
  42. package/dist/src/{types.d.ts → platform/types.d.ts} +74 -1
  43. package/dist/src/{persistence-store.d.ts → shared/persistence-store.d.ts} +1 -1
  44. package/dist/src/{utils.d.ts → shared/utils.d.ts} +1 -1
  45. package/dist/src/targeting/agent-name-matcher.d.ts +1 -1
  46. package/dist/src/targeting/agent-routing.d.ts +3 -3
  47. package/dist/src/{session-routing.d.ts → targeting/session-routing.d.ts} +1 -1
  48. package/index.ts +193 -69
  49. package/openclaw.plugin.json +158 -2
  50. package/package.json +16 -16
  51. package/src/{ack-reaction-classifier.ts → ack-reaction/ack-reaction-classifier.ts} +85 -13
  52. package/src/{ack-reaction-service.ts → ack-reaction/ack-reaction-service.ts} +13 -7
  53. package/src/ack-reaction/dynamic-ack-reaction-controller.ts +46 -31
  54. package/src/ack-reaction/dynamic-ack-reaction-progress.ts +4 -1
  55. package/src/card/ask-user-question-context.ts +1 -1
  56. package/src/card/ask-user-question-store.ts +2 -2
  57. package/src/card/ask-user-question.ts +11 -7
  58. package/src/card/card-action-handler.ts +2 -2
  59. package/src/{card-callback-service.ts → card/card-callback-service.ts} +7 -9
  60. package/src/card/card-draft-controller.ts +770 -0
  61. package/src/card/card-markdown-image-reroute.ts +8 -2
  62. package/src/card/card-run-registry.ts +17 -7
  63. package/src/{card-service.ts → card/card-service.ts} +91 -61
  64. package/src/card/card-stop-handler.ts +12 -8
  65. package/src/card/card-streaming-mode.ts +1 -1
  66. package/src/card/card-task-progress.ts +330 -0
  67. package/src/card/draft-stream-loop.ts +119 -0
  68. package/src/card/reasoning-answer-split.ts +125 -121
  69. package/src/card/reasoning-block-assembler.ts +122 -123
  70. package/src/{run-usage-store.ts → card/run-usage-store.ts} +18 -6
  71. package/src/card/statusline-renderer.ts +14 -5
  72. package/src/card/task-model-metadata.ts +8 -3
  73. package/src/channel.ts +14 -16
  74. package/src/command/card-stop-command.ts +2 -2
  75. package/src/{feedback-learning-service.ts → command/feedback-learning-service.ts} +36 -16
  76. package/src/{feedback-learning-store.ts → command/feedback-learning-store.ts} +133 -81
  77. package/src/command/inbound-command-dispatch-service.ts +12 -6
  78. package/src/{learning-command-service.ts → command/learning-command-service.ts} +36 -29
  79. package/src/{session-command-service.ts → command/session-command-service.ts} +3 -1
  80. package/src/gateway/channel-gateway.ts +106 -28
  81. package/src/{connection-manager.ts → gateway/connection-manager.ts} +45 -30
  82. package/src/{docs-service.ts → gateway/docs-service.ts} +5 -5
  83. package/src/{inbound-handler.ts → gateway/inbound-handler.ts} +139 -84
  84. package/src/gateway/inbound-session-queue-dispatcher.ts +18 -14
  85. package/src/{session-lock.ts → gateway/session-lock.ts} +14 -14
  86. package/src/messaging/attachment-text-extractor.ts +21 -7
  87. package/src/messaging/btw-deliver.ts +2 -2
  88. package/src/messaging/channel-actions.ts +15 -7
  89. package/src/messaging/channel-outbound.ts +16 -11
  90. package/src/{media-utils.ts → messaging/media-utils.ts} +276 -72
  91. package/src/{message-context-store.ts → messaging/message-context-store.ts} +11 -2
  92. package/src/{message-utils.ts → messaging/message-utils.ts} +46 -11
  93. package/src/messaging/quoted-context.ts +2 -2
  94. package/src/messaging/quoted-file-service.ts +311 -294
  95. package/src/messaging/quoted-ref.ts +11 -7
  96. package/src/{reply-strategy-card.ts → messaging/reply-strategy-card.ts} +178 -101
  97. package/src/{reply-strategy-markdown.ts → messaging/reply-strategy-markdown.ts} +8 -2
  98. package/src/{reply-strategy-types.ts → messaging/reply-strategy-types.ts} +11 -1
  99. package/src/{reply-strategy-with-reaction.ts → messaging/reply-strategy-with-reaction.ts} +6 -1
  100. package/src/{reply-strategy.ts → messaging/reply-strategy.ts} +2 -2
  101. package/src/{send-service.ts → messaging/send-service.ts} +100 -65
  102. package/src/{auth.ts → platform/auth.ts} +2 -2
  103. package/src/platform/channel-status.ts +3 -3
  104. package/src/{config-schema.ts → platform/config-schema.ts} +81 -4
  105. package/src/{config.ts → platform/config.ts} +167 -19
  106. package/src/{device-registration.ts → platform/device-registration.ts} +5 -4
  107. package/src/{onboarding.ts → platform/onboarding.ts} +1 -4
  108. package/src/{plugin-sdk-channel-actions-augment.ts → platform/plugin-sdk-channel-actions-augment.ts} +6 -5
  109. package/src/platform/runtime-events.ts +202 -0
  110. package/src/{secret-input.ts → platform/secret-input.ts} +117 -11
  111. package/src/{types.ts → platform/types.ts} +76 -1
  112. package/src/{http-client.ts → shared/http-client.ts} +1 -3
  113. package/src/{persistence-store.ts → shared/persistence-store.ts} +6 -6
  114. package/src/{utils.ts → shared/utils.ts} +30 -13
  115. package/src/targeting/agent-name-matcher.ts +1 -1
  116. package/src/targeting/agent-routing.ts +7 -7
  117. package/src/targeting/group-members-store.ts +1 -1
  118. package/src/{session-peer-store.ts → targeting/session-peer-store.ts} +9 -4
  119. package/src/{session-routing.ts → targeting/session-routing.ts} +1 -1
  120. package/src/targeting/target-directory-adapter.ts +3 -3
  121. package/src/targeting/target-directory-store.ts +1 -1
  122. package/src/targeting/target-input.ts +1 -1
  123. package/dist/src/ack-reaction/dynamic-ack-reaction-events.d.ts +0 -35
  124. package/dist/src/config.d.ts +0 -59
  125. package/src/ack-reaction/dynamic-ack-reaction-events.ts +0 -123
  126. package/src/card-draft-controller.ts +0 -637
  127. package/src/draft-stream-loop.ts +0 -119
  128. /package/dist/src/{ack-reaction-classifier.d.ts → ack-reaction/ack-reaction-classifier.d.ts} +0 -0
  129. /package/dist/src/{card-callback-service.d.ts → card/card-callback-service.d.ts} +0 -0
  130. /package/dist/src/{draft-stream-loop.d.ts → card/draft-stream-loop.d.ts} +0 -0
  131. /package/dist/src/{run-usage-store.d.ts → card/run-usage-store.d.ts} +0 -0
  132. /package/dist/src/{feedback-learning-store.d.ts → command/feedback-learning-store.d.ts} +0 -0
  133. /package/dist/src/{session-command-service.d.ts → command/session-command-service.d.ts} +0 -0
  134. /package/dist/src/{session-lock.d.ts → gateway/session-lock.d.ts} +0 -0
  135. /package/dist/src/{proactive-risk-registry.d.ts → messaging/proactive-risk-registry.d.ts} +0 -0
  136. /package/dist/src/{reply-strategy-markdown.d.ts → messaging/reply-strategy-markdown.d.ts} +0 -0
  137. /package/dist/src/{access-control.d.ts → platform/access-control.d.ts} +0 -0
  138. /package/dist/src/{auth.d.ts → platform/auth.d.ts} +0 -0
  139. /package/dist/src/{config-schema.d.ts → platform/config-schema.d.ts} +0 -0
  140. /package/dist/src/{device-registration.d.ts → platform/device-registration.d.ts} +0 -0
  141. /package/dist/src/{logger-context.d.ts → platform/logger-context.d.ts} +0 -0
  142. /package/dist/src/{onboarding.d.ts → platform/onboarding.d.ts} +0 -0
  143. /package/dist/src/{plugin-sdk-channel-actions-augment.d.ts → platform/plugin-sdk-channel-actions-augment.d.ts} +0 -0
  144. /package/dist/src/{runtime.d.ts → platform/runtime.d.ts} +0 -0
  145. /package/dist/src/{secret-input.d.ts → platform/secret-input.d.ts} +0 -0
  146. /package/dist/src/{session-state.d.ts → platform/session-state.d.ts} +0 -0
  147. /package/dist/src/{signature.d.ts → platform/signature.d.ts} +0 -0
  148. /package/dist/src/{dedup.d.ts → shared/dedup.d.ts} +0 -0
  149. /package/dist/src/{http-client.d.ts → shared/http-client.d.ts} +0 -0
  150. /package/dist/src/{path-utils.d.ts → shared/path-utils.d.ts} +0 -0
  151. /package/dist/src/{peer-id-registry.d.ts → targeting/peer-id-registry.d.ts} +0 -0
  152. /package/dist/src/{session-peer-store.d.ts → targeting/session-peer-store.d.ts} +0 -0
  153. /package/src/{proactive-risk-registry.ts → messaging/proactive-risk-registry.ts} +0 -0
  154. /package/src/{access-control.ts → platform/access-control.ts} +0 -0
  155. /package/src/{logger-context.ts → platform/logger-context.ts} +0 -0
  156. /package/src/{runtime.ts → platform/runtime.ts} +0 -0
  157. /package/src/{session-state.ts → platform/session-state.ts} +0 -0
  158. /package/src/{signature.ts → platform/signature.ts} +0 -0
  159. /package/src/{dedup.ts → shared/dedup.ts} +0 -0
  160. /package/src/{path-utils.ts → shared/path-utils.ts} +0 -0
  161. /package/src/{peer-id-registry.ts → targeting/peer-id-registry.ts} +0 -0
package/src/channel.ts CHANGED
@@ -1,22 +1,27 @@
1
1
  import { buildJsonChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
2
2
  import type { OpenClawConfig } from "openclaw/plugin-sdk/core";
3
3
  import pluginManifest from "../openclaw.plugin.json";
4
- import { getConfig, isConfigured, mergeAccountWithDefaults, resolveGroupConfig } from "./config";
5
4
  import {
6
5
  CHANNEL_INFLIGHT_NAMESPACE_POLICY,
7
6
  createDingTalkGateway,
8
7
  } from "./gateway/channel-gateway";
9
- import { dingtalkSetupAdapter, dingtalkSetupWizard } from "./onboarding.js";
10
8
  import { createDingTalkMessageActions } from "./messaging/channel-actions";
11
9
  import { createDingTalkOutbound } from "./messaging/channel-outbound";
12
10
  import { createDingTalkStatus } from "./platform/channel-status";
13
- import { hasConfiguredSecretInput } from "./secret-input";
11
+ import {
12
+ getConfig,
13
+ isConfigured,
14
+ mergeAccountWithDefaults,
15
+ resolveGroupConfig,
16
+ } from "./platform/config";
17
+ import { dingtalkSetupAdapter, dingtalkSetupWizard } from "./platform/onboarding.js";
18
+ import { hasConfiguredSecretInput } from "./platform/secret-input";
19
+ import type { DingTalkChannelPlugin, ResolvedAccount } from "./platform/types";
14
20
  import {
15
21
  listDingTalkDirectoryGroups,
16
22
  listDingTalkDirectoryUsers,
17
23
  } from "./targeting/target-directory-adapter";
18
24
  import { looksLikeDingTalkTargetId, normalizeDingTalkTarget } from "./targeting/target-input";
19
- import type { DingTalkChannelPlugin, ResolvedAccount } from "./types";
20
25
 
21
26
  // DingTalk Channel Definition (assembly layer).
22
27
  // Heavy logic is delegated to service modules for maintainability.
@@ -98,13 +103,6 @@ export const dingtalkPlugin: DingTalkChannelPlugin = {
98
103
  }
99
104
  return config.groupPolicy !== "open";
100
105
  },
101
- resolveGroupIntroHint: ({ groupId, groupChannel }: any): string | undefined => {
102
- const parts = [`conversationId=${groupId}`];
103
- if (groupChannel) {
104
- parts.push(`sessionKey=${groupChannel}`);
105
- }
106
- return `DingTalk IDs: ${parts.join(", ")}.`;
107
- },
108
106
  },
109
107
  messaging: {
110
108
  normalizeTarget: (raw: string) => (raw ? normalizeDingTalkTarget(raw) : undefined),
@@ -128,13 +126,13 @@ export const dingtalkPlugin: DingTalkChannelPlugin = {
128
126
  };
129
127
 
130
128
  export { CHANNEL_INFLIGHT_NAMESPACE_POLICY };
131
- export { getAccessToken } from "./auth";
132
- export { createAICard, finishAICard, streamAICard } from "./card-service";
133
- export { detectMediaTypeFromExtension } from "./media-utils";
134
- export { getLogger } from "./logger-context";
129
+ export { getAccessToken } from "./platform/auth";
130
+ export { createAICard, finishAICard, streamAICard } from "./card/card-service";
131
+ export { detectMediaTypeFromExtension } from "./messaging/media-utils";
132
+ export { getLogger } from "./platform/logger-context";
135
133
  export {
136
134
  sendBySession,
137
135
  sendMessage,
138
136
  sendProactiveMedia,
139
137
  uploadMedia,
140
- } from "./send-service";
138
+ } from "./messaging/send-service";
@@ -1,7 +1,7 @@
1
1
  import { resolveNativeCommandSessionTargets } from "openclaw/plugin-sdk/command-auth";
2
2
  import type { OpenClawConfig } from "openclaw/plugin-sdk/core";
3
- import { getDingTalkRuntime } from "../runtime";
4
- import type { Logger } from "../types";
3
+ import { getDingTalkRuntime } from "../platform/runtime";
4
+ import type { Logger } from "../platform/types";
5
5
 
6
6
  /**
7
7
  * Dispatch a native targeted `/stop` command through the OpenClaw SDK,
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import type { DingTalkConfig, MessageContent } from "../platform/types";
2
3
  import {
3
4
  appendFeedbackEvent,
4
5
  appendOutboundReplySnapshot,
@@ -24,12 +25,14 @@ import {
24
25
  upsertTargetSet,
25
26
  upsertLearnedRule,
26
27
  } from "./feedback-learning-store";
27
- import type { DingTalkConfig, MessageContent } from "./types";
28
28
 
29
29
  const NEGATIVE_SIGNAL_PATTERNS: Array<{ pattern: RegExp; category: ReflectionCategory }> = [
30
30
  { pattern: /(没看图|没看图片|看图|补发原图|别猜图)/i, category: "missing_image_context" },
31
31
  { pattern: /(引用|原文|原消息|别猜|没拿到|没看到)/i, category: "quoted_context_missing" },
32
- { pattern: /(不是这个意思|理解错|答偏|重新答|重新回答|我问的是)/i, category: "misunderstood_intent" },
32
+ {
33
+ pattern: /(不是这个意思|理解错|答偏|重新答|重新回答|我问的是)/i,
34
+ category: "misunderstood_intent",
35
+ },
33
36
  ];
34
37
 
35
38
  function buildRuleInstruction(category: ReflectionCategory): string {
@@ -128,7 +131,9 @@ function updateLearnedRule(
128
131
  return;
129
132
  }
130
133
  const ruleId = `rule_${category}`;
131
- const existing = listLearnedRules({ storePath, accountId }).find((rule) => rule.ruleId === ruleId);
134
+ const existing = listLearnedRules({ storePath, accountId }).find(
135
+ (rule) => rule.ruleId === ruleId,
136
+ );
132
137
  const negativeCount = (existing?.negativeCount || 0) + 1;
133
138
  const positiveCount = existing?.positiveCount || 0;
134
139
  const rule: LearnedRuleRecord = {
@@ -286,7 +291,10 @@ export function analyzeImplicitNegativeFeedback(params: {
286
291
  snapshot,
287
292
  content: params.content,
288
293
  });
289
- if (category === "generic_negative" && !NEGATIVE_SIGNAL_PATTERNS.some((item) => item.pattern.test(params.signalText))) {
294
+ if (
295
+ category === "generic_negative" &&
296
+ !NEGATIVE_SIGNAL_PATTERNS.some((item) => item.pattern.test(params.signalText))
297
+ ) {
290
298
  return;
291
299
  }
292
300
 
@@ -418,7 +426,9 @@ export function applyManualGlobalLearningRule(params: {
418
426
  return null;
419
427
  }
420
428
  const ruleId = `manual_${Date.now()}`;
421
- const exactReplyMatch = params.instruction.trim().match(/^当用户问[“"](.+?)[”"]时,必须回答[“"](.+?)[”"][。.!!]?$/);
429
+ const exactReplyMatch = params.instruction
430
+ .trim()
431
+ .match(/^当用户问[“"](.+?)[”"]时,必须回答[“"](.+?)[”"][。.!!]?$/);
422
432
  upsertLearnedRule({
423
433
  storePath: params.storePath,
424
434
  accountId: params.accountId,
@@ -452,9 +462,13 @@ export function resolveManualForcedReply(params: {
452
462
  return null;
453
463
  }
454
464
  const targetMatched = params.targetId
455
- ? listTargetRules({ storePath: params.storePath, accountId: params.accountId, targetId: params.targetId })
456
- .filter((rule) => rule.enabled && rule.manual && rule.triggerText && rule.forcedReply)
457
- .find((rule) => normalizeManualTriggerText(rule.triggerText) === text)
465
+ ? listTargetRules({
466
+ storePath: params.storePath,
467
+ accountId: params.accountId,
468
+ targetId: params.targetId,
469
+ })
470
+ .filter((rule) => rule.enabled && rule.manual && rule.triggerText && rule.forcedReply)
471
+ .find((rule) => normalizeManualTriggerText(rule.triggerText) === text)
458
472
  : null;
459
473
  if (targetMatched?.forcedReply) {
460
474
  return targetMatched.forcedReply;
@@ -502,7 +516,9 @@ export function applyManualTargetLearningRule(params: {
502
516
  return null;
503
517
  }
504
518
  const ruleId = `manual_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
505
- const exactReplyMatch = params.instruction.trim().match(/^当用户问[“"](.+?)[”"]时,必须回答[“"](.+?)[”"][。.!!]?$/);
519
+ const exactReplyMatch = params.instruction
520
+ .trim()
521
+ .match(/^当用户问[“"](.+?)[”"]时,必须回答[“"](.+?)[”"][。.!!]?$/);
506
522
  upsertTargetRule({
507
523
  storePath: params.storePath,
508
524
  accountId: params.accountId,
@@ -533,13 +549,17 @@ export function applyManualTargetsLearningRule(params: {
533
549
  return [];
534
550
  }
535
551
  return params.targetIds
536
- .map((targetId) => applyManualTargetLearningRule({
537
- storePath: params.storePath,
538
- accountId: params.accountId,
539
- targetId,
540
- instruction: params.instruction,
541
- }))
542
- .map((result, index) => result ? { targetId: params.targetIds[index], ruleId: result.ruleId } : null)
552
+ .map((targetId) =>
553
+ applyManualTargetLearningRule({
554
+ storePath: params.storePath,
555
+ accountId: params.accountId,
556
+ targetId,
557
+ instruction: params.instruction,
558
+ }),
559
+ )
560
+ .map((result, index) =>
561
+ result ? { targetId: params.targetIds[index], ruleId: result.ruleId } : null,
562
+ )
543
563
  .filter(Boolean) as Array<{ targetId: string; ruleId: string }>;
544
564
  }
545
565
 
@@ -1,4 +1,4 @@
1
- import { readNamespaceJson, writeNamespaceJsonAtomic } from "./persistence-store";
1
+ import { readNamespaceJson, writeNamespaceJsonAtomic } from "../shared/persistence-store";
2
2
 
3
3
  const MAX_EVENTS = 200;
4
4
  const MAX_SNAPSHOTS = 100;
@@ -151,57 +151,70 @@ function writeListBucket<T>(
151
151
  });
152
152
  }
153
153
 
154
- export function appendFeedbackEvent(
155
- params: { storePath?: string; accountId: string; targetId: string; event: FeedbackEventRecord },
156
- ): void {
154
+ export function appendFeedbackEvent(params: {
155
+ storePath?: string;
156
+ accountId: string;
157
+ targetId: string;
158
+ event: FeedbackEventRecord;
159
+ }): void {
157
160
  const bucket = readListBucket<FeedbackEventRecord>(EVENTS_NAMESPACE, params);
158
161
  bucket.entries = trimNewest([...bucket.entries, params.event], MAX_EVENTS);
159
162
  writeListBucket(EVENTS_NAMESPACE, { ...params, entries: bucket.entries });
160
163
  }
161
164
 
162
- export function listFeedbackEvents(
163
- params: { storePath?: string; accountId: string; targetId: string },
164
- ): FeedbackEventRecord[] {
165
+ export function listFeedbackEvents(params: {
166
+ storePath?: string;
167
+ accountId: string;
168
+ targetId: string;
169
+ }): FeedbackEventRecord[] {
165
170
  return readListBucket<FeedbackEventRecord>(EVENTS_NAMESPACE, params).entries;
166
171
  }
167
172
 
168
- export function appendOutboundReplySnapshot(
169
- params: { storePath?: string; accountId: string; targetId: string; snapshot: OutboundReplySnapshot },
170
- ): void {
173
+ export function appendOutboundReplySnapshot(params: {
174
+ storePath?: string;
175
+ accountId: string;
176
+ targetId: string;
177
+ snapshot: OutboundReplySnapshot;
178
+ }): void {
171
179
  const bucket = readListBucket<OutboundReplySnapshot>(SNAPSHOTS_NAMESPACE, params);
172
180
  bucket.entries = trimNewest([...bucket.entries, params.snapshot], MAX_SNAPSHOTS);
173
181
  writeListBucket(SNAPSHOTS_NAMESPACE, { ...params, entries: bucket.entries });
174
182
  }
175
183
 
176
- export function listOutboundReplySnapshots(
177
- params: { storePath?: string; accountId: string; targetId: string },
178
- ): OutboundReplySnapshot[] {
184
+ export function listOutboundReplySnapshots(params: {
185
+ storePath?: string;
186
+ accountId: string;
187
+ targetId: string;
188
+ }): OutboundReplySnapshot[] {
179
189
  return readListBucket<OutboundReplySnapshot>(SNAPSHOTS_NAMESPACE, params).entries;
180
190
  }
181
191
 
182
- export function appendReflectionRecord(
183
- params: { storePath?: string; accountId: string; targetId: string; reflection: ReflectionRecord },
184
- ): void {
192
+ export function appendReflectionRecord(params: {
193
+ storePath?: string;
194
+ accountId: string;
195
+ targetId: string;
196
+ reflection: ReflectionRecord;
197
+ }): void {
185
198
  const bucket = readListBucket<ReflectionRecord>(REFLECTIONS_NAMESPACE, params);
186
199
  bucket.entries = trimNewest([...bucket.entries, params.reflection], MAX_REFLECTIONS);
187
200
  writeListBucket(REFLECTIONS_NAMESPACE, { ...params, entries: bucket.entries });
188
201
  }
189
202
 
190
- export function listReflectionRecords(
191
- params: { storePath?: string; accountId: string; targetId: string },
192
- ): ReflectionRecord[] {
203
+ export function listReflectionRecords(params: {
204
+ storePath?: string;
205
+ accountId: string;
206
+ targetId: string;
207
+ }): ReflectionRecord[] {
193
208
  return readListBucket<ReflectionRecord>(REFLECTIONS_NAMESPACE, params).entries;
194
209
  }
195
210
 
196
- export function appendSessionLearningNote(
197
- params: {
198
- storePath?: string;
199
- accountId: string;
200
- targetId: string;
201
- note: Omit<SessionLearningNote, "expiresAt"> & { expiresAt?: number };
202
- ttlMs?: number;
203
- },
204
- ): void {
211
+ export function appendSessionLearningNote(params: {
212
+ storePath?: string;
213
+ accountId: string;
214
+ targetId: string;
215
+ note: Omit<SessionLearningNote, "expiresAt"> & { expiresAt?: number };
216
+ ttlMs?: number;
217
+ }): void {
205
218
  const ttlMs = params.ttlMs && params.ttlMs > 0 ? params.ttlMs : DEFAULT_NOTE_TTL_MS;
206
219
  const nowMs = Date.now();
207
220
  const bucket = readListBucket<SessionLearningNote>(SESSION_NOTES_NAMESPACE, params);
@@ -216,18 +229,23 @@ export function appendSessionLearningNote(
216
229
  });
217
230
  }
218
231
 
219
- export function listActiveSessionLearningNotes(
220
- params: { storePath?: string; accountId: string; targetId: string; nowMs?: number },
221
- ): SessionLearningNote[] {
232
+ export function listActiveSessionLearningNotes(params: {
233
+ storePath?: string;
234
+ accountId: string;
235
+ targetId: string;
236
+ nowMs?: number;
237
+ }): SessionLearningNote[] {
222
238
  const nowMs = params.nowMs ?? Date.now();
223
239
  return readListBucket<SessionLearningNote>(SESSION_NOTES_NAMESPACE, params).entries.filter(
224
240
  (note) => note.expiresAt > nowMs,
225
241
  );
226
242
  }
227
243
 
228
- export function upsertLearnedRule(
229
- params: { storePath?: string; accountId: string; rule: LearnedRuleRecord },
230
- ): void {
244
+ export function upsertLearnedRule(params: {
245
+ storePath?: string;
246
+ accountId: string;
247
+ rule: LearnedRuleRecord;
248
+ }): void {
231
249
  if (!params.storePath) {
232
250
  return;
233
251
  }
@@ -253,9 +271,10 @@ export function upsertLearnedRule(
253
271
  });
254
272
  }
255
273
 
256
- export function listLearnedRules(
257
- params: { storePath?: string; accountId: string },
258
- ): LearnedRuleRecord[] {
274
+ export function listLearnedRules(params: {
275
+ storePath?: string;
276
+ accountId: string;
277
+ }): LearnedRuleRecord[] {
259
278
  if (!params.storePath) {
260
279
  return [];
261
280
  }
@@ -268,9 +287,11 @@ export function listLearnedRules(
268
287
  return Object.values(bucket.rules).toSorted((left, right) => right.updatedAt - left.updatedAt);
269
288
  }
270
289
 
271
- export function disableLearnedRule(
272
- params: { storePath?: string; accountId: string; ruleId: string },
273
- ): boolean {
290
+ export function disableLearnedRule(params: {
291
+ storePath?: string;
292
+ accountId: string;
293
+ ruleId: string;
294
+ }): boolean {
274
295
  if (!params.storePath) {
275
296
  return false;
276
297
  }
@@ -298,9 +319,11 @@ export function disableLearnedRule(
298
319
  return true;
299
320
  }
300
321
 
301
- export function deleteLearnedRule(
302
- params: { storePath?: string; accountId: string; ruleId: string },
303
- ): boolean {
322
+ export function deleteLearnedRule(params: {
323
+ storePath?: string;
324
+ accountId: string;
325
+ ruleId: string;
326
+ }): boolean {
304
327
  if (!params.storePath) {
305
328
  return false;
306
329
  }
@@ -323,9 +346,10 @@ export function deleteLearnedRule(
323
346
  return true;
324
347
  }
325
348
 
326
- function readTargetRuleIndex(
327
- params: { storePath?: string; accountId: string },
328
- ): TargetRuleIndexBucket {
349
+ function readTargetRuleIndex(params: {
350
+ storePath?: string;
351
+ accountId: string;
352
+ }): TargetRuleIndexBucket {
329
353
  if (!params.storePath) {
330
354
  return { updatedAt: 0, targetIds: [] };
331
355
  }
@@ -337,9 +361,11 @@ function readTargetRuleIndex(
337
361
  });
338
362
  }
339
363
 
340
- function writeTargetRuleIndex(
341
- params: { storePath?: string; accountId: string; targetIds: string[] },
342
- ): void {
364
+ function writeTargetRuleIndex(params: {
365
+ storePath?: string;
366
+ accountId: string;
367
+ targetIds: string[];
368
+ }): void {
343
369
  if (!params.storePath) {
344
370
  return;
345
371
  }
@@ -354,9 +380,11 @@ function writeTargetRuleIndex(
354
380
  });
355
381
  }
356
382
 
357
- function readTargetRuleBucket(
358
- params: { storePath?: string; accountId: string; targetId: string },
359
- ): LearnedRuleBucket {
383
+ function readTargetRuleBucket(params: {
384
+ storePath?: string;
385
+ accountId: string;
386
+ targetId: string;
387
+ }): LearnedRuleBucket {
360
388
  if (!params.storePath) {
361
389
  return { updatedAt: 0, rules: {} };
362
390
  }
@@ -368,9 +396,12 @@ function readTargetRuleBucket(
368
396
  });
369
397
  }
370
398
 
371
- function writeTargetRuleBucket(
372
- params: { storePath?: string; accountId: string; targetId: string; bucket: LearnedRuleBucket },
373
- ): void {
399
+ function writeTargetRuleBucket(params: {
400
+ storePath?: string;
401
+ accountId: string;
402
+ targetId: string;
403
+ bucket: LearnedRuleBucket;
404
+ }): void {
374
405
  if (!params.storePath) {
375
406
  return;
376
407
  }
@@ -382,9 +413,12 @@ function writeTargetRuleBucket(
382
413
  });
383
414
  }
384
415
 
385
- export function upsertTargetRule(
386
- params: { storePath?: string; accountId: string; targetId: string; rule: LearnedRuleRecord },
387
- ): void {
416
+ export function upsertTargetRule(params: {
417
+ storePath?: string;
418
+ accountId: string;
419
+ targetId: string;
420
+ rule: LearnedRuleRecord;
421
+ }): void {
388
422
  if (!params.storePath) {
389
423
  return;
390
424
  }
@@ -411,18 +445,24 @@ export function upsertTargetRule(
411
445
  });
412
446
  }
413
447
 
414
- export function listTargetRules(
415
- params: { storePath?: string; accountId: string; targetId: string },
416
- ): LearnedRuleRecord[] {
448
+ export function listTargetRules(params: {
449
+ storePath?: string;
450
+ accountId: string;
451
+ targetId: string;
452
+ }): LearnedRuleRecord[] {
417
453
  return Object.values(readTargetRuleBucket(params).rules).toSorted(
418
454
  (left, right) => right.updatedAt - left.updatedAt,
419
455
  );
420
456
  }
421
457
 
422
- export function listAllScopedRules(
423
- params: { storePath?: string; accountId: string },
424
- ): ScopedLearnedRuleRecord[] {
425
- const globalRules = listLearnedRules(params).map((rule) => ({ ...rule, scope: "global" as const }));
458
+ export function listAllScopedRules(params: {
459
+ storePath?: string;
460
+ accountId: string;
461
+ }): ScopedLearnedRuleRecord[] {
462
+ const globalRules = listLearnedRules(params).map((rule) => ({
463
+ ...rule,
464
+ scope: "global" as const,
465
+ }));
426
466
  const targetIds = readTargetRuleIndex(params).targetIds;
427
467
  const targetRules = targetIds.flatMap((targetId) =>
428
468
  listTargetRules({ ...params, targetId }).map((rule) => ({
@@ -431,12 +471,16 @@ export function listAllScopedRules(
431
471
  targetId,
432
472
  })),
433
473
  );
434
- return [...targetRules, ...globalRules].toSorted((left, right) => right.updatedAt - left.updatedAt);
474
+ return [...targetRules, ...globalRules].toSorted(
475
+ (left, right) => right.updatedAt - left.updatedAt,
476
+ );
435
477
  }
436
478
 
437
- export function disableScopedRule(
438
- params: { storePath?: string; accountId: string; ruleId: string },
439
- ): { existed: boolean; scope?: "global" | "target"; targetId?: string } {
479
+ export function disableScopedRule(params: {
480
+ storePath?: string;
481
+ accountId: string;
482
+ ruleId: string;
483
+ }): { existed: boolean; scope?: "global" | "target"; targetId?: string } {
440
484
  if (disableLearnedRule(params)) {
441
485
  return { existed: true, scope: "global" };
442
486
  }
@@ -463,9 +507,11 @@ export function disableScopedRule(
463
507
  return { existed: false };
464
508
  }
465
509
 
466
- export function deleteScopedRule(
467
- params: { storePath?: string; accountId: string; ruleId: string },
468
- ): { existed: boolean; scope?: "global" | "target"; targetId?: string } {
510
+ export function deleteScopedRule(params: {
511
+ storePath?: string;
512
+ accountId: string;
513
+ ruleId: string;
514
+ }): { existed: boolean; scope?: "global" | "target"; targetId?: string } {
469
515
  if (deleteLearnedRule(params)) {
470
516
  return { existed: true, scope: "global" };
471
517
  }
@@ -487,9 +533,12 @@ export function deleteScopedRule(
487
533
  return { existed: false };
488
534
  }
489
535
 
490
- export function upsertTargetSet(
491
- params: { storePath?: string; accountId: string; name: string; targetIds: string[] },
492
- ): void {
536
+ export function upsertTargetSet(params: {
537
+ storePath?: string;
538
+ accountId: string;
539
+ name: string;
540
+ targetIds: string[];
541
+ }): void {
493
542
  if (!params.storePath) {
494
543
  return;
495
544
  }
@@ -512,9 +561,11 @@ export function upsertTargetSet(
512
561
  });
513
562
  }
514
563
 
515
- export function getTargetSet(
516
- params: { storePath?: string; accountId: string; name: string },
517
- ): TargetSetRecord | null {
564
+ export function getTargetSet(params: {
565
+ storePath?: string;
566
+ accountId: string;
567
+ name: string;
568
+ }): TargetSetRecord | null {
518
569
  if (!params.storePath) {
519
570
  return null;
520
571
  }
@@ -527,9 +578,10 @@ export function getTargetSet(
527
578
  return bucket.sets[params.name] || null;
528
579
  }
529
580
 
530
- export function listTargetSets(
531
- params: { storePath?: string; accountId: string },
532
- ): TargetSetRecord[] {
581
+ export function listTargetSets(params: {
582
+ storePath?: string;
583
+ accountId: string;
584
+ }): TargetSetRecord[] {
533
585
  if (!params.storePath) {
534
586
  return [];
535
587
  }
@@ -1,3 +1,9 @@
1
+ import type {
2
+ DingTalkConfig,
3
+ HandleDingTalkMessageParams,
4
+ MessageContent,
5
+ } from "../platform/types";
6
+ import type { SessionPeerSourceKind } from "../targeting/session-peer-store";
1
7
  import {
2
8
  applyManualGlobalLearningRule,
3
9
  applyManualSessionLearningNote,
@@ -10,7 +16,7 @@ import {
10
16
  listLearningTargetSets,
11
17
  listScopedLearningRules,
12
18
  resolveManualForcedReply,
13
- } from "../feedback-learning-service";
19
+ } from "./feedback-learning-service";
14
20
  import {
15
21
  formatLearnAppliedReply,
16
22
  formatLearnCommandHelp,
@@ -24,7 +30,7 @@ import {
24
30
  formatWhoAmIReply,
25
31
  isLearningOwner,
26
32
  parseLearnCommand,
27
- } from "../learning-command-service";
33
+ } from "./learning-command-service";
28
34
  import {
29
35
  formatSessionAliasBoundReply,
30
36
  formatSessionAliasClearedReply,
@@ -34,9 +40,7 @@ import {
34
40
  formatSessionAliasValidationErrorReply,
35
41
  parseSessionCommand,
36
42
  validateSessionAlias,
37
- } from "../session-command-service";
38
- import type { SessionPeerSourceKind } from "../session-peer-store";
39
- import type { DingTalkConfig, HandleDingTalkMessageParams, MessageContent } from "../types";
43
+ } from "./session-command-service";
40
44
 
41
45
  type InboundCommandDispatchParams = {
42
46
  cfg: HandleDingTalkMessageParams["cfg"];
@@ -405,7 +409,9 @@ export async function handleInboundCommandDispatch(
405
409
  accountId: params.accountId,
406
410
  })
407
411
  .slice(0, 10)
408
- .map((targetSet) => `- [target-set] ${targetSet.name} => ${targetSet.targetIds.join(", ")}`);
412
+ .map(
413
+ (targetSet) => `- [target-set] ${targetSet.name} => ${targetSet.targetIds.join(", ")}`,
414
+ );
409
415
  await params.sendReply(formatLearnListReply([...rules, ...targetSets]));
410
416
  return true;
411
417
  }