@dcrays/dcgchat 0.1.6 → 0.1.8
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 +2 -0
- package/package.json +1 -1
- package/src/bot.ts +5 -0
- package/src/channel.ts +23 -11
- package/src/monitor.ts +13 -4
- package/src/tool.ts +65 -0
- package/src/types.ts +4 -0
package/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
|
2
2
|
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
3
3
|
import { dcgchatPlugin } from "./src/channel.js";
|
|
4
4
|
import { setDcgchatRuntime } from "./src/runtime.js";
|
|
5
|
+
import { monitoringToolMessage } from "./src/tool.js";
|
|
5
6
|
|
|
6
7
|
const plugin = {
|
|
7
8
|
id: "dcgchat",
|
|
@@ -10,6 +11,7 @@ const plugin = {
|
|
|
10
11
|
configSchema: emptyPluginConfigSchema(),
|
|
11
12
|
register(api: OpenClawPluginApi) {
|
|
12
13
|
setDcgchatRuntime(api.runtime);
|
|
14
|
+
monitoringToolMessage(api);
|
|
13
15
|
api.registerChannel({ plugin: dcgchatPlugin });
|
|
14
16
|
},
|
|
15
17
|
};
|
package/package.json
CHANGED
package/src/bot.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { createReplyPrefixContext } from "openclaw/plugin-sdk";
|
|
|
4
4
|
import type { InboundMessage, OutboundReply } from "./types.js";
|
|
5
5
|
import { getDcgchatRuntime } from "./runtime.js";
|
|
6
6
|
import { resolveAccount } from "./channel.js";
|
|
7
|
+
import { setMsgParams } from "./tool.js";
|
|
7
8
|
|
|
8
9
|
type MediaInfo = {
|
|
9
10
|
path: string;
|
|
@@ -244,6 +245,10 @@ export async function handleDcgchatMessage(params: {
|
|
|
244
245
|
state: 'final',
|
|
245
246
|
},
|
|
246
247
|
});
|
|
248
|
+
setMsgParams({
|
|
249
|
+
sessionId: '',
|
|
250
|
+
messageId: ''
|
|
251
|
+
});
|
|
247
252
|
log(`dcgchat[${accountId}]: final state sent`);
|
|
248
253
|
|
|
249
254
|
markDispatchIdle();
|
package/src/channel.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { ResolvedDcgchatAccount, DcgchatConfig } from "./types.js";
|
|
|
4
4
|
import { logDcgchat } from "./log.js";
|
|
5
5
|
import { getWsConnection } from "./connection.js";
|
|
6
6
|
import { ossUpload } from "./oss.js";
|
|
7
|
+
import { getMsgParams } from "./tool.js";
|
|
7
8
|
|
|
8
9
|
export function resolveAccount(cfg: OpenClawConfig, accountId?: string | null): ResolvedDcgchatAccount {
|
|
9
10
|
const id = accountId ?? DEFAULT_ACCOUNT_ID;
|
|
@@ -15,6 +16,8 @@ export function resolveAccount(cfg: OpenClawConfig, accountId?: string | null):
|
|
|
15
16
|
wsUrl: raw.wsUrl ?? "",
|
|
16
17
|
botToken: raw.botToken ?? "",
|
|
17
18
|
userId: raw.userId ?? "",
|
|
19
|
+
domainId: raw.domainId ?? "",
|
|
20
|
+
appId: raw.appId ?? "",
|
|
18
21
|
};
|
|
19
22
|
}
|
|
20
23
|
|
|
@@ -35,9 +38,10 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
35
38
|
threads: true,
|
|
36
39
|
media: true,
|
|
37
40
|
nativeCommands: true,
|
|
38
|
-
reactions:
|
|
41
|
+
reactions: true,
|
|
39
42
|
edit: false,
|
|
40
43
|
reply: true,
|
|
44
|
+
effects: true,
|
|
41
45
|
// blockStreaming: true,
|
|
42
46
|
},
|
|
43
47
|
reload: { configPrefixes: ["channels.dcgchat"] },
|
|
@@ -50,6 +54,8 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
50
54
|
wsUrl: { type: "string" },
|
|
51
55
|
botToken: { type: "string" },
|
|
52
56
|
userId: { type: "string" },
|
|
57
|
+
appId: { type: "string" },
|
|
58
|
+
domainId: { type: "string" },
|
|
53
59
|
capabilities: { type: "array", items: { type: "string" } },
|
|
54
60
|
},
|
|
55
61
|
},
|
|
@@ -76,6 +82,8 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
76
82
|
wsUrl: account.wsUrl,
|
|
77
83
|
botToken: account.botToken ? "***" : "",
|
|
78
84
|
userId: account.userId,
|
|
85
|
+
domainId: account.domainId,
|
|
86
|
+
appId: account.appId,
|
|
79
87
|
}),
|
|
80
88
|
},
|
|
81
89
|
messaging: {
|
|
@@ -91,8 +99,8 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
91
99
|
textChunkLimit: 4000,
|
|
92
100
|
sendText: async (ctx) => {
|
|
93
101
|
const target = ctx.to || "(implicit)";
|
|
94
|
-
logDcgchat.info(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> sendText ${target}: ${ctx.text}`);
|
|
95
102
|
const ws = getWsConnection()
|
|
103
|
+
const params = getMsgParams();
|
|
96
104
|
if (ws?.readyState === WebSocket.OPEN) {
|
|
97
105
|
const {botToken} = resolveAccount(ctx.cfg, ctx.accountId);
|
|
98
106
|
const content = {
|
|
@@ -102,12 +110,14 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
102
110
|
content: {
|
|
103
111
|
bot_token: botToken,
|
|
104
112
|
response: ctx.text,
|
|
105
|
-
session_id:
|
|
106
|
-
message_id: Date.now().toString(),
|
|
113
|
+
session_id: params.sessionId || Date.now().toString(),
|
|
114
|
+
message_id: params.messageId ||Date.now().toString(),
|
|
107
115
|
},
|
|
108
116
|
};
|
|
109
117
|
ws.send(JSON.stringify(content));
|
|
110
118
|
logDcgchat.info(`dcgchat[${ctx.accountId}]: sendText to ${target}, ${JSON.stringify(content)}`);
|
|
119
|
+
} else {
|
|
120
|
+
logDcgchat.warn(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> ${ws?.readyState}: ${ctx.text}`);
|
|
111
121
|
}
|
|
112
122
|
return {
|
|
113
123
|
channel: "dcgchat",
|
|
@@ -117,8 +127,8 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
117
127
|
},
|
|
118
128
|
sendMedia: async (ctx) => {
|
|
119
129
|
const target = ctx.to || "(implicit)";
|
|
120
|
-
logDcgchat.info(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> sendMedia ${target}: ${ctx.text + ctx.mediaUrl}`);
|
|
121
130
|
const ws = getWsConnection()
|
|
131
|
+
const params = getMsgParams();
|
|
122
132
|
if (ws?.readyState === WebSocket.OPEN) {
|
|
123
133
|
const {botToken} = resolveAccount(ctx.cfg, ctx.accountId);
|
|
124
134
|
try {
|
|
@@ -131,12 +141,12 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
131
141
|
content: {
|
|
132
142
|
bot_token: botToken,
|
|
133
143
|
response: ctx.text + '\n' + `[${fileName}](${url})`,
|
|
134
|
-
session_id:
|
|
135
|
-
message_id: Date.now().toString(),
|
|
144
|
+
session_id: params.sessionId || Date.now().toString(),
|
|
145
|
+
message_id: params.messageId ||Date.now().toString(),
|
|
136
146
|
},
|
|
137
147
|
};
|
|
138
148
|
ws.send(JSON.stringify(content));
|
|
139
|
-
logDcgchat.info(`dcgchat[${ctx.accountId}]:
|
|
149
|
+
logDcgchat.info(`dcgchat[${ctx.accountId}]: sendMedia to ${target}, ${JSON.stringify(content)}`);
|
|
140
150
|
} catch (error) {
|
|
141
151
|
const content = {
|
|
142
152
|
messageType: "openclaw_bot_chat",
|
|
@@ -145,13 +155,15 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
145
155
|
content: {
|
|
146
156
|
bot_token: botToken,
|
|
147
157
|
response: ctx.text + '\n' + ctx.mediaUrl,
|
|
148
|
-
session_id:
|
|
149
|
-
message_id: Date.now().toString(),
|
|
158
|
+
session_id: params.sessionId || Date.now().toString(),
|
|
159
|
+
message_id: params.messageId ||Date.now().toString(),
|
|
150
160
|
},
|
|
151
161
|
};
|
|
152
162
|
ws.send(JSON.stringify(content));
|
|
153
|
-
logDcgchat.info(`dcgchat[${ctx.accountId}]:
|
|
163
|
+
logDcgchat.info(`dcgchat[${ctx.accountId}]: sendMedia to ${target}, ${JSON.stringify(content)}`);
|
|
154
164
|
}
|
|
165
|
+
} else {
|
|
166
|
+
logDcgchat.warn(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> ${ws?.readyState}: ${ctx.text}`);
|
|
155
167
|
}
|
|
156
168
|
return {
|
|
157
169
|
channel: "dcgchat",
|
package/src/monitor.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { handleDcgchatMessage } from "./bot.js";
|
|
|
4
4
|
import { resolveAccount } from "./channel.js";
|
|
5
5
|
import { setWsConnection } from "./connection.js";
|
|
6
6
|
import type { InboundMessage, OutboundReply } from "./types.js";
|
|
7
|
+
import { setMsgParams } from "./tool.js";
|
|
7
8
|
|
|
8
9
|
export type MonitorDcgchatOpts = {
|
|
9
10
|
config?: ClawdbotConfig;
|
|
@@ -15,17 +16,19 @@ export type MonitorDcgchatOpts = {
|
|
|
15
16
|
const RECONNECT_DELAY_MS = 3000;
|
|
16
17
|
const HEARTBEAT_INTERVAL_MS = 30_000;
|
|
17
18
|
|
|
18
|
-
function buildConnectUrl(
|
|
19
|
+
function buildConnectUrl(account: Record<string, string>): string {
|
|
20
|
+
const { wsUrl, botToken, userId, domainId, appId } = account;
|
|
19
21
|
const url = new URL(wsUrl);
|
|
20
22
|
if (botToken) url.searchParams.set("bot_token", botToken);
|
|
21
23
|
if (userId) url.searchParams.set("_userId", userId);
|
|
22
|
-
url.searchParams.set("_domainId", "1000");
|
|
23
|
-
url.searchParams.set("_appId", "100");
|
|
24
|
+
url.searchParams.set("_domainId", domainId || "1000");
|
|
25
|
+
url.searchParams.set("_appId", appId || "100");
|
|
24
26
|
return url.toString();
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
export async function monitorDcgchatProvider(opts: MonitorDcgchatOpts): Promise<void> {
|
|
28
30
|
const { config, runtime, abortSignal, accountId } = opts;
|
|
31
|
+
// @ts-ignore
|
|
29
32
|
const cfg = config ?? (runtime?.config?.() as ClawdbotConfig | undefined);
|
|
30
33
|
if (!cfg) {
|
|
31
34
|
runtime?.error?.("dcgchat: no config available");
|
|
@@ -74,7 +77,7 @@ export async function monitorDcgchatProvider(opts: MonitorDcgchatOpts): Promise<
|
|
|
74
77
|
const connect = () => {
|
|
75
78
|
if (!shouldReconnect) return;
|
|
76
79
|
|
|
77
|
-
const connectUrl = buildConnectUrl(account
|
|
80
|
+
const connectUrl = buildConnectUrl(account as Record<string, any>);
|
|
78
81
|
log(`dcgchat[${account.accountId}]: connecting to ${connectUrl}`);
|
|
79
82
|
ws = new WebSocket(connectUrl);
|
|
80
83
|
|
|
@@ -107,6 +110,12 @@ export async function monitorDcgchatProvider(opts: MonitorDcgchatOpts): Promise<
|
|
|
107
110
|
parsed.content = JSON.parse(parsed.content);
|
|
108
111
|
|
|
109
112
|
const msg = parsed as unknown as InboundMessage;
|
|
113
|
+
setMsgParams({
|
|
114
|
+
userId: msg._userId,
|
|
115
|
+
token: msg.content.bot_token,
|
|
116
|
+
sessionId: msg.content.session_id,
|
|
117
|
+
messageId: msg.content.message_id,
|
|
118
|
+
});
|
|
110
119
|
await handleDcgchatMessage({
|
|
111
120
|
cfg,
|
|
112
121
|
msg,
|
package/src/tool.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
|
|
2
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
3
|
+
import { getWsConnection } from "./connection.js";
|
|
4
|
+
import { logDcgchat } from "./log.js";
|
|
5
|
+
|
|
6
|
+
let msgParams = {} as {
|
|
7
|
+
userId: number;
|
|
8
|
+
token: string
|
|
9
|
+
sessionId: string
|
|
10
|
+
messageId: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function setMsgParams(params: any) {
|
|
14
|
+
msgParams = params;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function getMsgParams() {
|
|
18
|
+
return msgParams;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function monitoringToolMessage(api: OpenClawPluginApi) {
|
|
22
|
+
api.on("after_tool_call", (event, payload) => {
|
|
23
|
+
const ws = getWsConnection()
|
|
24
|
+
const params = getMsgParams();
|
|
25
|
+
if (ws?.readyState === WebSocket.OPEN && params?.sessionId) {
|
|
26
|
+
ws.send(JSON.stringify({
|
|
27
|
+
messageType: "openclaw_bot_chat",
|
|
28
|
+
_userId: params?.userId,
|
|
29
|
+
source: "client",
|
|
30
|
+
content: {
|
|
31
|
+
bot_token: params?.token,
|
|
32
|
+
response: 'all_finished',
|
|
33
|
+
session_id:params?.sessionId,
|
|
34
|
+
message_id: params?.messageId || Date.now().toString()
|
|
35
|
+
},
|
|
36
|
+
}));
|
|
37
|
+
ws.send(JSON.stringify({
|
|
38
|
+
messageType: "openclaw_bot_chat",
|
|
39
|
+
_userId: params?.userId,
|
|
40
|
+
source: "client",
|
|
41
|
+
content: {
|
|
42
|
+
bot_token: params?.token,
|
|
43
|
+
response: JSON.stringify({
|
|
44
|
+
type: 'tool_call',
|
|
45
|
+
...event
|
|
46
|
+
}),
|
|
47
|
+
session_id:params?.sessionId,
|
|
48
|
+
message_id: params?.messageId || Date.now().toString()
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
ws.send(JSON.stringify({
|
|
52
|
+
messageType: "openclaw_bot_chat",
|
|
53
|
+
_userId: params?.userId,
|
|
54
|
+
source: "client",
|
|
55
|
+
content: {
|
|
56
|
+
bot_token: params?.token,
|
|
57
|
+
response: 'all_finished',
|
|
58
|
+
session_id:params?.sessionId,
|
|
59
|
+
message_id: params?.messageId || Date.now().toString()
|
|
60
|
+
},
|
|
61
|
+
}));
|
|
62
|
+
logDcgchat.info(`dcgchat: tool message to ${params?.sessionId}, ${JSON.stringify(event)}`);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -9,6 +9,8 @@ export type DcgchatConfig = {
|
|
|
9
9
|
botToken?: string;
|
|
10
10
|
/** 用户标识 */
|
|
11
11
|
userId?: string;
|
|
12
|
+
domainId?: string;
|
|
13
|
+
appId?: string;
|
|
12
14
|
};
|
|
13
15
|
|
|
14
16
|
export type ResolvedDcgchatAccount = {
|
|
@@ -18,6 +20,8 @@ export type ResolvedDcgchatAccount = {
|
|
|
18
20
|
wsUrl: string;
|
|
19
21
|
botToken: string;
|
|
20
22
|
userId: string;
|
|
23
|
+
domainId?: string;
|
|
24
|
+
appId?: string;
|
|
21
25
|
};
|
|
22
26
|
|
|
23
27
|
/**
|