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 +2 -2
- package/scripts/lark-stdio-bridge.ts +178 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ylib-syim",
|
|
3
|
-
"version": "0.0.
|
|
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.
|
|
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: () => ({}),
|