@soimy/dingtalk 3.6.2 → 3.6.3
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.js +267 -97
- package/dist/index.js.map +3 -3
- package/dist/src/card-draft-controller.d.ts.map +1 -1
- package/dist/src/card-service.d.ts.map +1 -1
- package/dist/src/message-utils.d.ts +10 -0
- package/dist/src/message-utils.d.ts.map +1 -1
- package/dist/src/reply-strategy-card.d.ts.map +1 -1
- package/dist/src/reply-strategy-markdown.d.ts.map +1 -1
- package/dist/src/reply-strategy-types.d.ts +2 -0
- package/dist/src/reply-strategy-types.d.ts.map +1 -1
- package/dist/src/send-service.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/card-callback-service.ts +1 -1
- package/src/card-draft-controller.ts +4 -3
- package/src/card-service.ts +28 -4
- package/src/message-utils.ts +103 -7
- package/src/reply-strategy-card.ts +12 -3
- package/src/reply-strategy-markdown.ts +139 -20
- package/src/reply-strategy-types.ts +3 -0
- package/src/send-service.ts +67 -65
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card-draft-controller.d.ts","sourceRoot":"","sources":["../../src/card-draft-controller.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"card-draft-controller.d.ts","sourceRoot":"","sources":["../../src/card-draft-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card-service.d.ts","sourceRoot":"","sources":["../../src/card-service.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EACV,cAAc,EAGd,cAAc,EACd,wBAAwB,EACxB,MAAM,EACN,SAAS,EACV,MAAM,SAAS,CAAC;AAgBjB,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,EACzC,OAAO,SAAI,GACV,OAAO,CAAC,IAAI,CAAC,CAiBf;AAoFD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAU3D;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAChB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAWhD;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,cAAc,EACvB,GAAG,CAAC,EAAE,MAAM,GACX,IAAI,CAeN;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAOxE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAInE;AA8HD,UAAU,mBAAmB;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA+MD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAM5D;AAsBD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAcnG;AA4CD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,wBAAwB,CAAC,CAqBrE;AAED,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAEjB;AAsED,wBAAsB,YAAY,CAChC,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,MAAM,EACtB,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"card-service.d.ts","sourceRoot":"","sources":["../../src/card-service.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EACV,cAAc,EAGd,cAAc,EACd,wBAAwB,EACxB,MAAM,EACN,SAAS,EACV,MAAM,SAAS,CAAC;AAgBjB,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,EACzC,OAAO,SAAI,GACV,OAAO,CAAC,IAAI,CAAC,CAiBf;AAoFD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAU3D;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAChB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAWhD;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,cAAc,EACvB,GAAG,CAAC,EAAE,MAAM,GACX,IAAI,CAeN;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAOxE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAInE;AA8HD,UAAU,mBAAmB;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA+MD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAM5D;AAsBD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAcnG;AA4CD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,wBAAwB,CAAC,CAqBrE;AAED,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAEjB;AAsED,wBAAsB,YAAY,CAChC,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,MAAM,EACtB,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAsLhC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,cAAc,EACpB,aAAa,EAAE,MAAM,EACrB,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAChC,OAAO,CAAC,IAAI,CAAC,CAsCf;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,cAAc,EACpB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAWf;AAsBD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,mBAAmB,EAC5B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAqEf;AAGD,wBAAsB,YAAY,CAChC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,OAAe,EACzB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,SAAS,CAAA;CAAO,GACtC,OAAO,CAAC,IAAI,CAAC,CAwBf;AAuBD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,cAAc,EACpB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAqFlB;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE;IACP,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,EACD,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAsCf;AAqCD,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,IAAI,CA0BN;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,gBAAgB,EAAE,MAAM,EACxB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAkCf;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAGnD"}
|
|
@@ -7,6 +7,16 @@ export declare function detectMarkdownAndExtractTitle(text: string, options: Sen
|
|
|
7
7
|
useMarkdown: boolean;
|
|
8
8
|
title: string;
|
|
9
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* Convert markdown tables to DingTalk-compatible format.
|
|
12
|
+
* DingTalk's markdown renderer supports left/center/right alignment (:---, :---:, ---:).
|
|
13
|
+
* This function preserves the original alignment from the separator row.
|
|
14
|
+
* Tables inside code fences are preserved unchanged.
|
|
15
|
+
*
|
|
16
|
+
* Note: Despite the function name, this now produces DingTalk-compatible
|
|
17
|
+
* markdown tables rather than plain text. The name is preserved for API
|
|
18
|
+
* compatibility with the `convertMarkdownTables` config option.
|
|
19
|
+
*/
|
|
10
20
|
export declare function convertMarkdownTablesToPlainText(text: string): string;
|
|
11
21
|
export declare function extractMessageContent(data: DingTalkInboundMessage): MessageContent;
|
|
12
22
|
//# sourceMappingURL=message-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-utils.d.ts","sourceRoot":"","sources":["../../src/message-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,sBAAsB,EACtB,cAAc,EAEd,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAwWjB;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,kBAAkB,EAC3B,YAAY,EAAE,MAAM,GACnB;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAczC;
|
|
1
|
+
{"version":3,"file":"message-utils.d.ts","sourceRoot":"","sources":["../../src/message-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,sBAAsB,EACtB,cAAc,EAEd,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAwWjB;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,kBAAkB,EAC3B,YAAY,EAAE,MAAM,GACnB;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAczC;AAgHD;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4CrE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,sBAAsB,GAAG,cAAc,CAsSlF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply-strategy-card.d.ts","sourceRoot":"","sources":["../../src/reply-strategy-card.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmBH,OAAO,KAAK,EAAgC,aAAa,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAQhH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAc9C,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,oBAAoB,GAAG;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAA;CAAE,GACpF,aAAa,
|
|
1
|
+
{"version":3,"file":"reply-strategy-card.d.ts","sourceRoot":"","sources":["../../src/reply-strategy-card.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmBH,OAAO,KAAK,EAAgC,aAAa,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAQhH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAc9C,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,oBAAoB,GAAG;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAA;CAAE,GACpF,aAAa,CAkwBf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply-strategy-markdown.d.ts","sourceRoot":"","sources":["../../src/reply-strategy-markdown.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"reply-strategy-markdown.d.ts","sourceRoot":"","sources":["../../src/reply-strategy-markdown.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAGV,aAAa,EACb,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAmDhC,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,oBAAoB,GAAG,aAAa,CAmNpF"}
|
|
@@ -11,6 +11,7 @@ export type InternalReplyStrategyConfig = DingTalkConfig & {
|
|
|
11
11
|
/** @deprecated Internal compatibility only. Removed from public config surface. */
|
|
12
12
|
cardStreamReasoning?: boolean;
|
|
13
13
|
};
|
|
14
|
+
export type SourceReplyDeliveryMode = "automatic" | "message_tool_only";
|
|
14
15
|
export interface DeliverPayload {
|
|
15
16
|
text?: string;
|
|
16
17
|
mediaUrls: string[];
|
|
@@ -25,6 +26,7 @@ export interface DeliverPayload {
|
|
|
25
26
|
}
|
|
26
27
|
export interface ReplyOptions {
|
|
27
28
|
disableBlockStreaming: boolean;
|
|
29
|
+
sourceReplyDeliveryMode?: SourceReplyDeliveryMode;
|
|
28
30
|
onPartialReply?: (payload: {
|
|
29
31
|
text?: string;
|
|
30
32
|
}) => void | Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply-strategy-types.d.ts","sourceRoot":"","sources":["../../src/reply-strategy-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIjE,MAAM,MAAM,2BAA2B,GAAG,cAAc,GAAG;IACzD,mFAAmF;IACnF,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;
|
|
1
|
+
{"version":3,"file":"reply-strategy-types.d.ts","sourceRoot":"","sources":["../../src/reply-strategy-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send-service.d.ts","sourceRoot":"","sources":["../../src/send-service.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,cAAc,EACd,wBAAwB,EACxB,MAAM,EAGN,kBAAkB,EAEnB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAiD7D,KAAK,uBAAuB,GAAG,aAAa,GAAG;IAAE,QAAQ,EAAE,wBAAwB,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"send-service.d.ts","sourceRoot":"","sources":["../../src/send-service.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,cAAc,EACd,wBAAwB,EACxB,MAAM,EAGN,kBAAkB,EAEnB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAiD7D,KAAK,uBAAuB,GAAG,aAAa,GAAG;IAAE,QAAQ,EAAE,wBAAwB,CAAA;CAAE,CAAC;AAqPtF;;GAEG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,EAC/C,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GACvC,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAEnC;AAED,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,uBAAuB,CAAC,CA6HlC;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,EAC/C,OAAO,GAAE,kBAAkB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACxD,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,GAAG,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsJ5F;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,kBAAkB,GAAG;IAC5B,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IACjD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACzB,GACL,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,GAAG,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAuE5F;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,aAAa,CAAC,CA4ExB;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,kBAAkB,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,cAAc,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACxG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,aAAa,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,wBAAwB,CAAA;CAAE,CAAC,CA6HzH"}
|
package/package.json
CHANGED
|
@@ -187,7 +187,7 @@ export async function updateCardVariables(
|
|
|
187
187
|
{
|
|
188
188
|
outTrackId,
|
|
189
189
|
cardData: { cardParamMap: stringMap },
|
|
190
|
-
cardUpdateOptions: { updateCardDataByKey: true
|
|
190
|
+
cardUpdateOptions: { updateCardDataByKey: true },
|
|
191
191
|
},
|
|
192
192
|
{
|
|
193
193
|
headers: {
|
|
@@ -328,9 +328,9 @@ export function createCardDraftController(params: {
|
|
|
328
328
|
if (stopped || failed) {
|
|
329
329
|
return;
|
|
330
330
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
//
|
|
331
|
+
// Clear the live streaming content before committing blockList at the boundary.
|
|
332
|
+
// This drops any queued fake-streaming tail so the empty stream update can stop
|
|
333
|
+
// the animation before the blockList frame lands.
|
|
334
334
|
if (hasStreamingContent) {
|
|
335
335
|
await clearStreamingContentFromCard();
|
|
336
336
|
}
|
|
@@ -546,6 +546,7 @@ export function createCardDraftController(params: {
|
|
|
546
546
|
discardCurrentAnswer();
|
|
547
547
|
} else {
|
|
548
548
|
sealCurrentAnswer();
|
|
549
|
+
queueRender();
|
|
549
550
|
}
|
|
550
551
|
await beginBoundaryFlush();
|
|
551
552
|
return;
|
package/src/card-service.ts
CHANGED
|
@@ -910,6 +910,29 @@ export async function createAICard(
|
|
|
910
910
|
|
|
911
911
|
clearAICardDegrade(accountId, log);
|
|
912
912
|
|
|
913
|
+
// Kick the card into streaming mode immediately so the card enters the
|
|
914
|
+
// streaming lifecycle on the DingTalk side. Cards in IM_GROUP spaces may
|
|
915
|
+
// not accept variable updates (blockList etc.) without the streaming
|
|
916
|
+
// lifecycle being opened first. The lifecycle is tracked and finalized
|
|
917
|
+
// in commitAICardBlocks / finalizeStoppedAICard.
|
|
918
|
+
// Sends an empty content stream (isFull=true, isFinalize=false) which
|
|
919
|
+
// transitions the card from PROCESSING to INPUTING on the DingTalk side.
|
|
920
|
+
try {
|
|
921
|
+
await putAICardStreamingField(aiCardInstance, template.contentKey, "", false, log, {
|
|
922
|
+
suppressDegrade: true,
|
|
923
|
+
});
|
|
924
|
+
aiCardInstance.state = AICardStatus.INPUTING;
|
|
925
|
+
// Persist the updated streamLifecycleOpened and state so recovery
|
|
926
|
+
// can properly close the streaming lifecycle on DingTalk side.
|
|
927
|
+
if (shouldPersistPending) {
|
|
928
|
+
upsertPendingCard(aiCardInstance, options.storePath, log);
|
|
929
|
+
}
|
|
930
|
+
} catch (kickErr: any) {
|
|
931
|
+
log?.debug?.(
|
|
932
|
+
`[DingTalk][AICard] Non-critical: failed to kick card into streaming mode: ${kickErr.message}`,
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
|
|
913
936
|
return aiCardInstance;
|
|
914
937
|
} catch (err: any) {
|
|
915
938
|
log?.error?.(`[DingTalk][AICard] Create failed: ${err.message}`);
|
|
@@ -1049,7 +1072,6 @@ export async function clearAICardStreamingContent(
|
|
|
1049
1072
|
|
|
1050
1073
|
async function finalizeAICardStreamingLifecycleIfNeeded(
|
|
1051
1074
|
card: AICardInstance,
|
|
1052
|
-
content: string,
|
|
1053
1075
|
log?: Logger,
|
|
1054
1076
|
): Promise<void> {
|
|
1055
1077
|
if (!card.streamLifecycleOpened) {
|
|
@@ -1057,7 +1079,9 @@ async function finalizeAICardStreamingLifecycleIfNeeded(
|
|
|
1057
1079
|
}
|
|
1058
1080
|
const template = DINGTALK_CARD_TEMPLATE;
|
|
1059
1081
|
try {
|
|
1060
|
-
|
|
1082
|
+
// Close DingTalk's opened streaming lifecycle without re-rendering the final
|
|
1083
|
+
// answer in the live content area; the instances API below commits it once.
|
|
1084
|
+
await putAICardStreamingField(card, template.streamingKey, "", true, log, {
|
|
1061
1085
|
suppressDegrade: true,
|
|
1062
1086
|
});
|
|
1063
1087
|
} catch (err: unknown) {
|
|
@@ -1101,7 +1125,7 @@ export async function commitAICardBlocks(
|
|
|
1101
1125
|
}
|
|
1102
1126
|
|
|
1103
1127
|
await ensureFreshToken(card, log);
|
|
1104
|
-
await finalizeAICardStreamingLifecycleIfNeeded(card,
|
|
1128
|
+
await finalizeAICardStreamingLifecycleIfNeeded(card, log);
|
|
1105
1129
|
|
|
1106
1130
|
const template = DINGTALK_CARD_TEMPLATE;
|
|
1107
1131
|
const updates: Record<string, unknown> = {
|
|
@@ -1395,7 +1419,7 @@ export async function finalizeStoppedAICard(
|
|
|
1395
1419
|
await ensureFreshToken(card, log);
|
|
1396
1420
|
const template = DINGTALK_CARD_TEMPLATE;
|
|
1397
1421
|
const payload = buildStoppedCardFinalizePayload(options);
|
|
1398
|
-
await finalizeAICardStreamingLifecycleIfNeeded(card,
|
|
1422
|
+
await finalizeAICardStreamingLifecycleIfNeeded(card, log);
|
|
1399
1423
|
try {
|
|
1400
1424
|
await updateCardVariables(
|
|
1401
1425
|
card.outTrackId || card.cardInstanceId,
|
package/src/message-utils.ts
CHANGED
|
@@ -398,7 +398,10 @@ function isMarkdownTableSeparator(line: string): boolean {
|
|
|
398
398
|
.replace(/\|$/, "")
|
|
399
399
|
.split("|")
|
|
400
400
|
.map((cell) => cell.trim());
|
|
401
|
-
|
|
401
|
+
// DingTalk markdown requires :-: separator format (1 dash minimum).
|
|
402
|
+
// Note: single `-` cells in data rows would also match; this is an accepted trade-off
|
|
403
|
+
// for compatibility with DingTalk's recommended :-: separator format.
|
|
404
|
+
return cells.length > 0 && cells.every((cell) => /^:?-{1,}:?$/.test(cell));
|
|
402
405
|
}
|
|
403
406
|
|
|
404
407
|
function isMarkdownTableRow(line: string): boolean {
|
|
@@ -415,11 +418,96 @@ function parseMarkdownTableRow(line: string): string[] {
|
|
|
415
418
|
.map((cell) => cell.trim());
|
|
416
419
|
}
|
|
417
420
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
+
/**
|
|
422
|
+
* Parse alignment from a separator cell.
|
|
423
|
+
* Returns 'left', 'center', 'right', or 'center' (default).
|
|
424
|
+
*/
|
|
425
|
+
function parseSeparatorAlignment(cell: string): "left" | "center" | "right" {
|
|
426
|
+
const trimmed = cell.trim();
|
|
427
|
+
const hasLeftColon = trimmed.startsWith(":");
|
|
428
|
+
const hasRightColon = trimmed.endsWith(":");
|
|
429
|
+
if (hasLeftColon && hasRightColon) {
|
|
430
|
+
return "center";
|
|
431
|
+
}
|
|
432
|
+
if (hasRightColon) {
|
|
433
|
+
return "right";
|
|
434
|
+
}
|
|
435
|
+
if (hasLeftColon) {
|
|
436
|
+
return "left";
|
|
437
|
+
}
|
|
438
|
+
// Default to center for bare dashes (standard markdown)
|
|
439
|
+
return "center";
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Build separator row from alignment array.
|
|
444
|
+
*/
|
|
445
|
+
function buildSeparatorRow(alignments: ("left" | "center" | "right")[]): string {
|
|
446
|
+
const cells = alignments.map((align) => {
|
|
447
|
+
if (align === "left") {
|
|
448
|
+
return ":---";
|
|
449
|
+
}
|
|
450
|
+
if (align === "right") {
|
|
451
|
+
return "---:";
|
|
452
|
+
}
|
|
453
|
+
return ":---:";
|
|
454
|
+
});
|
|
455
|
+
return "|" + cells.join("|") + "|";
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Render markdown table rows preserving original alignment.
|
|
460
|
+
* Extracts alignment from the separator row and applies it to output.
|
|
461
|
+
*/
|
|
462
|
+
function renderMarkdownTable(headerLine: string, separatorLine: string, dataLines: string[]): string {
|
|
463
|
+
const headerCells = parseMarkdownTableRow(headerLine);
|
|
464
|
+
const separatorCells = parseMarkdownTableRow(separatorLine);
|
|
465
|
+
const dataRows = dataLines.map(parseMarkdownTableRow).filter((cells) => cells.length > 0);
|
|
466
|
+
|
|
467
|
+
if (headerCells.length === 0) {
|
|
468
|
+
return "";
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const colCount = Math.max(
|
|
472
|
+
headerCells.length,
|
|
473
|
+
separatorCells.length,
|
|
474
|
+
...dataRows.map((cells) => cells.length),
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
// Extract alignments from separator
|
|
478
|
+
const alignments: ("left" | "center" | "right")[] = [];
|
|
479
|
+
for (let i = 0; i < colCount; i++) {
|
|
480
|
+
const sepCell = separatorCells[i] || "";
|
|
481
|
+
alignments.push(parseSeparatorAlignment(sepCell));
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const separator = buildSeparatorRow(alignments);
|
|
485
|
+
|
|
486
|
+
const allRows = [headerCells, ...dataRows];
|
|
487
|
+
const rendered = allRows
|
|
488
|
+
.map((cells) => {
|
|
489
|
+
const padded = cells.length < colCount
|
|
490
|
+
? [...cells, ...Array(colCount - cells.length).fill("")]
|
|
491
|
+
: cells;
|
|
492
|
+
return "|" + padded.join("|") + "|";
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
// Insert separator after header row (works for header-only tables too)
|
|
496
|
+
rendered.splice(1, 0, separator);
|
|
497
|
+
|
|
498
|
+
return rendered.join("\n");
|
|
421
499
|
}
|
|
422
500
|
|
|
501
|
+
/**
|
|
502
|
+
* Convert markdown tables to DingTalk-compatible format.
|
|
503
|
+
* DingTalk's markdown renderer supports left/center/right alignment (:---, :---:, ---:).
|
|
504
|
+
* This function preserves the original alignment from the separator row.
|
|
505
|
+
* Tables inside code fences are preserved unchanged.
|
|
506
|
+
*
|
|
507
|
+
* Note: Despite the function name, this now produces DingTalk-compatible
|
|
508
|
+
* markdown tables rather than plain text. The name is preserved for API
|
|
509
|
+
* compatibility with the `convertMarkdownTables` config option.
|
|
510
|
+
*/
|
|
423
511
|
export function convertMarkdownTablesToPlainText(text: string): string {
|
|
424
512
|
const lines = text.split("\n");
|
|
425
513
|
const output: string[] = [];
|
|
@@ -441,13 +529,21 @@ export function convertMarkdownTablesToPlainText(text: string): string {
|
|
|
441
529
|
isMarkdownTableRow(line) &&
|
|
442
530
|
isMarkdownTableSeparator(lines[index + 1] || "")
|
|
443
531
|
) {
|
|
444
|
-
const
|
|
532
|
+
const headerLine = line;
|
|
533
|
+
const separatorLine = lines[index + 1] || "";
|
|
534
|
+
const dataLines: string[] = [];
|
|
445
535
|
index += 2;
|
|
446
536
|
while (index < lines.length && isMarkdownTableRow(lines[index] || "")) {
|
|
447
|
-
|
|
537
|
+
dataLines.push(lines[index] || "");
|
|
448
538
|
index += 1;
|
|
449
539
|
}
|
|
450
|
-
|
|
540
|
+
const renderedTable = renderMarkdownTable(headerLine, separatorLine, dataLines);
|
|
541
|
+
// Ensure blank line before table for DingTalk markdown rendering
|
|
542
|
+
const lastOutput = output[output.length - 1];
|
|
543
|
+
if (lastOutput !== undefined && lastOutput.trim() !== "") {
|
|
544
|
+
output.push("");
|
|
545
|
+
}
|
|
546
|
+
output.push(renderedTable);
|
|
451
547
|
continue;
|
|
452
548
|
}
|
|
453
549
|
|
|
@@ -102,7 +102,6 @@ export function createCardReplyStrategy(
|
|
|
102
102
|
};
|
|
103
103
|
const { mode, usedDeprecatedCardRealTimeStream } = resolveCardStreamingMode(config);
|
|
104
104
|
const streamAnswerLive = mode === "answer" || mode === "all";
|
|
105
|
-
const renderAnswerBlocksLive = mode === "all";
|
|
106
105
|
const streamThinkingLive = mode === "all";
|
|
107
106
|
let lifecycleState: CardReplyLifecycleState = "open";
|
|
108
107
|
const shouldAcceptAnswerSnapshot = () => lifecycleState === "open";
|
|
@@ -261,7 +260,10 @@ export function createCardReplyStrategy(
|
|
|
261
260
|
finalTextForFallback = normalized.answerText;
|
|
262
261
|
return;
|
|
263
262
|
}
|
|
264
|
-
await controller.updateAnswer(normalized.answerText
|
|
263
|
+
await controller.updateAnswer(normalized.answerText, {
|
|
264
|
+
stream: streamAnswerLive,
|
|
265
|
+
renderBlocks: !streamAnswerLive,
|
|
266
|
+
});
|
|
265
267
|
}
|
|
266
268
|
};
|
|
267
269
|
|
|
@@ -304,7 +306,8 @@ export function createCardReplyStrategy(
|
|
|
304
306
|
|
|
305
307
|
await controller.updateAnswer(answerSnapshot, {
|
|
306
308
|
stream: streamAnswerLive,
|
|
307
|
-
|
|
309
|
+
// Active answer previews live in the content field; blockList is committed at boundaries/finalize.
|
|
310
|
+
renderBlocks: false,
|
|
308
311
|
});
|
|
309
312
|
};
|
|
310
313
|
|
|
@@ -388,6 +391,11 @@ export function createCardReplyStrategy(
|
|
|
388
391
|
// Card mode keeps runtime block streaming disabled, but still consumes
|
|
389
392
|
// reasoning blocks through explicit callbacks and delivery metadata.
|
|
390
393
|
disableBlockStreaming: ctx.disableBlockStreaming ?? true,
|
|
394
|
+
// DingTalk card mode owns the visible reply surface. In group chats,
|
|
395
|
+
// OpenClaw defaults source replies to message-tool-only; override that
|
|
396
|
+
// so final replies are delivered into this card instead of spawning a
|
|
397
|
+
// separate visible message/card via the message tool.
|
|
398
|
+
sourceReplyDeliveryMode: "automatic",
|
|
391
399
|
|
|
392
400
|
onAssistantMessageStart: async () => {
|
|
393
401
|
if (isLifecycleSealed() || isStopRequested?.()) {
|
|
@@ -671,6 +679,7 @@ export function createCardReplyStrategy(
|
|
|
671
679
|
try {
|
|
672
680
|
await flushPendingReasoning();
|
|
673
681
|
|
|
682
|
+
await controller.clearStreamingContent?.();
|
|
674
683
|
await controller.flush();
|
|
675
684
|
await controller.waitForInFlight();
|
|
676
685
|
|
|
@@ -6,7 +6,15 @@
|
|
|
6
6
|
* Reasoning display is intentionally unsupported on DingTalk markdown.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { resolveRelativePath } from "./config";
|
|
11
|
+
import { prepareMediaInput, resolveOutboundMediaType } from "./media-utils";
|
|
12
|
+
import type {
|
|
13
|
+
DeliverPayload,
|
|
14
|
+
ReplyOptions,
|
|
15
|
+
ReplyStrategy,
|
|
16
|
+
ReplyStrategyContext,
|
|
17
|
+
} from "./reply-strategy-types";
|
|
10
18
|
import { sendMessage } from "./send-service";
|
|
11
19
|
|
|
12
20
|
const EMPTY_FINAL_FALLBACK_TEXT = "✅ Done";
|
|
@@ -14,7 +22,7 @@ const EMPTY_FINAL_FALLBACK_TEXT = "✅ Done";
|
|
|
14
22
|
function renderQuotedSegment(text: string): string {
|
|
15
23
|
return text
|
|
16
24
|
.split("\n")
|
|
17
|
-
.map((line) => line.length > 0 ? `> ${line}` : ">")
|
|
25
|
+
.map((line) => (line.length > 0 ? `> ${line}` : ">"))
|
|
18
26
|
.join("\n");
|
|
19
27
|
}
|
|
20
28
|
|
|
@@ -52,9 +60,12 @@ function computeSharedPrefixTail(previous: string, next: string): string {
|
|
|
52
60
|
return suffix.trim() ? suffix : "";
|
|
53
61
|
}
|
|
54
62
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
function renderMarkdownImage(mediaPath: string): string {
|
|
64
|
+
const filename = path.basename(mediaPath) || "image";
|
|
65
|
+
return ``;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function createMarkdownReplyStrategy(ctx: ReplyStrategyContext): ReplyStrategy {
|
|
58
69
|
let finalText: string | undefined;
|
|
59
70
|
let activeAnswerText = "";
|
|
60
71
|
let lastSentAnswerText = "";
|
|
@@ -79,7 +90,10 @@ export function createMarkdownReplyStrategy(
|
|
|
79
90
|
sentVisibleContent = true;
|
|
80
91
|
};
|
|
81
92
|
|
|
82
|
-
const
|
|
93
|
+
const prepareAnswerSuffix = (text: string | undefined): {
|
|
94
|
+
text: string;
|
|
95
|
+
markSent: () => void;
|
|
96
|
+
} | null => {
|
|
83
97
|
const current = typeof text === "string" ? text : "";
|
|
84
98
|
if (current.length > 0) {
|
|
85
99
|
activeAnswerText = current;
|
|
@@ -88,42 +102,146 @@ export function createMarkdownReplyStrategy(
|
|
|
88
102
|
|
|
89
103
|
const suffix = computeIncrementalSuffix(lastSentAnswerText, current);
|
|
90
104
|
if (suffix) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
105
|
+
return {
|
|
106
|
+
text: suffix,
|
|
107
|
+
markSent: () => {
|
|
108
|
+
lastSentAnswerText = current;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
94
111
|
}
|
|
95
112
|
|
|
96
113
|
if (current.trim() && lastSentAnswerText && !current.startsWith(lastSentAnswerText)) {
|
|
97
114
|
const suffix = computeSharedPrefixTail(lastSentAnswerText, current);
|
|
98
115
|
ctx.log?.warn?.(
|
|
99
116
|
`[DingTalk][Markdown] answer prefix drift detected; falling back to shared-prefix tail ` +
|
|
100
|
-
|
|
117
|
+
`prevLen=${lastSentAnswerText.length} currentLen=${current.length}`,
|
|
101
118
|
);
|
|
102
|
-
lastSentAnswerText = "";
|
|
103
119
|
if (suffix) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
120
|
+
return {
|
|
121
|
+
text: suffix,
|
|
122
|
+
markSent: () => {
|
|
123
|
+
lastSentAnswerText = current;
|
|
124
|
+
},
|
|
125
|
+
};
|
|
107
126
|
}
|
|
108
|
-
|
|
109
|
-
|
|
127
|
+
return {
|
|
128
|
+
text: current,
|
|
129
|
+
markSent: () => {
|
|
130
|
+
lastSentAnswerText = current;
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return null;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const emitAnswerSuffix = async (text: string | undefined): Promise<void> => {
|
|
139
|
+
const suffix = prepareAnswerSuffix(text);
|
|
140
|
+
if (suffix) {
|
|
141
|
+
await sendMarkdownSegment(suffix.text);
|
|
142
|
+
suffix.markSent();
|
|
110
143
|
}
|
|
111
144
|
};
|
|
112
145
|
|
|
146
|
+
const prepareMarkdownImageAttachments = async (
|
|
147
|
+
mediaUrls: string[],
|
|
148
|
+
): Promise<{
|
|
149
|
+
imageMarkdown: string[];
|
|
150
|
+
passthroughMediaUrls: string[];
|
|
151
|
+
cleanups: Array<() => Promise<void>>;
|
|
152
|
+
}> => {
|
|
153
|
+
const imageMarkdown: string[] = [];
|
|
154
|
+
const passthroughMediaUrls: string[] = [];
|
|
155
|
+
const cleanups: Array<() => Promise<void>> = [];
|
|
156
|
+
|
|
157
|
+
for (const rawMediaUrl of mediaUrls) {
|
|
158
|
+
const preparedMedia = await prepareMediaInput(
|
|
159
|
+
rawMediaUrl,
|
|
160
|
+
ctx.log,
|
|
161
|
+
ctx.config.mediaUrlAllowlist,
|
|
162
|
+
);
|
|
163
|
+
const actualMediaPath = preparedMedia.cleanup
|
|
164
|
+
? preparedMedia.path
|
|
165
|
+
: resolveRelativePath(preparedMedia.path);
|
|
166
|
+
const mediaType = resolveOutboundMediaType({
|
|
167
|
+
mediaPath: actualMediaPath,
|
|
168
|
+
asVoice: false,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
if (mediaType === "image") {
|
|
172
|
+
imageMarkdown.push(renderMarkdownImage(actualMediaPath));
|
|
173
|
+
if (preparedMedia.cleanup) {
|
|
174
|
+
cleanups.push(preparedMedia.cleanup);
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
await preparedMedia.cleanup?.();
|
|
178
|
+
passthroughMediaUrls.push(rawMediaUrl);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return { imageMarkdown, passthroughMediaUrls, cleanups };
|
|
183
|
+
};
|
|
184
|
+
|
|
113
185
|
return {
|
|
114
186
|
getReplyOptions(): ReplyOptions {
|
|
115
187
|
return {
|
|
116
188
|
disableBlockStreaming: ctx.disableBlockStreaming === true,
|
|
189
|
+
// DingTalk markdown/sessionWebhook mode owns the visible reply surface.
|
|
190
|
+
// Keep runtime final replies on this strategy even when group chats
|
|
191
|
+
// default source replies to message-tool-only.
|
|
192
|
+
sourceReplyDeliveryMode: "automatic",
|
|
117
193
|
};
|
|
118
194
|
},
|
|
119
195
|
|
|
120
196
|
async deliver(payload: DeliverPayload): Promise<void> {
|
|
197
|
+
let answerTextSentWithImages = false;
|
|
198
|
+
let toolTextSentWithImages = false;
|
|
199
|
+
|
|
121
200
|
if (payload.mediaUrls.length > 0) {
|
|
122
|
-
|
|
123
|
-
|
|
201
|
+
const prepared =
|
|
202
|
+
payload.audioAsVoice === true
|
|
203
|
+
? {
|
|
204
|
+
imageMarkdown: [],
|
|
205
|
+
passthroughMediaUrls: payload.mediaUrls,
|
|
206
|
+
cleanups: [],
|
|
207
|
+
}
|
|
208
|
+
: await prepareMarkdownImageAttachments(payload.mediaUrls);
|
|
209
|
+
try {
|
|
210
|
+
if (prepared.passthroughMediaUrls.length > 0) {
|
|
211
|
+
await ctx.deliverMedia(prepared.passthroughMediaUrls, {
|
|
212
|
+
audioAsVoice: payload.audioAsVoice,
|
|
213
|
+
});
|
|
214
|
+
sentVisibleContent = true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (prepared.imageMarkdown.length > 0) {
|
|
218
|
+
const answerSuffix =
|
|
219
|
+
payload.kind === "block" || payload.kind === "final"
|
|
220
|
+
? prepareAnswerSuffix(payload.text)
|
|
221
|
+
: typeof payload.text === "string"
|
|
222
|
+
? { text: renderQuotedSegment(payload.text), markSent: () => {} }
|
|
223
|
+
: null;
|
|
224
|
+
const markdownParts = [answerSuffix?.text || "", ...prepared.imageMarkdown].filter(
|
|
225
|
+
(part) => part.trim().length > 0,
|
|
226
|
+
);
|
|
227
|
+
if (markdownParts.length > 0) {
|
|
228
|
+
await sendMarkdownSegment(markdownParts.join("\n\n"));
|
|
229
|
+
answerSuffix?.markSent();
|
|
230
|
+
}
|
|
231
|
+
answerTextSentWithImages = payload.kind === "block" || payload.kind === "final";
|
|
232
|
+
toolTextSentWithImages = payload.kind === "tool";
|
|
233
|
+
}
|
|
234
|
+
} finally {
|
|
235
|
+
for (const cleanup of prepared.cleanups) {
|
|
236
|
+
await cleanup();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
124
239
|
}
|
|
125
240
|
|
|
126
241
|
if (payload.kind === "tool") {
|
|
242
|
+
if (toolTextSentWithImages) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
127
245
|
const text = typeof payload.text === "string" ? payload.text : "";
|
|
128
246
|
if (!text.trim()) {
|
|
129
247
|
return;
|
|
@@ -133,8 +251,9 @@ export function createMarkdownReplyStrategy(
|
|
|
133
251
|
}
|
|
134
252
|
|
|
135
253
|
if (
|
|
136
|
-
(payload.kind === "block" || payload.kind === "final")
|
|
137
|
-
|
|
254
|
+
(payload.kind === "block" || payload.kind === "final") &&
|
|
255
|
+
typeof payload.text === "string" &&
|
|
256
|
+
!answerTextSentWithImages
|
|
138
257
|
) {
|
|
139
258
|
await emitAnswerSuffix(payload.text);
|
|
140
259
|
}
|
|
@@ -16,6 +16,8 @@ export type InternalReplyStrategyConfig = DingTalkConfig & {
|
|
|
16
16
|
cardStreamReasoning?: boolean;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
export type SourceReplyDeliveryMode = "automatic" | "message_tool_only";
|
|
20
|
+
|
|
19
21
|
// ---- Public interfaces ----
|
|
20
22
|
|
|
21
23
|
export interface DeliverPayload {
|
|
@@ -33,6 +35,7 @@ export interface DeliverPayload {
|
|
|
33
35
|
|
|
34
36
|
export interface ReplyOptions {
|
|
35
37
|
disableBlockStreaming: boolean;
|
|
38
|
+
sourceReplyDeliveryMode?: SourceReplyDeliveryMode;
|
|
36
39
|
onPartialReply?: (payload: { text?: string }) => void | Promise<void>;
|
|
37
40
|
onReasoningStream?: (payload: { text?: string }) => void | Promise<void>;
|
|
38
41
|
onAssistantMessageStart?: () => void | Promise<void>;
|