@cjhyy/code-shell-chat 0.9.18 → 0.9.20
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/bound-session-chat.d.ts +1 -1
- package/dist/bound-session-chat.js +13 -18
- package/dist/channel.d.ts +2 -0
- package/dist/cli.js +2 -0
- package/dist/dingtalk.js +1 -0
- package/dist/discord.js +2 -0
- package/dist/gateway.js +1 -0
- package/dist/lark.js +1 -0
- package/dist/line.js +1 -0
- package/dist/mattermost.js +1 -0
- package/dist/protocol.d.ts +2 -0
- package/dist/slack.js +8 -0
- package/dist/teams.js +1 -0
- package/dist/telegram.js +1 -0
- package/dist/wechat.js +1 -0
- package/dist/wecom.js +2 -0
- package/dist/whatsapp.js +1 -0
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Two properties matter more than they look:
|
|
11
11
|
*
|
|
12
|
-
* - Leaving is decided
|
|
12
|
+
* - Leaving is decided by the host, never by a model. /mimi has
|
|
13
13
|
* to work when the worker is wedged or the bound Session is unreachable,
|
|
14
14
|
* otherwise a user can be stuck inside a Session with no way out.
|
|
15
15
|
* - The reply for an accepted message is not this middleware's job. A Session
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Two properties matter more than they look:
|
|
11
11
|
*
|
|
12
|
-
* - Leaving is decided
|
|
12
|
+
* - Leaving is decided by the host, never by a model. /mimi has
|
|
13
13
|
* to work when the worker is wedged or the bound Session is unreachable,
|
|
14
14
|
* otherwise a user can be stuck inside a Session with no way out.
|
|
15
15
|
* - The reply for an accepted message is not this middleware's job. A Session
|
|
@@ -26,28 +26,23 @@ function isAddressable(message) {
|
|
|
26
26
|
return Boolean(message.target?.trim() && message.senderId?.trim());
|
|
27
27
|
}
|
|
28
28
|
export function createBoundSessionChat(options) {
|
|
29
|
-
const isDirectMessage = options.isDirectMessage ?? (() => true);
|
|
29
|
+
const isDirectMessage = options.isDirectMessage ?? ((message) => message.isDirectMessage === true);
|
|
30
30
|
return async ({ message, reply }, next) => {
|
|
31
31
|
if (!message.text.trim() && !message.attachments?.length)
|
|
32
32
|
return next();
|
|
33
33
|
if (!isAddressable(message))
|
|
34
34
|
return next();
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
// The bridge being unreachable must not swallow the message: fall
|
|
48
|
-
// through so Mimi still answers, which is the pre-binding behavior.
|
|
49
|
-
return next();
|
|
50
|
-
}
|
|
35
|
+
// A transport timeout is ambiguous: the Work Session may already have
|
|
36
|
+
// accepted this message. Leave retry to the durable inbox instead of also
|
|
37
|
+
// handing the same message to Mimi.
|
|
38
|
+
const disposition = await options.desktop.routeBoundSessionMessage({
|
|
39
|
+
channel: message.channel,
|
|
40
|
+
target: message.target,
|
|
41
|
+
senderId: message.senderId,
|
|
42
|
+
...(message.messageId ? { messageId: message.messageId } : {}),
|
|
43
|
+
text: message.text,
|
|
44
|
+
isDirectMessage: isDirectMessage(message),
|
|
45
|
+
});
|
|
51
46
|
switch (disposition.kind) {
|
|
52
47
|
case "not-bound":
|
|
53
48
|
return next();
|
package/dist/channel.d.ts
CHANGED
|
@@ -62,6 +62,8 @@ export interface ChannelMessage {
|
|
|
62
62
|
channel: string;
|
|
63
63
|
target: string;
|
|
64
64
|
senderId: string;
|
|
65
|
+
/** Adapter-authenticated conversation kind; missing means unknown, never private. */
|
|
66
|
+
isDirectMessage?: boolean;
|
|
65
67
|
text: string;
|
|
66
68
|
attachments?: readonly ChatAttachment[];
|
|
67
69
|
messageId?: string;
|
package/dist/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ import { createChannelAdapterAsync } from "./adapter-factory.js";
|
|
|
7
7
|
import { ChatGateway, createAllowlistMiddleware, createRateLimitMiddleware, } from "./chat-gateway.js";
|
|
8
8
|
import { defaultGatewayConfigPath, loadGatewayConfig } from "./config.js";
|
|
9
9
|
import { DesktopControlClient } from "./desktop-control-client.js";
|
|
10
|
+
import { createBoundSessionChat } from "./bound-session-chat.js";
|
|
10
11
|
import { CODE_SHELL_REMOTE_COMMANDS, createCodeShellRemoteCommands, createMimiPetChat, MIMI_MIN_CONCURRENT_MESSAGES_PER_TARGET, } from "./gateway.js";
|
|
11
12
|
import { loginCodeShellWechat } from "./wechat-login.js";
|
|
12
13
|
import { defaultWechatDataDirectory } from "./wechat-storage.js";
|
|
@@ -76,6 +77,7 @@ async function main(args = process.argv.slice(2)) {
|
|
|
76
77
|
]))));
|
|
77
78
|
gateway.use(createRateLimitMiddleware(config.runtime.maxMessagesPerUserPerMinute));
|
|
78
79
|
gateway.use(createCodeShellRemoteCommands({ desktop }));
|
|
80
|
+
gateway.use(createBoundSessionChat({ desktop }));
|
|
79
81
|
gateway.use(createMimiPetChat({ desktop, channels: adapters }));
|
|
80
82
|
console.log(`[code-shell-chat] gateway 已启动:${config.channels.map(({ channel }) => channel).join(", ")}`);
|
|
81
83
|
const gatewayTask = gateway.run(shutdown.signal);
|
package/dist/dingtalk.js
CHANGED
|
@@ -17,6 +17,7 @@ export function parseDingTalkTextMessage(data, messageId) {
|
|
|
17
17
|
channel: "dingtalk",
|
|
18
18
|
target: message.conversationId,
|
|
19
19
|
senderId: message.senderStaffId || message.senderId,
|
|
20
|
+
isDirectMessage: message.conversationType === "1",
|
|
20
21
|
text: message.text.content,
|
|
21
22
|
...(messageId ? { messageId } : {}),
|
|
22
23
|
metadata: {
|
package/dist/discord.js
CHANGED
|
@@ -43,6 +43,7 @@ export class DiscordAdapter {
|
|
|
43
43
|
channel: this.channel,
|
|
44
44
|
target: message.channelId,
|
|
45
45
|
senderId: message.author.id,
|
|
46
|
+
isDirectMessage: message.channel.type === ChannelType.DM,
|
|
46
47
|
text: message.content,
|
|
47
48
|
messageId: message.id,
|
|
48
49
|
...(attachments.length > 0 ? { attachments } : {}),
|
|
@@ -91,6 +92,7 @@ export class DiscordAdapter {
|
|
|
91
92
|
channel: this.channel,
|
|
92
93
|
target,
|
|
93
94
|
senderId: interaction.user.id,
|
|
95
|
+
isDirectMessage: interaction.channel?.type === ChannelType.DM,
|
|
94
96
|
text: `/${interaction.commandName}`,
|
|
95
97
|
messageId: interaction.id,
|
|
96
98
|
}));
|
package/dist/gateway.js
CHANGED
|
@@ -186,6 +186,7 @@ async function buildMimiOutgoingReplies(options, message, capabilities, configur
|
|
|
186
186
|
channel: message.channel,
|
|
187
187
|
target: message.target,
|
|
188
188
|
senderId: message.senderId,
|
|
189
|
+
isDirectMessage: message.isDirectMessage === true,
|
|
189
190
|
...(message.messageId ? { messageId: message.messageId } : {}),
|
|
190
191
|
capabilities,
|
|
191
192
|
channels: gatewayChannelCatalog(message.channel, capabilities, configuredChannels),
|
package/dist/lark.js
CHANGED
|
@@ -37,6 +37,7 @@ export class LarkAdapter {
|
|
|
37
37
|
channel: this.channel,
|
|
38
38
|
target: event.message.chat_id,
|
|
39
39
|
senderId: sender,
|
|
40
|
+
isDirectMessage: event.message.chat_type === "p2p",
|
|
40
41
|
text,
|
|
41
42
|
...(event.message.message_id ? { messageId: event.message.message_id } : {}),
|
|
42
43
|
...(attachment ? { attachments: [attachment] } : {}),
|
package/dist/line.js
CHANGED
package/dist/mattermost.js
CHANGED
|
@@ -143,6 +143,7 @@ export class MattermostAdapter {
|
|
|
143
143
|
channel: this.channel,
|
|
144
144
|
target: post.channel_id,
|
|
145
145
|
senderId: post.user_id,
|
|
146
|
+
isDirectMessage: event.data.channel_type === "D",
|
|
146
147
|
text: post.message ?? "",
|
|
147
148
|
...(post.id ? { messageId: post.id } : {}),
|
|
148
149
|
...(attachments.length > 0 ? { attachments } : {}),
|
package/dist/protocol.d.ts
CHANGED
|
@@ -77,6 +77,8 @@ export interface PetChatRequest {
|
|
|
77
77
|
channel: string;
|
|
78
78
|
target: string;
|
|
79
79
|
senderId: string;
|
|
80
|
+
/** Adapter-authenticated private-chat signal; absent for legacy clients. */
|
|
81
|
+
isDirectMessage?: boolean;
|
|
80
82
|
messageId?: string;
|
|
81
83
|
/** Adapter-declared implementation capabilities for this exact route. */
|
|
82
84
|
capabilities: ChannelCapabilities;
|
package/dist/slack.js
CHANGED
|
@@ -58,6 +58,7 @@ export class SlackAdapter {
|
|
|
58
58
|
channel: this.channel,
|
|
59
59
|
target: event.channel,
|
|
60
60
|
senderId: event.user,
|
|
61
|
+
isDirectMessage: event.channel_type === "im",
|
|
61
62
|
text,
|
|
62
63
|
...(event.client_msg_id || event.ts
|
|
63
64
|
? { messageId: String(event.client_msg_id ?? event.ts) }
|
|
@@ -73,10 +74,17 @@ export class SlackAdapter {
|
|
|
73
74
|
await ack();
|
|
74
75
|
return;
|
|
75
76
|
}
|
|
77
|
+
// A user can name a channel "directmessage"; only Slack's conversation
|
|
78
|
+
// metadata can distinguish a DM from a private channel or group DM.
|
|
79
|
+
const isDirectMessage = await this.web.conversations
|
|
80
|
+
.info({ channel: body.channel_id })
|
|
81
|
+
.then(({ channel }) => channel?.is_im === true)
|
|
82
|
+
.catch(() => false);
|
|
76
83
|
await dispatchSafely(handler, {
|
|
77
84
|
channel: this.channel,
|
|
78
85
|
target: body.channel_id,
|
|
79
86
|
senderId: body.user_id,
|
|
87
|
+
isDirectMessage,
|
|
80
88
|
text: [body.command, typeof body.text === "string" ? body.text : ""]
|
|
81
89
|
.filter(Boolean)
|
|
82
90
|
.join(" "),
|
package/dist/teams.js
CHANGED
|
@@ -97,6 +97,7 @@ export class TeamsAdapter {
|
|
|
97
97
|
channel: this.channel,
|
|
98
98
|
target,
|
|
99
99
|
senderId,
|
|
100
|
+
isDirectMessage: activity.conversation.conversationType === "personal",
|
|
100
101
|
text,
|
|
101
102
|
...(activity.id ? { messageId: activity.id } : {}),
|
|
102
103
|
...(attachments.length > 0 ? { attachments } : {}),
|
package/dist/telegram.js
CHANGED
|
@@ -181,6 +181,7 @@ function toChannelMessage(update, download) {
|
|
|
181
181
|
channel: "telegram",
|
|
182
182
|
target: String(message.chat.id),
|
|
183
183
|
senderId: String(sender),
|
|
184
|
+
isDirectMessage: message.chat.type === "private",
|
|
184
185
|
text,
|
|
185
186
|
...(attachments.length > 0 ? { attachments } : {}),
|
|
186
187
|
...(message.message_id === undefined ? {} : { messageId: String(message.message_id) }),
|
package/dist/wechat.js
CHANGED
|
@@ -470,6 +470,7 @@ export class WechatAdapter {
|
|
|
470
470
|
channel: this.channel,
|
|
471
471
|
target: senderId,
|
|
472
472
|
senderId,
|
|
473
|
+
isDirectMessage: !raw.group_id,
|
|
473
474
|
text,
|
|
474
475
|
...(attachments.length > 0 ? { attachments } : {}),
|
|
475
476
|
messageId: raw.message_id === undefined ? undefined : String(raw.message_id),
|
package/dist/wecom.js
CHANGED
|
@@ -24,6 +24,7 @@ export class WeComAdapter {
|
|
|
24
24
|
channel: this.channel,
|
|
25
25
|
target: message.chatid ?? message.from.userid,
|
|
26
26
|
senderId: message.from.userid,
|
|
27
|
+
isDirectMessage: message.chattype === "single",
|
|
27
28
|
text: message.text.content,
|
|
28
29
|
...(frame.headers?.req_id
|
|
29
30
|
? { messageId: frame.headers.req_id }
|
|
@@ -120,6 +121,7 @@ export class WeComAdapter {
|
|
|
120
121
|
channel: this.channel,
|
|
121
122
|
target: message.chatid ?? message.from.userid,
|
|
122
123
|
senderId: message.from.userid,
|
|
124
|
+
isDirectMessage: message.chattype === "single",
|
|
123
125
|
text,
|
|
124
126
|
messageId: message.msgid,
|
|
125
127
|
...(attachments.length > 0 ? { attachments } : {}),
|
package/dist/whatsapp.js
CHANGED
|
@@ -51,6 +51,7 @@ export class WhatsAppAdapter {
|
|
|
51
51
|
channel: this.channel,
|
|
52
52
|
target: message.from,
|
|
53
53
|
senderId: message.from,
|
|
54
|
+
isDirectMessage: !message.group_id,
|
|
54
55
|
text,
|
|
55
56
|
...(message.id ? { messageId: message.id } : {}),
|
|
56
57
|
...(media?.attachment ? { attachments: [media.attachment] } : {}),
|