@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.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11684 -10583
- package/dist/src/{ack-reaction-service.d.ts → ack-reaction/ack-reaction-service.d.ts} +1 -1
- package/dist/src/ack-reaction/dynamic-ack-reaction-controller.d.ts +3 -3
- package/dist/src/card/ask-user-question-context.d.ts +1 -1
- package/dist/src/card/ask-user-question-store.d.ts +1 -1
- package/dist/src/card/ask-user-question.d.ts +1 -1
- package/dist/src/card/card-action-handler.d.ts +2 -2
- package/dist/src/{card-draft-controller.d.ts → card/card-draft-controller.d.ts} +5 -1
- package/dist/src/card/card-run-registry.d.ts +2 -2
- package/dist/src/{card-service.d.ts → card/card-service.d.ts} +1 -1
- package/dist/src/card/card-stop-handler.d.ts +1 -1
- package/dist/src/card/card-streaming-mode.d.ts +1 -1
- package/dist/src/card/card-task-progress.d.ts +60 -0
- package/dist/src/channel.d.ts +6 -6
- package/dist/src/command/card-stop-command.d.ts +1 -1
- package/dist/src/{feedback-learning-service.d.ts → command/feedback-learning-service.d.ts} +1 -1
- package/dist/src/command/inbound-command-dispatch-service.d.ts +2 -2
- package/dist/src/{learning-command-service.d.ts → command/learning-command-service.d.ts} +1 -1
- package/dist/src/gateway/channel-gateway.d.ts +1 -1
- package/dist/src/{connection-manager.d.ts → gateway/connection-manager.d.ts} +1 -1
- package/dist/src/{docs-service.d.ts → gateway/docs-service.d.ts} +1 -1
- package/dist/src/{inbound-handler.d.ts → gateway/inbound-handler.d.ts} +1 -1
- package/dist/src/gateway/inbound-session-queue-dispatcher.d.ts +1 -1
- package/dist/src/messaging/attachment-text-extractor.d.ts +1 -1
- package/dist/src/messaging/btw-deliver.d.ts +1 -1
- package/dist/src/messaging/channel-outbound.d.ts +1 -1
- package/dist/src/{media-utils.d.ts → messaging/media-utils.d.ts} +1 -1
- package/dist/src/{message-context-store.d.ts → messaging/message-context-store.d.ts} +7 -1
- package/dist/src/{message-utils.d.ts → messaging/message-utils.d.ts} +1 -1
- package/dist/src/messaging/quoted-context.d.ts +2 -2
- package/dist/src/messaging/quoted-file-service.d.ts +1 -1
- package/dist/src/messaging/quoted-ref.d.ts +2 -2
- package/dist/src/{reply-strategy-card.d.ts → messaging/reply-strategy-card.d.ts} +1 -1
- package/dist/src/{reply-strategy-types.d.ts → messaging/reply-strategy-types.d.ts} +10 -1
- package/dist/src/{reply-strategy-with-reaction.d.ts → messaging/reply-strategy-with-reaction.d.ts} +1 -1
- package/dist/src/{reply-strategy.d.ts → messaging/reply-strategy.d.ts} +1 -1
- package/dist/src/{send-service.d.ts → messaging/send-service.d.ts} +1 -1
- package/dist/src/platform/channel-status.d.ts +1 -1
- package/dist/src/platform/config.d.ts +110 -0
- package/dist/src/platform/runtime-events.d.ts +67 -0
- package/dist/src/{types.d.ts → platform/types.d.ts} +74 -1
- package/dist/src/{persistence-store.d.ts → shared/persistence-store.d.ts} +1 -1
- package/dist/src/{utils.d.ts → shared/utils.d.ts} +1 -1
- package/dist/src/targeting/agent-name-matcher.d.ts +1 -1
- package/dist/src/targeting/agent-routing.d.ts +3 -3
- package/dist/src/{session-routing.d.ts → targeting/session-routing.d.ts} +1 -1
- package/index.ts +193 -69
- package/openclaw.plugin.json +158 -2
- package/package.json +16 -16
- package/src/{ack-reaction-classifier.ts → ack-reaction/ack-reaction-classifier.ts} +85 -13
- package/src/{ack-reaction-service.ts → ack-reaction/ack-reaction-service.ts} +13 -7
- package/src/ack-reaction/dynamic-ack-reaction-controller.ts +46 -31
- package/src/ack-reaction/dynamic-ack-reaction-progress.ts +4 -1
- package/src/card/ask-user-question-context.ts +1 -1
- package/src/card/ask-user-question-store.ts +2 -2
- package/src/card/ask-user-question.ts +11 -7
- package/src/card/card-action-handler.ts +2 -2
- package/src/{card-callback-service.ts → card/card-callback-service.ts} +7 -9
- package/src/card/card-draft-controller.ts +770 -0
- package/src/card/card-markdown-image-reroute.ts +8 -2
- package/src/card/card-run-registry.ts +17 -7
- package/src/{card-service.ts → card/card-service.ts} +91 -61
- package/src/card/card-stop-handler.ts +12 -8
- package/src/card/card-streaming-mode.ts +1 -1
- package/src/card/card-task-progress.ts +330 -0
- package/src/card/draft-stream-loop.ts +119 -0
- package/src/card/reasoning-answer-split.ts +125 -121
- package/src/card/reasoning-block-assembler.ts +122 -123
- package/src/{run-usage-store.ts → card/run-usage-store.ts} +18 -6
- package/src/card/statusline-renderer.ts +14 -5
- package/src/card/task-model-metadata.ts +8 -3
- package/src/channel.ts +14 -16
- package/src/command/card-stop-command.ts +2 -2
- package/src/{feedback-learning-service.ts → command/feedback-learning-service.ts} +36 -16
- package/src/{feedback-learning-store.ts → command/feedback-learning-store.ts} +133 -81
- package/src/command/inbound-command-dispatch-service.ts +12 -6
- package/src/{learning-command-service.ts → command/learning-command-service.ts} +36 -29
- package/src/{session-command-service.ts → command/session-command-service.ts} +3 -1
- package/src/gateway/channel-gateway.ts +106 -28
- package/src/{connection-manager.ts → gateway/connection-manager.ts} +45 -30
- package/src/{docs-service.ts → gateway/docs-service.ts} +5 -5
- package/src/{inbound-handler.ts → gateway/inbound-handler.ts} +139 -84
- package/src/gateway/inbound-session-queue-dispatcher.ts +18 -14
- package/src/{session-lock.ts → gateway/session-lock.ts} +14 -14
- package/src/messaging/attachment-text-extractor.ts +21 -7
- package/src/messaging/btw-deliver.ts +2 -2
- package/src/messaging/channel-actions.ts +15 -7
- package/src/messaging/channel-outbound.ts +16 -11
- package/src/{media-utils.ts → messaging/media-utils.ts} +276 -72
- package/src/{message-context-store.ts → messaging/message-context-store.ts} +11 -2
- package/src/{message-utils.ts → messaging/message-utils.ts} +46 -11
- package/src/messaging/quoted-context.ts +2 -2
- package/src/messaging/quoted-file-service.ts +311 -294
- package/src/messaging/quoted-ref.ts +11 -7
- package/src/{reply-strategy-card.ts → messaging/reply-strategy-card.ts} +178 -101
- package/src/{reply-strategy-markdown.ts → messaging/reply-strategy-markdown.ts} +8 -2
- package/src/{reply-strategy-types.ts → messaging/reply-strategy-types.ts} +11 -1
- package/src/{reply-strategy-with-reaction.ts → messaging/reply-strategy-with-reaction.ts} +6 -1
- package/src/{reply-strategy.ts → messaging/reply-strategy.ts} +2 -2
- package/src/{send-service.ts → messaging/send-service.ts} +100 -65
- package/src/{auth.ts → platform/auth.ts} +2 -2
- package/src/platform/channel-status.ts +3 -3
- package/src/{config-schema.ts → platform/config-schema.ts} +81 -4
- package/src/{config.ts → platform/config.ts} +167 -19
- package/src/{device-registration.ts → platform/device-registration.ts} +5 -4
- package/src/{onboarding.ts → platform/onboarding.ts} +1 -4
- package/src/{plugin-sdk-channel-actions-augment.ts → platform/plugin-sdk-channel-actions-augment.ts} +6 -5
- package/src/platform/runtime-events.ts +202 -0
- package/src/{secret-input.ts → platform/secret-input.ts} +117 -11
- package/src/{types.ts → platform/types.ts} +76 -1
- package/src/{http-client.ts → shared/http-client.ts} +1 -3
- package/src/{persistence-store.ts → shared/persistence-store.ts} +6 -6
- package/src/{utils.ts → shared/utils.ts} +30 -13
- package/src/targeting/agent-name-matcher.ts +1 -1
- package/src/targeting/agent-routing.ts +7 -7
- package/src/targeting/group-members-store.ts +1 -1
- package/src/{session-peer-store.ts → targeting/session-peer-store.ts} +9 -4
- package/src/{session-routing.ts → targeting/session-routing.ts} +1 -1
- package/src/targeting/target-directory-adapter.ts +3 -3
- package/src/targeting/target-directory-store.ts +1 -1
- package/src/targeting/target-input.ts +1 -1
- package/dist/src/ack-reaction/dynamic-ack-reaction-events.d.ts +0 -35
- package/dist/src/config.d.ts +0 -59
- package/src/ack-reaction/dynamic-ack-reaction-events.ts +0 -123
- package/src/card-draft-controller.ts +0 -637
- package/src/draft-stream-loop.ts +0 -119
- /package/dist/src/{ack-reaction-classifier.d.ts → ack-reaction/ack-reaction-classifier.d.ts} +0 -0
- /package/dist/src/{card-callback-service.d.ts → card/card-callback-service.d.ts} +0 -0
- /package/dist/src/{draft-stream-loop.d.ts → card/draft-stream-loop.d.ts} +0 -0
- /package/dist/src/{run-usage-store.d.ts → card/run-usage-store.d.ts} +0 -0
- /package/dist/src/{feedback-learning-store.d.ts → command/feedback-learning-store.d.ts} +0 -0
- /package/dist/src/{session-command-service.d.ts → command/session-command-service.d.ts} +0 -0
- /package/dist/src/{session-lock.d.ts → gateway/session-lock.d.ts} +0 -0
- /package/dist/src/{proactive-risk-registry.d.ts → messaging/proactive-risk-registry.d.ts} +0 -0
- /package/dist/src/{reply-strategy-markdown.d.ts → messaging/reply-strategy-markdown.d.ts} +0 -0
- /package/dist/src/{access-control.d.ts → platform/access-control.d.ts} +0 -0
- /package/dist/src/{auth.d.ts → platform/auth.d.ts} +0 -0
- /package/dist/src/{config-schema.d.ts → platform/config-schema.d.ts} +0 -0
- /package/dist/src/{device-registration.d.ts → platform/device-registration.d.ts} +0 -0
- /package/dist/src/{logger-context.d.ts → platform/logger-context.d.ts} +0 -0
- /package/dist/src/{onboarding.d.ts → platform/onboarding.d.ts} +0 -0
- /package/dist/src/{plugin-sdk-channel-actions-augment.d.ts → platform/plugin-sdk-channel-actions-augment.d.ts} +0 -0
- /package/dist/src/{runtime.d.ts → platform/runtime.d.ts} +0 -0
- /package/dist/src/{secret-input.d.ts → platform/secret-input.d.ts} +0 -0
- /package/dist/src/{session-state.d.ts → platform/session-state.d.ts} +0 -0
- /package/dist/src/{signature.d.ts → platform/signature.d.ts} +0 -0
- /package/dist/src/{dedup.d.ts → shared/dedup.d.ts} +0 -0
- /package/dist/src/{http-client.d.ts → shared/http-client.d.ts} +0 -0
- /package/dist/src/{path-utils.d.ts → shared/path-utils.d.ts} +0 -0
- /package/dist/src/{peer-id-registry.d.ts → targeting/peer-id-registry.d.ts} +0 -0
- /package/dist/src/{session-peer-store.d.ts → targeting/session-peer-store.d.ts} +0 -0
- /package/src/{proactive-risk-registry.ts → messaging/proactive-risk-registry.ts} +0 -0
- /package/src/{access-control.ts → platform/access-control.ts} +0 -0
- /package/src/{logger-context.ts → platform/logger-context.ts} +0 -0
- /package/src/{runtime.ts → platform/runtime.ts} +0 -0
- /package/src/{session-state.ts → platform/session-state.ts} +0 -0
- /package/src/{signature.ts → platform/signature.ts} +0 -0
- /package/src/{dedup.ts → shared/dedup.ts} +0 -0
- /package/src/{path-utils.ts → shared/path-utils.ts} +0 -0
- /package/src/{peer-id-registry.ts → targeting/peer-id-registry.ts} +0 -0
|
@@ -23,8 +23,34 @@ export type AckReactionMode = "off" | "emoji" | "kaomoji";
|
|
|
23
23
|
// explicit modes remain: "off" | "emoji" | "kaomoji".
|
|
24
24
|
export type AckReactionConfigValue = string;
|
|
25
25
|
export type CardStreamingMode = "off" | "answer" | "all";
|
|
26
|
+
/** How tool-driven task-progress changes reach the card:
|
|
27
|
+
* - `heartbeat` (default): coalesced into the 30s progress heartbeat
|
|
28
|
+
* - `interval`: pushed on every correlated tool event, throttled by `cardStreamInterval` */
|
|
29
|
+
export type CardTaskProgressRefresh = "heartbeat" | "interval";
|
|
26
30
|
export type ContextVisibilityMode = "all" | "allowlist" | "allowlist_quote";
|
|
27
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Gateway RPC capability configuration (Issue #608, 问题 3).
|
|
34
|
+
* Aligns with the official connector's `tools: { docs, media }` gate shape.
|
|
35
|
+
* All capabilities default to enabled for backward compatibility.
|
|
36
|
+
*/
|
|
37
|
+
export interface DingTalkGatewayCapabilitiesConfig {
|
|
38
|
+
tools?: {
|
|
39
|
+
/** Enable `dingtalk.docs.*` and `dingtalk-connector.docs.*` Gateway RPCs (default: true) */
|
|
40
|
+
docs?: boolean;
|
|
41
|
+
/** Enable proactive-send Gateway RPCs: `dingtalk-connector.sendToUser/sendToGroup/send` (default: true) */
|
|
42
|
+
proactiveSend?: boolean;
|
|
43
|
+
};
|
|
44
|
+
/** Optional doc-space allowlist; when set, docs RPCs only accept these `spaceId` values */
|
|
45
|
+
docs?: {
|
|
46
|
+
allowedSpaceIds?: string[];
|
|
47
|
+
};
|
|
48
|
+
/** Optional proactive-send target allowlist; entries must be `user:*` or `group:*` */
|
|
49
|
+
send?: {
|
|
50
|
+
allowedTargets?: string[];
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
28
54
|
/**
|
|
29
55
|
* DingTalk channel configuration (extends base OpenClaw config)
|
|
30
56
|
*/
|
|
@@ -79,10 +105,23 @@ export interface DingTalkConfig extends OpenClawConfig {
|
|
|
79
105
|
* - answer: stream answer text
|
|
80
106
|
* - all: stream answer + reasoning text */
|
|
81
107
|
cardStreamingMode?: CardStreamingMode;
|
|
108
|
+
/** Internal derived flag, not a user-facing config key: whether
|
|
109
|
+
* `cardStreamingMode` came from an explicit user setting instead of the
|
|
110
|
+
* runtime default. Written by config normalization only. */
|
|
111
|
+
cardStreamingModeConfigured?: boolean;
|
|
82
112
|
/** @deprecated Use `cardStreamingMode` instead. */
|
|
83
113
|
cardRealTimeStream?: boolean;
|
|
84
114
|
/** Throttle interval in ms for card stream updates (default 1000) */
|
|
85
115
|
cardStreamInterval?: number;
|
|
116
|
+
/** Live "task in progress" block on AI cards for long-running tasks.
|
|
117
|
+
* `true` forces it on, `false` forces it off; when unset it is on unless
|
|
118
|
+
* `cardStreamingMode` is explicitly `"off"`. */
|
|
119
|
+
cardTaskProgress?: boolean;
|
|
120
|
+
/** How stage/step changes reach the progress block. `heartbeat` (default)
|
|
121
|
+
* keeps the documented "once on appearance, then once per 30s" budget;
|
|
122
|
+
* `interval` pushes on every correlated tool event, throttled by
|
|
123
|
+
* `cardStreamInterval`, trading card updates for a fresher stage label. */
|
|
124
|
+
cardTaskProgressRefresh?: CardTaskProgressRefresh;
|
|
86
125
|
/** AICard degrade duration in milliseconds after trigger errors (default 30m) */
|
|
87
126
|
aicardDegradeMs?: number;
|
|
88
127
|
/** Enable local learning loop (events/reflections/session notes/global rules) */
|
|
@@ -104,6 +143,8 @@ export interface DingTalkConfig extends OpenClawConfig {
|
|
|
104
143
|
tokens?: boolean;
|
|
105
144
|
dapiUsage?: boolean;
|
|
106
145
|
};
|
|
146
|
+
/** Gateway RPC capability gates and allowlists (docs RPCs + proactive-send RPCs). Named `gatewayCapabilities` because host `OpenClawConfig` already owns `gateway` and `tools`, and a bare `capabilities` key would collide with this plugin's channel capabilities metadata. */
|
|
147
|
+
gatewayCapabilities?: DingTalkGatewayCapabilitiesConfig;
|
|
107
148
|
}
|
|
108
149
|
|
|
109
150
|
/**
|
|
@@ -159,10 +200,23 @@ export interface DingTalkChannelConfig {
|
|
|
159
200
|
* - answer: stream answer text
|
|
160
201
|
* - all: stream answer + reasoning text */
|
|
161
202
|
cardStreamingMode?: CardStreamingMode;
|
|
203
|
+
/** Internal derived flag, not a user-facing config key: whether
|
|
204
|
+
* `cardStreamingMode` came from an explicit user setting instead of the
|
|
205
|
+
* runtime default. Written by config normalization only. */
|
|
206
|
+
cardStreamingModeConfigured?: boolean;
|
|
162
207
|
/** @deprecated Use `cardStreamingMode` instead. */
|
|
163
208
|
cardRealTimeStream?: boolean;
|
|
164
209
|
/** Throttle interval in ms for card stream updates (default 1000) */
|
|
165
210
|
cardStreamInterval?: number;
|
|
211
|
+
/** Live "task in progress" block on AI cards for long-running tasks.
|
|
212
|
+
* `true` forces it on, `false` forces it off; when unset it is on unless
|
|
213
|
+
* `cardStreamingMode` is explicitly `"off"`. */
|
|
214
|
+
cardTaskProgress?: boolean;
|
|
215
|
+
/** How stage/step changes reach the progress block. `heartbeat` (default)
|
|
216
|
+
* keeps the documented "once on appearance, then once per 30s" budget;
|
|
217
|
+
* `interval` pushes on every correlated tool event, throttled by
|
|
218
|
+
* `cardStreamInterval`, trading card updates for a fresher stage label. */
|
|
219
|
+
cardTaskProgressRefresh?: CardTaskProgressRefresh;
|
|
166
220
|
/** AICard degrade duration in milliseconds after trigger errors (default 30m) */
|
|
167
221
|
aicardDegradeMs?: number;
|
|
168
222
|
/** Enable local learning loop (events/reflections/session notes/global rules) */
|
|
@@ -175,6 +229,8 @@ export interface DingTalkChannelConfig {
|
|
|
175
229
|
convertMarkdownTables?: boolean;
|
|
176
230
|
/** @mention the sender after card finalization in group chats; value is the message text */
|
|
177
231
|
cardAtSender?: string;
|
|
232
|
+
/** Gateway RPC capability gates and allowlists (docs RPCs + proactive-send RPCs). Named `gatewayCapabilities` because host `OpenClawConfig` already owns `gateway` and `tools`, and a bare `capabilities` key would collide with this plugin's channel capabilities metadata. */
|
|
233
|
+
gatewayCapabilities?: DingTalkGatewayCapabilitiesConfig;
|
|
178
234
|
}
|
|
179
235
|
|
|
180
236
|
/**
|
|
@@ -227,6 +283,17 @@ export interface DocInfo {
|
|
|
227
283
|
updatedAt?: number | string;
|
|
228
284
|
}
|
|
229
285
|
|
|
286
|
+
/**
|
|
287
|
+
* Recursive element node of an interactiveCard `cardContent` payload.
|
|
288
|
+
* Real DingTalk quote callbacks carry card text as nested element trees
|
|
289
|
+
* (e.g. LIST -> RICHTEXT -> TEXT nodes) rather than a flat `text` field.
|
|
290
|
+
*/
|
|
291
|
+
export interface DingTalkCardContentNode {
|
|
292
|
+
elementType?: string;
|
|
293
|
+
value?: string;
|
|
294
|
+
children?: DingTalkCardContentNode[];
|
|
295
|
+
}
|
|
296
|
+
|
|
230
297
|
/**
|
|
231
298
|
* DingTalk incoming message (Stream mode)
|
|
232
299
|
*/
|
|
@@ -252,9 +319,13 @@ export interface DingTalkInboundMessage {
|
|
|
252
319
|
createdAt?: number;
|
|
253
320
|
content?: {
|
|
254
321
|
text?: string;
|
|
322
|
+
/** Quoted text message body in real payloads (`msgType: "text"`). */
|
|
323
|
+
content?: string;
|
|
255
324
|
downloadCode?: string;
|
|
256
325
|
fileName?: string;
|
|
257
326
|
biz_custom_action_url?: string;
|
|
327
|
+
/** interactiveCard quoted content as nested element tree. */
|
|
328
|
+
cardContent?: DingTalkCardContentNode[];
|
|
258
329
|
richText?: Array<{
|
|
259
330
|
msgType?: string;
|
|
260
331
|
type?: string;
|
|
@@ -415,7 +486,11 @@ export interface SendMessageOptions {
|
|
|
415
486
|
/** Force markdown/text delivery even when messageType is "card". Bypasses card
|
|
416
487
|
* creation while preserving journal writes and other side-effects. */
|
|
417
488
|
forceMarkdown?: boolean;
|
|
418
|
-
/**
|
|
489
|
+
/**
|
|
490
|
+
* Host-provided allowlist of local media roots. When set, caller-supplied
|
|
491
|
+
* host paths whose canonical location is outside these roots are resolved
|
|
492
|
+
* through the runtime media bridge instead of being read directly.
|
|
493
|
+
*/
|
|
419
494
|
mediaLocalRoots?: string[];
|
|
420
495
|
}
|
|
421
496
|
|
|
@@ -10,9 +10,7 @@ type AxiosInstanceWithGuards = AxiosInstance & {
|
|
|
10
10
|
// Centralize repo-level axios policy without mutating the global axios singleton
|
|
11
11
|
// that third-party dependencies may also share.
|
|
12
12
|
const httpClient = (
|
|
13
|
-
typeof axios?.create === "function"
|
|
14
|
-
? axios.create({ timeout: DEFAULT_HTTP_TIMEOUT_MS })
|
|
15
|
-
: axios
|
|
13
|
+
typeof axios?.create === "function" ? axios.create({ timeout: DEFAULT_HTTP_TIMEOUT_MS }) : axios
|
|
16
14
|
) as AxiosInstanceWithGuards;
|
|
17
15
|
|
|
18
16
|
httpClient.isAxiosError = axios.isAxiosError;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import type { Logger } from "
|
|
3
|
+
import type { Logger } from "../platform/types";
|
|
4
4
|
|
|
5
5
|
type NamespaceFormat = "json";
|
|
6
6
|
|
|
@@ -71,7 +71,10 @@ function buildScopeSuffix(scope?: PersistenceScope): string {
|
|
|
71
71
|
return `.${segments.join(".")}`;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
export function resolveNamespacePath(
|
|
74
|
+
export function resolveNamespacePath(
|
|
75
|
+
namespace: string,
|
|
76
|
+
options: ResolveNamespacePathOptions,
|
|
77
|
+
): string {
|
|
75
78
|
const format = options.format || "json";
|
|
76
79
|
const baseDir = path.join(path.dirname(options.storePath), NAMESPACE_ROOT_DIR);
|
|
77
80
|
const safeNamespace = sanitizeSegment(namespace.trim());
|
|
@@ -79,10 +82,7 @@ export function resolveNamespacePath(namespace: string, options: ResolveNamespac
|
|
|
79
82
|
return path.join(baseDir, `${safeNamespace}${suffix}.${format}`);
|
|
80
83
|
}
|
|
81
84
|
|
|
82
|
-
export function readNamespaceJson<T>(
|
|
83
|
-
namespace: string,
|
|
84
|
-
options: ReadNamespaceJsonOptions<T>,
|
|
85
|
-
): T {
|
|
85
|
+
export function readNamespaceJson<T>(namespace: string, options: ReadNamespaceJsonOptions<T>): T {
|
|
86
86
|
const filePath = resolveNamespacePath(namespace, options);
|
|
87
87
|
try {
|
|
88
88
|
if (!fs.existsSync(filePath)) {
|
|
@@ -3,7 +3,7 @@ import * as fs from "node:fs";
|
|
|
3
3
|
import * as net from "node:net";
|
|
4
4
|
import * as os from "node:os";
|
|
5
5
|
import * as path from "node:path";
|
|
6
|
-
import type { Logger, RetryOptions } from "
|
|
6
|
+
import type { Logger, RetryOptions } from "../platform/types";
|
|
7
7
|
|
|
8
8
|
type PluginDebugLogParams = {
|
|
9
9
|
accountId: string;
|
|
@@ -44,7 +44,11 @@ function formatPluginDebugDate(date: Date): string {
|
|
|
44
44
|
return `${date.getFullYear()}-${padNumber(date.getMonth() + 1)}-${padNumber(date.getDate())}`;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
function resolvePluginDebugLogFilePath(params: {
|
|
47
|
+
function resolvePluginDebugLogFilePath(params: {
|
|
48
|
+
storePath: string;
|
|
49
|
+
accountId: string;
|
|
50
|
+
date: Date;
|
|
51
|
+
}): string {
|
|
48
52
|
return path.join(
|
|
49
53
|
path.dirname(params.storePath),
|
|
50
54
|
"logs",
|
|
@@ -58,7 +62,11 @@ function formatPluginDebugLine(params: { accountId: string; date: Date; message:
|
|
|
58
62
|
return `[${formatPluginDebugTimestamp(params.date)}] [debug] [dingtalk] [account:${params.accountId}] ${params.message}`;
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
function buildPluginDebugWriterKey(params: {
|
|
65
|
+
function buildPluginDebugWriterKey(params: {
|
|
66
|
+
storePath: string;
|
|
67
|
+
accountId: string;
|
|
68
|
+
date: Date;
|
|
69
|
+
}): string {
|
|
62
70
|
return JSON.stringify([params.storePath, params.accountId, formatPluginDebugDate(params.date)]);
|
|
63
71
|
}
|
|
64
72
|
|
|
@@ -209,11 +217,7 @@ export function stringifyUnknown(value: unknown): string {
|
|
|
209
217
|
if (typeof value === "string") {
|
|
210
218
|
return value;
|
|
211
219
|
}
|
|
212
|
-
if (
|
|
213
|
-
typeof value === "number" ||
|
|
214
|
-
typeof value === "boolean" ||
|
|
215
|
-
typeof value === "bigint"
|
|
216
|
-
) {
|
|
220
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
217
221
|
return String(value);
|
|
218
222
|
}
|
|
219
223
|
try {
|
|
@@ -292,7 +296,11 @@ export function formatDingTalkErrorPayload(payload: unknown): string {
|
|
|
292
296
|
} catch {
|
|
293
297
|
if (typeof payload === "string") {
|
|
294
298
|
serialized = payload;
|
|
295
|
-
} else if (
|
|
299
|
+
} else if (
|
|
300
|
+
typeof payload === "number" ||
|
|
301
|
+
typeof payload === "boolean" ||
|
|
302
|
+
typeof payload === "bigint"
|
|
303
|
+
) {
|
|
296
304
|
serialized = `${payload}`;
|
|
297
305
|
} else {
|
|
298
306
|
serialized = "[unserializable-payload]";
|
|
@@ -318,7 +326,9 @@ export function formatDingTalkErrorPayloadLog(
|
|
|
318
326
|
return `${prefix}[ErrorPayload][${scope}] ${formatDingTalkErrorPayload(payload)}`;
|
|
319
327
|
}
|
|
320
328
|
|
|
321
|
-
export function getProxyBypassOption(config?: {
|
|
329
|
+
export function getProxyBypassOption(config?: {
|
|
330
|
+
bypassProxyForSend?: boolean;
|
|
331
|
+
}): { proxy: false } | Record<string, never> {
|
|
322
332
|
return config?.bypassProxyForSend ? { proxy: false } : {};
|
|
323
333
|
}
|
|
324
334
|
|
|
@@ -445,7 +455,8 @@ export function formatDingTalkConnectionErrorLog(
|
|
|
445
455
|
? errRecord.dingtalkConnectionEndpoint
|
|
446
456
|
: undefined;
|
|
447
457
|
|
|
448
|
-
const hasResponse =
|
|
458
|
+
const hasResponse =
|
|
459
|
+
"response" in errRecord && errRecord.response !== null && errRecord.response !== undefined;
|
|
449
460
|
if (!hasResponse && !endpoint && stage === scope) {
|
|
450
461
|
return null;
|
|
451
462
|
}
|
|
@@ -455,7 +466,8 @@ export function formatDingTalkConnectionErrorLog(
|
|
|
455
466
|
parts.push(`endpoint=${endpoint}`);
|
|
456
467
|
}
|
|
457
468
|
|
|
458
|
-
const response = (err as { response?: { status?: unknown; data?: unknown; headers?: unknown } })
|
|
469
|
+
const response = (err as { response?: { status?: unknown; data?: unknown; headers?: unknown } })
|
|
470
|
+
.response;
|
|
459
471
|
if (response) {
|
|
460
472
|
if (response.status !== undefined && response.status !== null) {
|
|
461
473
|
const statusText =
|
|
@@ -469,7 +481,12 @@ export function formatDingTalkConnectionErrorLog(
|
|
|
469
481
|
}
|
|
470
482
|
|
|
471
483
|
let requestId = getHeaderCaseInsensitive(response.headers, "x-acs-dingtalk-request-id");
|
|
472
|
-
if (
|
|
484
|
+
if (
|
|
485
|
+
!requestId &&
|
|
486
|
+
response.data &&
|
|
487
|
+
typeof response.data === "object" &&
|
|
488
|
+
!Array.isArray(response.data)
|
|
489
|
+
) {
|
|
473
490
|
const data = response.data as Record<string, unknown>;
|
|
474
491
|
if (typeof data.requestId === "string") {
|
|
475
492
|
requestId = data.requestId;
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
import { maybeResolveTextAlias } from "openclaw/plugin-sdk/command-auth";
|
|
11
11
|
import type { OpenClawConfig } from "openclaw/plugin-sdk/core";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
12
|
+
import { parseLearnCommand } from "../command/learning-command-service";
|
|
13
|
+
import { sendBySession } from "../messaging/send-service";
|
|
14
|
+
import { resolveRobotCode } from "../platform/config";
|
|
15
|
+
import { getDingTalkRuntime } from "../platform/runtime";
|
|
16
16
|
import type {
|
|
17
17
|
AgentNameMatch,
|
|
18
18
|
DingTalkConfig,
|
|
@@ -21,10 +21,10 @@ import type {
|
|
|
21
21
|
Logger,
|
|
22
22
|
MessageContent,
|
|
23
23
|
ResolvedDingTalkRoute,
|
|
24
|
-
} from "../types";
|
|
25
|
-
import { getErrorMessage } from "../utils";
|
|
24
|
+
} from "../platform/types";
|
|
25
|
+
import { getErrorMessage } from "../shared/utils";
|
|
26
26
|
import { resolveAtAgents } from "./agent-name-matcher";
|
|
27
|
-
import type { ResolvedDingTalkSessionPeer } from "
|
|
27
|
+
import type { ResolvedDingTalkSessionPeer } from "./session-routing";
|
|
28
28
|
|
|
29
29
|
export class HostRoutingHelperUnavailableError extends Error {
|
|
30
30
|
constructor(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { readNamespaceJson, writeNamespaceJsonAtomic } from "../persistence-store";
|
|
3
|
+
import { readNamespaceJson, writeNamespaceJsonAtomic } from "../shared/persistence-store";
|
|
4
4
|
|
|
5
5
|
const GROUP_MEMBERS_NAMESPACE = "members.group-roster";
|
|
6
6
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readNamespaceJson, writeNamespaceJsonAtomic } from "
|
|
1
|
+
import { readNamespaceJson, writeNamespaceJsonAtomic } from "../shared/persistence-store";
|
|
2
2
|
|
|
3
3
|
const SESSION_PEER_OVERRIDE_NAMESPACE = "session-peer-overrides";
|
|
4
4
|
|
|
@@ -20,7 +20,11 @@ function readBucket(storePath: string, accountId: string): SessionPeerOverrideBu
|
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function writeBucket(
|
|
23
|
+
function writeBucket(
|
|
24
|
+
storePath: string,
|
|
25
|
+
accountId: string,
|
|
26
|
+
bucket: SessionPeerOverrideBucket,
|
|
27
|
+
): void {
|
|
24
28
|
writeNamespaceJsonAtomic(SESSION_PEER_OVERRIDE_NAMESPACE, {
|
|
25
29
|
storePath,
|
|
26
30
|
scope: { accountId },
|
|
@@ -63,8 +67,9 @@ export function clearSessionPeerOverride(params: {
|
|
|
63
67
|
const bucket = readBucket(params.storePath, params.accountId);
|
|
64
68
|
const sourceKey = buildSourceKey(params.sourceKind, params.sourceId);
|
|
65
69
|
const legacyKey = params.sourceKind === "group" ? params.sourceId : undefined;
|
|
66
|
-
const existed =
|
|
67
|
-
|
|
70
|
+
const existed =
|
|
71
|
+
Object.prototype.hasOwnProperty.call(bucket.peers, sourceKey) ||
|
|
72
|
+
(legacyKey ? Object.prototype.hasOwnProperty.call(bucket.peers, legacyKey) : false);
|
|
68
73
|
if (!existed) {
|
|
69
74
|
return false;
|
|
70
75
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { OpenClawConfig } from "openclaw/plugin-sdk/core";
|
|
2
2
|
import type { ChannelDirectoryEntry } from "openclaw/plugin-sdk/directory-runtime";
|
|
3
|
-
import { getConfig, stripTargetPrefix } from "../config";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { getConfig, stripTargetPrefix } from "../platform/config";
|
|
4
|
+
import { getDingTalkRuntime } from "../platform/runtime";
|
|
5
|
+
import { resolveOriginalPeerId } from "./peer-id-registry";
|
|
6
6
|
import { listKnownGroupTargets, listKnownUserTargets } from "./target-directory-store";
|
|
7
7
|
|
|
8
8
|
export type DirectoryListParams = {
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
export type DynamicAckReactionLogger = {
|
|
2
|
-
debug?: (msg: string) => void;
|
|
3
|
-
info?: (msg: string) => void;
|
|
4
|
-
warn?: (msg: string) => void;
|
|
5
|
-
};
|
|
6
|
-
export type RuntimeAgentEvent = {
|
|
7
|
-
stream?: string;
|
|
8
|
-
runId?: string;
|
|
9
|
-
sessionKey?: string;
|
|
10
|
-
data?: {
|
|
11
|
-
phase?: string;
|
|
12
|
-
name?: string;
|
|
13
|
-
args?: unknown;
|
|
14
|
-
runId?: string;
|
|
15
|
-
sessionKey?: string;
|
|
16
|
-
toolCallId?: string;
|
|
17
|
-
meta?: {
|
|
18
|
-
runId?: string;
|
|
19
|
-
sessionKey?: string;
|
|
20
|
-
} | null;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
export type RuntimeEventsSurface = {
|
|
24
|
-
onAgentEvent?: (listener: (event: unknown) => void) => (() => void);
|
|
25
|
-
};
|
|
26
|
-
export declare function getEventRunId(event: RuntimeAgentEvent | undefined): string | undefined;
|
|
27
|
-
export declare function getEventSessionKey(event: RuntimeAgentEvent | undefined): string | undefined;
|
|
28
|
-
export declare function describeEvent(event: RuntimeAgentEvent | undefined): string;
|
|
29
|
-
export declare function createDynamicAckReactionCorrelator(params: {
|
|
30
|
-
sessionKey: string;
|
|
31
|
-
enabled: boolean;
|
|
32
|
-
createdAt: number;
|
|
33
|
-
optimisticCaptureWindowMs: number;
|
|
34
|
-
log?: DynamicAckReactionLogger;
|
|
35
|
-
}): (event: RuntimeAgentEvent | undefined) => boolean;
|
package/dist/src/config.d.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { OpenClawConfig } from "openclaw/plugin-sdk/core";
|
|
2
|
-
import type { DingTalkConfig } from "./types";
|
|
3
|
-
export { resolveRelativePath, resolveUserPath } from "./path-utils";
|
|
4
|
-
export type RuntimeDingTalkConfig = Omit<DingTalkConfig, "clientSecret"> & {
|
|
5
|
-
clientSecret: string;
|
|
6
|
-
};
|
|
7
|
-
/**
|
|
8
|
-
* Merge channel-level defaults into an account-specific config.
|
|
9
|
-
* Account-level values take precedence; `accounts` key is excluded to avoid recursion.
|
|
10
|
-
*/
|
|
11
|
-
export declare function mergeAccountWithDefaults(channelCfg: DingTalkConfig, accountCfg: DingTalkConfig): DingTalkConfig;
|
|
12
|
-
/**
|
|
13
|
-
* Resolve DingTalk config for an account.
|
|
14
|
-
* Named accounts inherit channel-level defaults with account-level overrides.
|
|
15
|
-
* Falls back to top-level config for single-account setups.
|
|
16
|
-
*/
|
|
17
|
-
export declare function getConfig(cfg: OpenClawConfig, accountId?: string): DingTalkConfig;
|
|
18
|
-
export declare function isConfigured(cfg: OpenClawConfig, accountId?: string): boolean;
|
|
19
|
-
export declare function resolveRuntimeConfig(config: DingTalkConfig, log?: {
|
|
20
|
-
warn?: (message: string, data?: unknown) => void;
|
|
21
|
-
}): Promise<RuntimeDingTalkConfig>;
|
|
22
|
-
/**
|
|
23
|
-
* Resolve the robot code used by DingTalk APIs.
|
|
24
|
-
* DingTalk robotCode is always equal to clientId; this helper trims whitespace.
|
|
25
|
-
*/
|
|
26
|
-
export declare function resolveRobotCode(config: Pick<DingTalkConfig, "clientId">): string;
|
|
27
|
-
export declare function resolveGroupConfig(cfg: DingTalkConfig, groupId: string): {
|
|
28
|
-
systemPrompt?: string;
|
|
29
|
-
requireMention?: boolean;
|
|
30
|
-
groupAllowFrom?: string[];
|
|
31
|
-
} | undefined;
|
|
32
|
-
export declare function resolveAckReactionSetting(params: {
|
|
33
|
-
cfg: OpenClawConfig;
|
|
34
|
-
accountId?: string | null;
|
|
35
|
-
agentId?: string | null;
|
|
36
|
-
}): string | undefined;
|
|
37
|
-
/**
|
|
38
|
-
* Strip group/user prefixes used by CLI targeting.
|
|
39
|
-
* Returns raw DingTalk target ID and whether caller explicitly requested a user target.
|
|
40
|
-
*/
|
|
41
|
-
export declare function stripTargetPrefix(target: string): {
|
|
42
|
-
targetId: string;
|
|
43
|
-
isExplicitUser: boolean;
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* List all DingTalk account IDs from config
|
|
47
|
-
*/
|
|
48
|
-
export declare function listDingTalkAccountIds(cfg: OpenClawConfig): string[];
|
|
49
|
-
/**
|
|
50
|
-
* Resolved DingTalk account with configuration status
|
|
51
|
-
*/
|
|
52
|
-
export interface ResolvedDingTalkAccount extends DingTalkConfig {
|
|
53
|
-
accountId: string;
|
|
54
|
-
configured: boolean;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Resolve a specific DingTalk account configuration
|
|
58
|
-
*/
|
|
59
|
-
export declare function resolveDingTalkAccount(cfg: OpenClawConfig, accountId?: string | null): ResolvedDingTalkAccount;
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { getErrorMessage } from "../utils";
|
|
2
|
-
|
|
3
|
-
export type DynamicAckReactionLogger = {
|
|
4
|
-
debug?: (msg: string) => void;
|
|
5
|
-
info?: (msg: string) => void;
|
|
6
|
-
warn?: (msg: string) => void;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export type RuntimeAgentEvent = {
|
|
10
|
-
stream?: string;
|
|
11
|
-
runId?: string;
|
|
12
|
-
sessionKey?: string;
|
|
13
|
-
data?: {
|
|
14
|
-
phase?: string;
|
|
15
|
-
name?: string;
|
|
16
|
-
args?: unknown;
|
|
17
|
-
runId?: string;
|
|
18
|
-
sessionKey?: string;
|
|
19
|
-
toolCallId?: string;
|
|
20
|
-
meta?: {
|
|
21
|
-
runId?: string;
|
|
22
|
-
sessionKey?: string;
|
|
23
|
-
} | null;
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export type RuntimeEventsSurface = {
|
|
28
|
-
onAgentEvent?: (listener: (event: unknown) => void) => (() => void);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
function firstTrimmedString(...values: unknown[]): string | undefined {
|
|
32
|
-
for (const value of values) {
|
|
33
|
-
if (typeof value === "string" && value.trim()) {
|
|
34
|
-
return value.trim();
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return undefined;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function getEventRunId(event: RuntimeAgentEvent | undefined): string | undefined {
|
|
41
|
-
return firstTrimmedString(event?.runId, event?.data?.runId, event?.data?.meta?.runId);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function getEventSessionKey(event: RuntimeAgentEvent | undefined): string | undefined {
|
|
45
|
-
return firstTrimmedString(event?.sessionKey, event?.data?.sessionKey, event?.data?.meta?.sessionKey);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function describeEvent(event: RuntimeAgentEvent | undefined): string {
|
|
49
|
-
const stream = firstTrimmedString(event?.stream) || "-";
|
|
50
|
-
const phase = firstTrimmedString(event?.data?.phase) || "-";
|
|
51
|
-
const toolName = firstTrimmedString(event?.data?.name) || "-";
|
|
52
|
-
const toolCallId = firstTrimmedString(event?.data?.toolCallId) || "-";
|
|
53
|
-
return `stream=${stream} phase=${phase} runId=${getEventRunId(event) || "-"} ` +
|
|
54
|
-
`sessionKey=${getEventSessionKey(event) || "-"} toolCallId=${toolCallId} toolName=${toolName}`;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function createDynamicAckReactionCorrelator(params: {
|
|
58
|
-
sessionKey: string;
|
|
59
|
-
enabled: boolean;
|
|
60
|
-
createdAt: number;
|
|
61
|
-
optimisticCaptureWindowMs: number;
|
|
62
|
-
log?: DynamicAckReactionLogger;
|
|
63
|
-
}) {
|
|
64
|
-
let activeRunId: string | undefined;
|
|
65
|
-
let correlationUnavailableLogged = false;
|
|
66
|
-
let optimisticCaptureCount = 0;
|
|
67
|
-
|
|
68
|
-
return (event: RuntimeAgentEvent | undefined): boolean => {
|
|
69
|
-
const eventRunId = getEventRunId(event);
|
|
70
|
-
const eventSessionKey = getEventSessionKey(event);
|
|
71
|
-
const eventStream = firstTrimmedString(event?.stream) || "";
|
|
72
|
-
const eventPhase = firstTrimmedString(event?.data?.phase) || "";
|
|
73
|
-
|
|
74
|
-
if (activeRunId) {
|
|
75
|
-
const matched = eventRunId === activeRunId;
|
|
76
|
-
params.log?.debug?.(
|
|
77
|
-
`[DingTalk] Dynamic reaction correlation by runId matched=${matched} activeRunId=${activeRunId} ` +
|
|
78
|
-
`eventRunId=${eventRunId || "-"} eventSessionKey=${eventSessionKey || "-"}`,
|
|
79
|
-
);
|
|
80
|
-
return matched;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (eventSessionKey === params.sessionKey) {
|
|
84
|
-
if (eventRunId) {
|
|
85
|
-
activeRunId = eventRunId;
|
|
86
|
-
params.log?.debug?.(
|
|
87
|
-
`[DingTalk] Dynamic reaction captured active runId=${activeRunId} from sessionKey=${params.sessionKey}`,
|
|
88
|
-
);
|
|
89
|
-
} else {
|
|
90
|
-
params.log?.debug?.(
|
|
91
|
-
`[DingTalk] Dynamic reaction correlated by sessionKey=${params.sessionKey} without runId`,
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (
|
|
98
|
-
optimisticCaptureCount === 0
|
|
99
|
-
&& eventStream === "lifecycle"
|
|
100
|
-
&& eventPhase === "start"
|
|
101
|
-
&& eventRunId
|
|
102
|
-
&& !eventSessionKey
|
|
103
|
-
&& Date.now() - params.createdAt <= params.optimisticCaptureWindowMs
|
|
104
|
-
) {
|
|
105
|
-
optimisticCaptureCount += 1;
|
|
106
|
-
activeRunId = eventRunId;
|
|
107
|
-
params.log?.debug?.(
|
|
108
|
-
`[DingTalk] Dynamic reaction optimistically captured active runId=${activeRunId} ` +
|
|
109
|
-
`from first lifecycle event without sessionKey windowMs=${params.optimisticCaptureWindowMs}`,
|
|
110
|
-
);
|
|
111
|
-
return true;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (!correlationUnavailableLogged && params.enabled) {
|
|
115
|
-
correlationUnavailableLogged = true;
|
|
116
|
-
params.log?.debug?.(
|
|
117
|
-
`[DingTalk] Dynamic reaction ignored uncorrelated agent events; ` +
|
|
118
|
-
`reason=${getErrorMessage(eventRunId || eventSessionKey || "waiting for sessionKey/runId match")}`,
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
return false;
|
|
122
|
-
};
|
|
123
|
-
}
|