ylib-syim 0.0.33 → 0.0.34

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ylib-syim",
3
- "version": "0.0.33",
3
+ "version": "0.0.34",
4
4
  "description": "多 IM / 多 Agent 的会话路由与上下文管理(支持 /new)",
5
5
  "type": "module",
6
6
  "exports": {
@@ -47,7 +47,7 @@
47
47
  "dependencies": {
48
48
  "@ffmpeg-installer/ffmpeg": "^1.1.0",
49
49
  "ylib-dingtalk-connector": "0.7.10-beta.20",
50
- "ylib-openclaw-lark": "2026.3.17-beta.24",
50
+ "ylib-openclaw-lark": "2026.3.17-beta.25",
51
51
  "ylib-openclaw-weixin": "2.1.7-beta.12",
52
52
  "axios": "^1.6.0",
53
53
  "dingtalk-stream": "^2.1.4",
@@ -513,6 +513,180 @@ function buildCfg(): {
513
513
  // ---------------------------------------------------------------------------
514
514
 
515
515
  function buildMinimalRuntime(cfg: Record<string, unknown>): unknown {
516
+ type BridgeGroupConfig = {
517
+ requireMention?: boolean;
518
+ };
519
+ type BridgeGroups = Record<string, BridgeGroupConfig | undefined>;
520
+
521
+ const normalizeAccountId = (value: unknown): string => {
522
+ const text = String(value || "").trim();
523
+ return text || "__default__";
524
+ };
525
+
526
+ const resolveAccountEntry = (
527
+ accounts: Record<string, unknown> | undefined,
528
+ accountId: unknown,
529
+ ): Record<string, unknown> | undefined => {
530
+ if (!accounts || typeof accounts !== "object") return undefined;
531
+ const normalized = normalizeAccountId(accountId);
532
+ const exact = accounts[normalized];
533
+ if (exact && typeof exact === "object" && !Array.isArray(exact)) {
534
+ return exact as Record<string, unknown>;
535
+ }
536
+ const fallback = accounts["__default__"];
537
+ if (fallback && typeof fallback === "object" && !Array.isArray(fallback)) {
538
+ return fallback as Record<string, unknown>;
539
+ }
540
+ return undefined;
541
+ };
542
+
543
+ const resolveChannelGroups = (
544
+ inCfg: Record<string, unknown>,
545
+ channel: string,
546
+ accountId?: unknown,
547
+ ): BridgeGroups | undefined => {
548
+ const channelsObj =
549
+ inCfg.channels && typeof inCfg.channels === "object"
550
+ ? (inCfg.channels as Record<string, unknown>)
551
+ : undefined;
552
+ const channelCfg =
553
+ channelsObj && channelsObj[channel] && typeof channelsObj[channel] === "object"
554
+ ? (channelsObj[channel] as Record<string, unknown>)
555
+ : undefined;
556
+ if (!channelCfg) return undefined;
557
+ const accountsObj =
558
+ channelCfg.accounts && typeof channelCfg.accounts === "object"
559
+ ? (channelCfg.accounts as Record<string, unknown>)
560
+ : undefined;
561
+ const accountEntry = resolveAccountEntry(accountsObj, accountId);
562
+ const accountGroups =
563
+ accountEntry && accountEntry.groups && typeof accountEntry.groups === "object"
564
+ ? (accountEntry.groups as BridgeGroups)
565
+ : undefined;
566
+ if (accountGroups) return accountGroups;
567
+ if (channelCfg.groups && typeof channelCfg.groups === "object") {
568
+ return channelCfg.groups as BridgeGroups;
569
+ }
570
+ return undefined;
571
+ };
572
+
573
+ const resolveChannelGroupPolicyMode = (
574
+ inCfg: Record<string, unknown>,
575
+ channel: string,
576
+ accountId?: unknown,
577
+ ): "open" | "allowlist" | "disabled" | undefined => {
578
+ const channelsObj =
579
+ inCfg.channels && typeof inCfg.channels === "object"
580
+ ? (inCfg.channels as Record<string, unknown>)
581
+ : undefined;
582
+ const channelCfg =
583
+ channelsObj && channelsObj[channel] && typeof channelsObj[channel] === "object"
584
+ ? (channelsObj[channel] as Record<string, unknown>)
585
+ : undefined;
586
+ if (!channelCfg) return undefined;
587
+ const accountsObj =
588
+ channelCfg.accounts && typeof channelCfg.accounts === "object"
589
+ ? (channelCfg.accounts as Record<string, unknown>)
590
+ : undefined;
591
+ const accountEntry = resolveAccountEntry(accountsObj, accountId);
592
+ const accountPolicy = String(accountEntry?.groupPolicy || "").trim();
593
+ if (accountPolicy === "open" || accountPolicy === "allowlist" || accountPolicy === "disabled") {
594
+ return accountPolicy;
595
+ }
596
+ const topPolicy = String(channelCfg.groupPolicy || "").trim();
597
+ if (topPolicy === "open" || topPolicy === "allowlist" || topPolicy === "disabled") {
598
+ return topPolicy;
599
+ }
600
+ return undefined;
601
+ };
602
+
603
+ const resolveChannelGroupConfig = (
604
+ groups: BridgeGroups | undefined,
605
+ groupId: string,
606
+ caseInsensitive: boolean,
607
+ ): BridgeGroupConfig | undefined => {
608
+ if (!groups) return undefined;
609
+ const direct = groups[groupId];
610
+ if (direct) return direct;
611
+ if (!caseInsensitive) return undefined;
612
+ const target = groupId.toLowerCase();
613
+ const matchedKey = Object.keys(groups).find(
614
+ (key) => key !== "*" && key.toLowerCase() === target,
615
+ );
616
+ return matchedKey ? groups[matchedKey] : undefined;
617
+ };
618
+
619
+ const resolveBridgeGroupPolicy = (params: {
620
+ cfg: Record<string, unknown>;
621
+ channel: string;
622
+ groupId?: string | null;
623
+ accountId?: string | null;
624
+ groupIdCaseInsensitive?: boolean;
625
+ hasGroupAllowFrom?: boolean;
626
+ }): {
627
+ allowlistEnabled: boolean;
628
+ allowed: boolean;
629
+ groupConfig?: BridgeGroupConfig;
630
+ defaultConfig?: BridgeGroupConfig;
631
+ } => {
632
+ const groups = resolveChannelGroups(params.cfg, params.channel, params.accountId);
633
+ const groupPolicy = resolveChannelGroupPolicyMode(
634
+ params.cfg,
635
+ params.channel,
636
+ params.accountId,
637
+ );
638
+ const hasGroups = Boolean(groups && Object.keys(groups).length > 0);
639
+ const allowlistEnabled = groupPolicy === "allowlist" || hasGroups;
640
+ const normalizedGroupId = String(params.groupId || "").trim();
641
+ const groupConfig = normalizedGroupId
642
+ ? resolveChannelGroupConfig(groups, normalizedGroupId, Boolean(params.groupIdCaseInsensitive))
643
+ : undefined;
644
+ const defaultConfig = groups?.["*"];
645
+ const allowAll = allowlistEnabled && Boolean(groups && Object.hasOwn(groups, "*"));
646
+ const senderFilterBypass =
647
+ groupPolicy === "allowlist" && !hasGroups && Boolean(params.hasGroupAllowFrom);
648
+ const allowed =
649
+ groupPolicy === "disabled"
650
+ ? false
651
+ : !allowlistEnabled || allowAll || Boolean(groupConfig) || senderFilterBypass;
652
+ return {
653
+ allowlistEnabled,
654
+ allowed,
655
+ groupConfig,
656
+ defaultConfig,
657
+ };
658
+ };
659
+
660
+ const resolveBridgeRequireMention = (params: {
661
+ cfg: Record<string, unknown>;
662
+ channel: string;
663
+ groupId?: string | null;
664
+ accountId?: string | null;
665
+ groupIdCaseInsensitive?: boolean;
666
+ requireMentionOverride?: boolean;
667
+ overrideOrder?: "before-config" | "after-config";
668
+ }): boolean => {
669
+ const { requireMentionOverride } = params;
670
+ const overrideOrder = params.overrideOrder || "after-config";
671
+ const { groupConfig, defaultConfig } = resolveBridgeGroupPolicy(params);
672
+ const configMention =
673
+ typeof groupConfig?.requireMention === "boolean"
674
+ ? groupConfig.requireMention
675
+ : typeof defaultConfig?.requireMention === "boolean"
676
+ ? defaultConfig.requireMention
677
+ : undefined;
678
+ if (overrideOrder === "before-config" && typeof requireMentionOverride === "boolean") {
679
+ return requireMentionOverride;
680
+ }
681
+ if (typeof configMention === "boolean") {
682
+ return configMention;
683
+ }
684
+ if (overrideOrder !== "before-config" && typeof requireMentionOverride === "boolean") {
685
+ return requireMentionOverride;
686
+ }
687
+ return true;
688
+ };
689
+
516
690
  return {
517
691
  log: (...args: unknown[]) => console.log("[Feishu]", ...args),
518
692
  error: (...args: unknown[]) => console.error("[Feishu][ERR]", ...args),
@@ -531,6 +705,10 @@ function buildMinimalRuntime(cfg: Record<string, unknown>): unknown {
531
705
  resolveCommandAuthorizedFromAuthorizers: async () => false,
532
706
  isControlCommandMessage: () => false,
533
707
  },
708
+ groups: {
709
+ resolveGroupPolicy: resolveBridgeGroupPolicy,
710
+ resolveRequireMention: resolveBridgeRequireMention,
711
+ },
534
712
  reply: {
535
713
  resolveEnvelopeFormatOptions: () => ({}),
536
714
  finalizeInboundContext: () => ({}),