@soimy/dingtalk 3.5.3 → 3.6.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.
- package/index.ts +7 -0
- package/openclaw.plugin.json +104 -0
- package/package.json +1 -1
- package/src/card/card-markdown-image-reroute.ts +106 -0
- package/src/card/card-run-registry.ts +54 -1
- package/src/card/card-stop-handler.ts +10 -20
- package/src/card/card-template.ts +14 -3
- package/src/card/statusline-renderer.ts +94 -0
- package/src/card-draft-controller.ts +245 -52
- package/src/card-service.ts +368 -8
- package/src/channel.ts +19 -1081
- package/src/config-schema.ts +19 -0
- package/src/config.ts +117 -1
- package/src/device-registration.ts +245 -0
- package/src/gateway/channel-gateway.ts +636 -0
- package/src/inbound-handler.ts +147 -24
- package/src/media-utils.ts +6 -0
- package/src/message-utils.ts +124 -16
- package/src/messaging/btw-deliver.ts +85 -0
- package/src/messaging/channel-actions.ts +173 -0
- package/src/messaging/channel-outbound.ts +158 -0
- package/src/onboarding.ts +321 -232
- package/src/platform/channel-status.ts +81 -0
- package/src/reply-strategy-card.ts +373 -64
- package/src/reply-strategy-markdown.ts +1 -1
- package/src/reply-strategy-types.ts +93 -0
- package/src/reply-strategy-with-reaction.ts +1 -1
- package/src/reply-strategy.ts +14 -72
- package/src/run-usage-store.ts +59 -0
- package/src/send-service.ts +115 -3
- package/src/session-state.ts +62 -0
- package/src/targeting/agent-name-matcher.ts +28 -0
- package/src/types.ts +23 -147
package/src/types.ts
CHANGED
|
@@ -19,7 +19,6 @@ import type {
|
|
|
19
19
|
ChannelLogSink as SDKChannelLogSink,
|
|
20
20
|
} from "openclaw/plugin-sdk/channel-runtime";
|
|
21
21
|
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
|
22
|
-
import { mergeAccountWithDefaults } from "./config";
|
|
23
22
|
|
|
24
23
|
export type AckReactionMode = "off" | "emoji" | "kaomoji";
|
|
25
24
|
// Accept arbitrary strings for backward compatibility; the recommended
|
|
@@ -95,6 +94,15 @@ export interface DingTalkConfig extends OpenClawConfig {
|
|
|
95
94
|
convertMarkdownTables?: boolean;
|
|
96
95
|
/** @mention the sender after card finalization in group chats; value is the message text */
|
|
97
96
|
cardAtSender?: string;
|
|
97
|
+
/** Status line visibility toggles for the AI card footer */
|
|
98
|
+
cardStatusLine?: {
|
|
99
|
+
model?: boolean;
|
|
100
|
+
effort?: boolean;
|
|
101
|
+
agent?: boolean;
|
|
102
|
+
taskTime?: boolean;
|
|
103
|
+
tokens?: boolean;
|
|
104
|
+
dapiUsage?: boolean;
|
|
105
|
+
};
|
|
98
106
|
}
|
|
99
107
|
|
|
100
108
|
/**
|
|
@@ -670,8 +678,11 @@ export interface AICardInstance {
|
|
|
670
678
|
lastUpdated: number;
|
|
671
679
|
state: AICardState; // Current card state: PROCESSING, INPUTING, FINISHED, STOPPED, FAILED
|
|
672
680
|
config?: DingTalkConfig; // Store config reference for token refresh
|
|
673
|
-
lastStreamedContent?: string;
|
|
681
|
+
lastStreamedContent?: string; // Latest copy/content text shown to user
|
|
682
|
+
lastBlockListJson?: string; // Latest rendered CardBlock[] JSON for V2 instances API
|
|
674
683
|
outTrackId?: string;
|
|
684
|
+
/** Cumulative DingTalk API call count for this card instance. */
|
|
685
|
+
dapiUsage?: number;
|
|
675
686
|
}
|
|
676
687
|
|
|
677
688
|
/**
|
|
@@ -731,150 +742,15 @@ export interface ConnectionAttemptResult {
|
|
|
731
742
|
error?: Error;
|
|
732
743
|
nextDelay?: number;
|
|
733
744
|
}
|
|
734
|
-
|
|
735
|
-
// ============ Onboarding Helper Functions ============
|
|
736
|
-
|
|
737
|
-
const DEFAULT_ACCOUNT_ID = "default";
|
|
738
|
-
|
|
739
|
-
function stripRemovedLegacyFieldsFromPublicAccount(
|
|
740
|
-
config: DingTalkConfig,
|
|
741
|
-
): DingTalkConfig {
|
|
742
|
-
const {
|
|
743
|
-
cardStreamReasoning: _cardStreamReasoning,
|
|
744
|
-
verboseRealtimeStream: _verboseRealtimeStream,
|
|
745
|
-
accounts,
|
|
746
|
-
...rest
|
|
747
|
-
} = config as DingTalkConfig & {
|
|
748
|
-
cardStreamReasoning?: unknown;
|
|
749
|
-
verboseRealtimeStream?: unknown;
|
|
750
|
-
accounts?: Record<string, DingTalkConfig | undefined>;
|
|
751
|
-
};
|
|
752
|
-
const sanitizedAccounts = accounts
|
|
753
|
-
? Object.fromEntries(
|
|
754
|
-
Object.entries(accounts).map(([accountId, accountConfig]) => [
|
|
755
|
-
accountId,
|
|
756
|
-
accountConfig ? stripRemovedLegacyFieldsFromPublicAccount(accountConfig) : accountConfig,
|
|
757
|
-
]),
|
|
758
|
-
)
|
|
759
|
-
: undefined;
|
|
760
|
-
if (sanitizedAccounts) {
|
|
761
|
-
return { ...rest, accounts: sanitizedAccounts } as DingTalkConfig;
|
|
762
|
-
}
|
|
763
|
-
return rest as DingTalkConfig;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
745
|
/**
|
|
767
|
-
*
|
|
746
|
+
* CardBlock types for AI Card v2 blockList.
|
|
747
|
+
* - 0 = answer (markdown text)
|
|
748
|
+
* - 1 = thinking process
|
|
749
|
+
* - 2 = tool result
|
|
750
|
+
* - 3 = image (uploaded mediaId)
|
|
768
751
|
*/
|
|
769
|
-
export
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
const accountIds: string[] = [];
|
|
776
|
-
|
|
777
|
-
// Check for direct configuration (default account)
|
|
778
|
-
if (dingtalk.clientId || dingtalk.clientSecret) {
|
|
779
|
-
accountIds.push(DEFAULT_ACCOUNT_ID);
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
// Check accounts object
|
|
783
|
-
if (dingtalk.accounts) {
|
|
784
|
-
accountIds.push(...Object.keys(dingtalk.accounts));
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
return accountIds;
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
/**
|
|
791
|
-
* Resolved DingTalk account with configuration status
|
|
792
|
-
*/
|
|
793
|
-
export interface ResolvedDingTalkAccount extends DingTalkConfig {
|
|
794
|
-
accountId: string;
|
|
795
|
-
configured: boolean;
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
/**
|
|
799
|
-
* Resolve a specific DingTalk account configuration
|
|
800
|
-
*/
|
|
801
|
-
export function resolveDingTalkAccount(
|
|
802
|
-
cfg: OpenClawConfig,
|
|
803
|
-
accountId?: string | null,
|
|
804
|
-
): ResolvedDingTalkAccount {
|
|
805
|
-
const id = accountId || DEFAULT_ACCOUNT_ID;
|
|
806
|
-
const dingtalk = cfg.channels?.dingtalk as DingTalkChannelConfig | undefined;
|
|
807
|
-
|
|
808
|
-
// If default account, return top-level config
|
|
809
|
-
if (id === DEFAULT_ACCOUNT_ID) {
|
|
810
|
-
const rawConfig: DingTalkConfig = {
|
|
811
|
-
clientId: dingtalk?.clientId ?? "",
|
|
812
|
-
clientSecret: dingtalk?.clientSecret ?? "",
|
|
813
|
-
name: dingtalk?.name,
|
|
814
|
-
enabled: dingtalk?.enabled,
|
|
815
|
-
dmPolicy: dingtalk?.dmPolicy,
|
|
816
|
-
groupPolicy: dingtalk?.groupPolicy,
|
|
817
|
-
allowFrom: dingtalk?.allowFrom,
|
|
818
|
-
groupAllowFrom: dingtalk?.groupAllowFrom,
|
|
819
|
-
displayNameResolution: dingtalk?.displayNameResolution,
|
|
820
|
-
contextVisibility: dingtalk?.contextVisibility,
|
|
821
|
-
journalTTLDays: dingtalk?.journalTTLDays,
|
|
822
|
-
ackReaction: dingtalk?.ackReaction,
|
|
823
|
-
debug: dingtalk?.debug,
|
|
824
|
-
messageType: dingtalk?.messageType,
|
|
825
|
-
cardTemplateId: dingtalk?.cardTemplateId,
|
|
826
|
-
cardTemplateKey: dingtalk?.cardTemplateKey,
|
|
827
|
-
groups: dingtalk?.groups,
|
|
828
|
-
accounts: dingtalk?.accounts,
|
|
829
|
-
maxConnectionAttempts: dingtalk?.maxConnectionAttempts,
|
|
830
|
-
initialReconnectDelay: dingtalk?.initialReconnectDelay,
|
|
831
|
-
maxReconnectDelay: dingtalk?.maxReconnectDelay,
|
|
832
|
-
reconnectJitter: dingtalk?.reconnectJitter,
|
|
833
|
-
maxReconnectCycles: dingtalk?.maxReconnectCycles,
|
|
834
|
-
reconnectDeadlineMs: dingtalk?.reconnectDeadlineMs,
|
|
835
|
-
useConnectionManager: dingtalk?.useConnectionManager,
|
|
836
|
-
mediaMaxMb: dingtalk?.mediaMaxMb,
|
|
837
|
-
keepAlive: dingtalk?.keepAlive,
|
|
838
|
-
bypassProxyForSend: dingtalk?.bypassProxyForSend,
|
|
839
|
-
proactivePermissionHint: dingtalk?.proactivePermissionHint,
|
|
840
|
-
cardStreamingMode: dingtalk?.cardStreamingMode,
|
|
841
|
-
cardRealTimeStream: dingtalk?.cardRealTimeStream,
|
|
842
|
-
cardStreamInterval: dingtalk?.cardStreamInterval,
|
|
843
|
-
aicardDegradeMs: dingtalk?.aicardDegradeMs,
|
|
844
|
-
learningEnabled: dingtalk?.learningEnabled,
|
|
845
|
-
learningAutoApply: dingtalk?.learningAutoApply,
|
|
846
|
-
learningNoteTtlMs: dingtalk?.learningNoteTtlMs,
|
|
847
|
-
convertMarkdownTables: dingtalk?.convertMarkdownTables,
|
|
848
|
-
cardAtSender: dingtalk?.cardAtSender,
|
|
849
|
-
};
|
|
850
|
-
const config = stripRemovedLegacyFieldsFromPublicAccount(rawConfig);
|
|
851
|
-
return {
|
|
852
|
-
...config,
|
|
853
|
-
accountId: id,
|
|
854
|
-
configured: Boolean(config.clientId && config.clientSecret),
|
|
855
|
-
};
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
// If named account, merge channel-level defaults with account-level overrides
|
|
859
|
-
const accountConfig = dingtalk?.accounts?.[id];
|
|
860
|
-
if (accountConfig) {
|
|
861
|
-
const merged = mergeAccountWithDefaults(
|
|
862
|
-
dingtalk as DingTalkConfig,
|
|
863
|
-
accountConfig,
|
|
864
|
-
);
|
|
865
|
-
const publicMerged = stripRemovedLegacyFieldsFromPublicAccount(merged);
|
|
866
|
-
return {
|
|
867
|
-
...publicMerged,
|
|
868
|
-
accountId: id,
|
|
869
|
-
configured: Boolean(merged.clientId && merged.clientSecret),
|
|
870
|
-
};
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
// Account doesn't exist, return empty config
|
|
874
|
-
return {
|
|
875
|
-
clientId: "",
|
|
876
|
-
clientSecret: "",
|
|
877
|
-
accountId: id,
|
|
878
|
-
configured: false,
|
|
879
|
-
};
|
|
880
|
-
}
|
|
752
|
+
export type CardBlock =
|
|
753
|
+
| { type: 0; markdown: string }
|
|
754
|
+
| { type: 1; markdown: string }
|
|
755
|
+
| { type: 2; markdown: string }
|
|
756
|
+
| { type: 3; mediaId: string; text?: string };
|