@dcrays/dcgchat 0.1.5 → 0.1.7
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 +26 -13
- package/src/monitor.ts +13 -4
- package/src/tool.ts +54 -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,10 +38,11 @@ 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,
|
|
41
|
-
|
|
44
|
+
effects: true,
|
|
45
|
+
// blockStreaming: true,
|
|
42
46
|
},
|
|
43
47
|
reload: { configPrefixes: ["channels.dcgchat"] },
|
|
44
48
|
configSchema: {
|
|
@@ -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: {
|
|
@@ -87,11 +95,12 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
87
95
|
},
|
|
88
96
|
outbound: {
|
|
89
97
|
deliveryMode: "direct",
|
|
90
|
-
textChunkLimit: 25,
|
|
98
|
+
// textChunkLimit: 25,
|
|
99
|
+
textChunkLimit: 4000,
|
|
91
100
|
sendText: async (ctx) => {
|
|
92
101
|
const target = ctx.to || "(implicit)";
|
|
93
|
-
logDcgchat.info(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> sendText ${target}: ${ctx.text}`);
|
|
94
102
|
const ws = getWsConnection()
|
|
103
|
+
const params = getMsgParams();
|
|
95
104
|
if (ws?.readyState === WebSocket.OPEN) {
|
|
96
105
|
const {botToken} = resolveAccount(ctx.cfg, ctx.accountId);
|
|
97
106
|
const content = {
|
|
@@ -101,12 +110,14 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
101
110
|
content: {
|
|
102
111
|
bot_token: botToken,
|
|
103
112
|
response: ctx.text,
|
|
104
|
-
session_id:
|
|
105
|
-
message_id: Date.now().toString(),
|
|
113
|
+
session_id: params.sessionId || Date.now().toString(),
|
|
114
|
+
message_id: params.messageId ||Date.now().toString(),
|
|
106
115
|
},
|
|
107
116
|
};
|
|
108
117
|
ws.send(JSON.stringify(content));
|
|
109
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}`);
|
|
110
121
|
}
|
|
111
122
|
return {
|
|
112
123
|
channel: "dcgchat",
|
|
@@ -116,8 +127,8 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
116
127
|
},
|
|
117
128
|
sendMedia: async (ctx) => {
|
|
118
129
|
const target = ctx.to || "(implicit)";
|
|
119
|
-
logDcgchat.info(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> sendMedia ${target}: ${ctx.text + ctx.mediaUrl}`);
|
|
120
130
|
const ws = getWsConnection()
|
|
131
|
+
const params = getMsgParams();
|
|
121
132
|
if (ws?.readyState === WebSocket.OPEN) {
|
|
122
133
|
const {botToken} = resolveAccount(ctx.cfg, ctx.accountId);
|
|
123
134
|
try {
|
|
@@ -130,12 +141,12 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
130
141
|
content: {
|
|
131
142
|
bot_token: botToken,
|
|
132
143
|
response: ctx.text + '\n' + `[${fileName}](${url})`,
|
|
133
|
-
session_id:
|
|
134
|
-
message_id: Date.now().toString(),
|
|
144
|
+
session_id: params.sessionId || Date.now().toString(),
|
|
145
|
+
message_id: params.messageId ||Date.now().toString(),
|
|
135
146
|
},
|
|
136
147
|
};
|
|
137
148
|
ws.send(JSON.stringify(content));
|
|
138
|
-
logDcgchat.info(`dcgchat[${ctx.accountId}]:
|
|
149
|
+
logDcgchat.info(`dcgchat[${ctx.accountId}]: sendMedia to ${target}, ${JSON.stringify(content)}`);
|
|
139
150
|
} catch (error) {
|
|
140
151
|
const content = {
|
|
141
152
|
messageType: "openclaw_bot_chat",
|
|
@@ -144,13 +155,15 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
144
155
|
content: {
|
|
145
156
|
bot_token: botToken,
|
|
146
157
|
response: ctx.text + '\n' + ctx.mediaUrl,
|
|
147
|
-
session_id:
|
|
148
|
-
message_id: Date.now().toString(),
|
|
158
|
+
session_id: params.sessionId || Date.now().toString(),
|
|
159
|
+
message_id: params.messageId ||Date.now().toString(),
|
|
149
160
|
},
|
|
150
161
|
};
|
|
151
162
|
ws.send(JSON.stringify(content));
|
|
152
|
-
logDcgchat.info(`dcgchat[${ctx.accountId}]:
|
|
163
|
+
logDcgchat.info(`dcgchat[${ctx.accountId}]: sendMedia to ${target}, ${JSON.stringify(content)}`);
|
|
153
164
|
}
|
|
165
|
+
} else {
|
|
166
|
+
logDcgchat.warn(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> ${ws?.readyState}: ${ctx.text}`);
|
|
154
167
|
}
|
|
155
168
|
return {
|
|
156
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,54 @@
|
|
|
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: JSON.stringify({
|
|
33
|
+
type: 'tool_call',
|
|
34
|
+
...event
|
|
35
|
+
}),
|
|
36
|
+
session_id:params?.sessionId,
|
|
37
|
+
message_id: params?.messageId || Date.now().toString()
|
|
38
|
+
},
|
|
39
|
+
}));
|
|
40
|
+
ws.send(JSON.stringify({
|
|
41
|
+
messageType: "openclaw_bot_chat",
|
|
42
|
+
_userId: params?.userId,
|
|
43
|
+
source: "client",
|
|
44
|
+
content: {
|
|
45
|
+
bot_token: params?.token,
|
|
46
|
+
response: 'all_finished',
|
|
47
|
+
session_id:params?.sessionId,
|
|
48
|
+
message_id: params?.messageId || Date.now().toString()
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
logDcgchat.info(`dcgchat: tool message to ${params?.sessionId}, ${JSON.stringify(event)}`);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
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
|
/**
|