@dcrays/dcgchat-test 0.4.26 → 0.4.27
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 +1 -2
- package/openclaw.plugin.json +4 -2
- package/package.json +3 -13
- package/src/bot.ts +7 -7
- package/src/channel.ts +12 -13
- package/src/cronToolCall.ts +2 -2
- package/src/utils/constant.ts +0 -4
- package/src/utils/global.ts +3 -3
- package/src/utils/log.ts +1 -2
- package/src/utils/params.ts +1 -1
- package/README.md +0 -83
package/index.ts
CHANGED
|
@@ -3,12 +3,11 @@ import { emptyPluginConfigSchema } from 'openclaw/plugin-sdk'
|
|
|
3
3
|
import { dcgchatPlugin } from './src/channel.js'
|
|
4
4
|
import { setDcgchatRuntime, setWorkspaceDir } from './src/utils/global.js'
|
|
5
5
|
import { monitoringToolMessage } from './src/tool.js'
|
|
6
|
-
import { channelInfo, ENV } from './src/utils/constant.js'
|
|
7
6
|
import { setOpenClawConfig } from './src/utils/global.js'
|
|
8
7
|
import { createDcgchatMessageTool } from './src/tools/messageTool.js'
|
|
9
8
|
|
|
10
9
|
const plugin = {
|
|
11
|
-
id:
|
|
10
|
+
id: "dcgchat-test",
|
|
12
11
|
name: '书灵墨宝',
|
|
13
12
|
description: '连接 OpenClaw 与 书灵墨宝 产品(WebSocket)',
|
|
14
13
|
configSchema: emptyPluginConfigSchema(),
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcrays/dcgchat-test",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.27",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenClaw channel plugin for 书灵墨宝 (WebSocket)",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -16,12 +16,6 @@
|
|
|
16
16
|
"websocket",
|
|
17
17
|
"ai"
|
|
18
18
|
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"typecheck": "tsc --noEmit",
|
|
21
|
-
"build:production": "npx tsx scripts/build.ts production",
|
|
22
|
-
"build:prod": "npx tsx scripts/build.ts production",
|
|
23
|
-
"build:test": "npx tsx scripts/build.ts test"
|
|
24
|
-
},
|
|
25
19
|
"dependencies": {
|
|
26
20
|
"ali-oss": "file:src/libs/ali-oss-6.23.0.tgz",
|
|
27
21
|
"axios": "file:src/libs/axios-1.13.6.tgz",
|
|
@@ -37,19 +31,15 @@
|
|
|
37
31
|
"id": "dcgchat-test",
|
|
38
32
|
"label": "书灵墨宝",
|
|
39
33
|
"selectionLabel": "书灵墨宝",
|
|
40
|
-
"docsPath": "/channels/dcgchat",
|
|
34
|
+
"docsPath": "/channels/dcgchat-test",
|
|
41
35
|
"docsLabel": "dcgchat-test",
|
|
42
36
|
"blurb": "连接 OpenClaw 与 书灵墨宝 产品",
|
|
43
37
|
"order": 80
|
|
44
38
|
},
|
|
45
39
|
"install": {
|
|
46
40
|
"npmSpec": "@dcrays/dcgchat-test",
|
|
47
|
-
"localPath": "extensions/dcgchat",
|
|
41
|
+
"localPath": "extensions/dcgchat-test",
|
|
48
42
|
"defaultChoice": "npm"
|
|
49
43
|
}
|
|
50
|
-
},
|
|
51
|
-
"devDependencies": {
|
|
52
|
-
"openclaw": "^2026.3.13",
|
|
53
|
-
"typescript": "~5.8.0"
|
|
54
44
|
}
|
|
55
45
|
}
|
package/src/bot.ts
CHANGED
|
@@ -190,7 +190,7 @@ async function handleDcgchatMessageInboundTurn(msg: InboundMessage, accountId: s
|
|
|
190
190
|
|
|
191
191
|
const route = core.channel.routing.resolveAgentRoute({
|
|
192
192
|
cfg: config,
|
|
193
|
-
channel:
|
|
193
|
+
channel: "dcgchat-test",
|
|
194
194
|
accountId: account.accountId,
|
|
195
195
|
peer: { kind: 'direct', id: conversationId }
|
|
196
196
|
})
|
|
@@ -207,7 +207,7 @@ async function handleDcgchatMessageInboundTurn(msg: InboundMessage, accountId: s
|
|
|
207
207
|
sessionId: conversationId,
|
|
208
208
|
messageId: msg.content.message_id,
|
|
209
209
|
domainId: msg.content.domain_id,
|
|
210
|
-
appId: config.channels?.[
|
|
210
|
+
appId: config.channels?.["dcgchat-test"]?.appId || 100,
|
|
211
211
|
botId: msg.content.bot_id ?? '',
|
|
212
212
|
agentId: msg.content.agent_id ?? '',
|
|
213
213
|
sessionKey: dcgSessionKey,
|
|
@@ -269,13 +269,13 @@ async function handleDcgchatMessageInboundTurn(msg: InboundMessage, accountId: s
|
|
|
269
269
|
ChatType: 'direct',
|
|
270
270
|
SenderName: agentDisplayName,
|
|
271
271
|
SenderId: userId,
|
|
272
|
-
Provider:
|
|
273
|
-
Surface:
|
|
272
|
+
Provider: "dcgchat-test",
|
|
273
|
+
Surface: "dcgchat-test",
|
|
274
274
|
MessageSid: msg.content.message_id,
|
|
275
275
|
Timestamp: Date.now(),
|
|
276
276
|
WasMentioned: true,
|
|
277
277
|
CommandAuthorized: true,
|
|
278
|
-
OriginatingChannel:
|
|
278
|
+
OriginatingChannel: "dcgchat-test",
|
|
279
279
|
OriginatingTo: dcgSessionKey,
|
|
280
280
|
Target: dcgSessionKey,
|
|
281
281
|
SourceTarget: dcgSessionKey,
|
|
@@ -298,7 +298,7 @@ async function handleDcgchatMessageInboundTurn(msg: InboundMessage, accountId: s
|
|
|
298
298
|
const prefixContext = createReplyPrefixContext({
|
|
299
299
|
cfg: config,
|
|
300
300
|
agentId: effectiveAgentId ?? '',
|
|
301
|
-
channel:
|
|
301
|
+
channel: "dcgchat-test",
|
|
302
302
|
accountId: account.accountId
|
|
303
303
|
})
|
|
304
304
|
|
|
@@ -479,7 +479,7 @@ async function handleDcgchatMessageInboundTurn(msg: InboundMessage, accountId: s
|
|
|
479
479
|
ctx: ctxPayload,
|
|
480
480
|
updateLastRoute: {
|
|
481
481
|
sessionKey: dcgSessionKey,
|
|
482
|
-
channel:
|
|
482
|
+
channel: "dcgchat-test",
|
|
483
483
|
to: dcgSessionKey,
|
|
484
484
|
accountId: route.accountId
|
|
485
485
|
},
|
package/src/channel.ts
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
setCronMessageId
|
|
14
14
|
} from './utils/global.js'
|
|
15
15
|
import { isWsOpen, mergeDefaultParams, mergeSessionParams, sendFinal, wsSendRaw } from './transport.js'
|
|
16
|
-
import { channelInfo, ENV } from './utils/constant.js'
|
|
17
16
|
import { dcgLogger, setLogger } from './utils/log.js'
|
|
18
17
|
import { getOutboundMsgParams, getParamsMessage } from './utils/params.js'
|
|
19
18
|
import { isSessionActiveForTool } from './tool.js'
|
|
@@ -21,7 +20,7 @@ import { startDcgchatGatewaySocket } from './gateway/socket.js'
|
|
|
21
20
|
import { getCronJobsPath, readCronJob } from './cron.js'
|
|
22
21
|
|
|
23
22
|
function dcgchatChannelCfg(): DcgchatConfig {
|
|
24
|
-
return (getOpenClawConfig()?.channels?.[
|
|
23
|
+
return (getOpenClawConfig()?.channels?.["dcgchat-test"] as DcgchatConfig | undefined) ?? {}
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
/** `agent:<code>:mobook:direct:<agentId>:<sessionId>`(与 getSessionKey 非 real_mobook 分支一致) */
|
|
@@ -222,7 +221,7 @@ export async function sendDcgchatMedia(opts: DcgchatMediaSendOptions): Promise<v
|
|
|
222
221
|
const fileName = mediaUrl?.split(/[\\/]/).pop() || ''
|
|
223
222
|
const notMessageId = `${msgCtx?.messageId}`?.length === 13 || !msgCtx?.messageId
|
|
224
223
|
try {
|
|
225
|
-
const botToken = msgCtx.botToken ?? getOpenClawConfig()?.channels?.[
|
|
224
|
+
const botToken = msgCtx.botToken ?? getOpenClawConfig()?.channels?.["dcgchat-test"]?.botToken ?? ''
|
|
226
225
|
const url = opts.mediaUrl ? await ossUpload(opts.mediaUrl, botToken, 1) : ''
|
|
227
226
|
if (!msgCtx.agentId) {
|
|
228
227
|
msgCtx.agentId = agentId
|
|
@@ -247,7 +246,7 @@ export async function sendDcgchatMedia(opts: DcgchatMediaSendOptions): Promise<v
|
|
|
247
246
|
|
|
248
247
|
export function resolveAccount(cfg: OpenClawConfig, accountId?: string | null): ResolvedDcgchatAccount {
|
|
249
248
|
const id = accountId ?? DEFAULT_ACCOUNT_ID
|
|
250
|
-
const raw = (cfg.channels?.[
|
|
249
|
+
const raw = (cfg.channels?.["dcgchat-test"] as DcgchatConfig | undefined) ?? {}
|
|
251
250
|
return {
|
|
252
251
|
accountId: id,
|
|
253
252
|
enabled: raw.enabled !== false,
|
|
@@ -261,13 +260,13 @@ export function resolveAccount(cfg: OpenClawConfig, accountId?: string | null):
|
|
|
261
260
|
}
|
|
262
261
|
|
|
263
262
|
export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
264
|
-
id:
|
|
263
|
+
id: "dcgchat-test",
|
|
265
264
|
meta: {
|
|
266
|
-
id:
|
|
265
|
+
id: "dcgchat-test",
|
|
267
266
|
label: '书灵墨宝',
|
|
268
267
|
selectionLabel: '书灵墨宝',
|
|
269
268
|
docsPath: '/channels/dcgchat',
|
|
270
|
-
docsLabel:
|
|
269
|
+
docsLabel: "dcgchat-test",
|
|
271
270
|
blurb: '连接 OpenClaw 与 书灵墨宝 产品',
|
|
272
271
|
order: 80
|
|
273
272
|
},
|
|
@@ -284,7 +283,7 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
284
283
|
// blockStreaming: true,
|
|
285
284
|
},
|
|
286
285
|
/** 当前构建的 channel id + 兼容旧配置键 `channels.dcgchat` */
|
|
287
|
-
reload: { configPrefixes: [`channels.${
|
|
286
|
+
reload: { configPrefixes: [`channels.${"dcgchat-test"}`, 'channels.dcgchat'] },
|
|
288
287
|
configSchema: {
|
|
289
288
|
schema: {
|
|
290
289
|
type: 'object',
|
|
@@ -320,7 +319,7 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
320
319
|
resolveAccount: (cfg, accountId) => resolveAccount(cfg, accountId),
|
|
321
320
|
defaultAccountId: () => DEFAULT_ACCOUNT_ID,
|
|
322
321
|
setAccountEnabled: ({ cfg, enabled }) => {
|
|
323
|
-
const channelKey =
|
|
322
|
+
const channelKey = "dcgchat-test"
|
|
324
323
|
const prev = (cfg.channels?.[channelKey as keyof NonNullable<typeof cfg.channels>] as Record<string, unknown> | undefined) ?? {}
|
|
325
324
|
return {
|
|
326
325
|
...cfg,
|
|
@@ -392,7 +391,7 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
392
391
|
if (!isSessionActiveForTool(to)) {
|
|
393
392
|
dcgLogger(`channel sendText dropped (session not active): to=${to}`)
|
|
394
393
|
return {
|
|
395
|
-
channel:
|
|
394
|
+
channel: "dcgchat-test",
|
|
396
395
|
messageId: '',
|
|
397
396
|
chatId: outboundChatId(ctx.to, to)
|
|
398
397
|
}
|
|
@@ -404,7 +403,7 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
404
403
|
}
|
|
405
404
|
}
|
|
406
405
|
return {
|
|
407
|
-
channel:
|
|
406
|
+
channel: "dcgchat-test",
|
|
408
407
|
messageId: `${messageId}`,
|
|
409
408
|
chatId: outboundChatId(ctx.to, to)
|
|
410
409
|
}
|
|
@@ -425,7 +424,7 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
425
424
|
if (!sessionId) {
|
|
426
425
|
dcgLogger(`channel sendMedia to ${ctx.to} -> sessionId not found`, 'error')
|
|
427
426
|
return {
|
|
428
|
-
channel:
|
|
427
|
+
channel: "dcgchat-test",
|
|
429
428
|
messageId,
|
|
430
429
|
chatId: outboundChatId(ctx.to, to || '')
|
|
431
430
|
}
|
|
@@ -444,7 +443,7 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
|
|
|
444
443
|
})
|
|
445
444
|
}
|
|
446
445
|
return {
|
|
447
|
-
channel:
|
|
446
|
+
channel: "dcgchat-test",
|
|
448
447
|
messageId,
|
|
449
448
|
chatId: outboundChatId(ctx.to, to || '')
|
|
450
449
|
}
|
package/src/cronToolCall.ts
CHANGED
|
@@ -137,7 +137,7 @@ function patchCronDeliveryInParams(
|
|
|
137
137
|
if (agentId) d.accountId = agentId
|
|
138
138
|
if (announceNoChannel) {
|
|
139
139
|
d.bestEffort = true
|
|
140
|
-
d.channel =
|
|
140
|
+
d.channel = "dcgchat-test"
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -191,7 +191,7 @@ export function cronToolCall(event: { toolName: any; params: any; toolCallId: an
|
|
|
191
191
|
if (params.command.indexOf('cron create') > -1 || params.command.indexOf('cron add') > -1) {
|
|
192
192
|
const newParams = JSON.parse(JSON.stringify(params)) as Record<string, unknown>
|
|
193
193
|
newParams.command =
|
|
194
|
-
params.command.replace('--json', '') + ` --session-key ${sk} --channel ${
|
|
194
|
+
params.command.replace('--json', '') + ` --session-key ${sk} --channel ${"dcgchat-test"} --to dcg-cron:${sk} --json`
|
|
195
195
|
return { params: newParams }
|
|
196
196
|
} else {
|
|
197
197
|
return undefined
|
package/src/utils/constant.ts
CHANGED
package/src/utils/global.ts
CHANGED
|
@@ -30,7 +30,7 @@ export function getOpenClawConfig(): OpenClawConfig | null {
|
|
|
30
30
|
function getWorkspacePath(): string | null {
|
|
31
31
|
const workspacePath = path.join(
|
|
32
32
|
os.homedir(),
|
|
33
|
-
config?.channels?.[
|
|
33
|
+
config?.channels?.["dcgchat-test"]?.appId == 110 ? '.mobook' : '.openclaw',
|
|
34
34
|
'workspace'
|
|
35
35
|
)
|
|
36
36
|
if (fs.existsSync(workspacePath)) {
|
|
@@ -55,7 +55,7 @@ export function getWorkspaceDir(): string {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
const { setRuntime: setDcgchatRuntime, getRuntime: getDcgchatRuntime } = createPluginRuntimeStore<PluginRuntime>(
|
|
58
|
-
`${
|
|
58
|
+
`${"dcgchat-test"} runtime not initialized`
|
|
59
59
|
)
|
|
60
60
|
export { setDcgchatRuntime, getDcgchatRuntime }
|
|
61
61
|
|
|
@@ -147,7 +147,7 @@ export const getSessionKey = (content: any, accountId: string) => {
|
|
|
147
147
|
|
|
148
148
|
const route = core.channel.routing.resolveAgentRoute({
|
|
149
149
|
cfg: getOpenClawConfig() as OpenClawConfig,
|
|
150
|
-
channel:
|
|
150
|
+
channel: "dcgchat-test",
|
|
151
151
|
accountId: accountId || 'default',
|
|
152
152
|
peer: { kind: 'direct', id: session_id }
|
|
153
153
|
})
|
package/src/utils/log.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { RuntimeEnv } from 'openclaw/plugin-sdk'
|
|
2
|
-
import { channelInfo, ENV } from './constant.js'
|
|
3
2
|
|
|
4
3
|
let logger: RuntimeEnv | null = null
|
|
5
4
|
|
|
@@ -11,6 +10,6 @@ export function dcgLogger(message: string, type: 'log' | 'error' = 'log'): void
|
|
|
11
10
|
if (logger) {
|
|
12
11
|
logger[type](`书灵墨宝🚀 ~ [${new Date().toISOString()}] ${message}`)
|
|
13
12
|
} else {
|
|
14
|
-
console[type](`书灵墨宝🚀 ~ ${new Date().toISOString()} [${
|
|
13
|
+
console[type](`书灵墨宝🚀 ~ ${new Date().toISOString()} [${"dcgchat-test"}]: ${message}`)
|
|
15
14
|
}
|
|
16
15
|
}
|
package/src/utils/params.ts
CHANGED
|
@@ -9,7 +9,7 @@ const paramsMessageMap = new Map<string, IMsgParams>()
|
|
|
9
9
|
|
|
10
10
|
/** 从 OpenClaw 配置读取当前 channel 的基础参数(唯一来源,供 transport / resolve 等复用) */
|
|
11
11
|
export function getParamsDefaults(): IMsgParams {
|
|
12
|
-
const ch = (getOpenClawConfig()?.channels?.[
|
|
12
|
+
const ch = (getOpenClawConfig()?.channels?.["dcgchat-test"] as DcgchatConfig | undefined) ?? {}
|
|
13
13
|
return {
|
|
14
14
|
userId: Number(ch.userId ?? 0),
|
|
15
15
|
botToken: ch.botToken ?? '',
|
package/README.md
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# OpenClaw 书灵墨宝 插件
|
|
2
|
-
|
|
3
|
-
连接 OpenClaw 与 书灵墨宝 产品的通道插件。
|
|
4
|
-
|
|
5
|
-
## 架构
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
┌──────────┐ WebSocket ┌──────────────┐ WebSocket ┌─────────────────────┐
|
|
9
|
-
│ Web 前端 │ ←───────────────→ │ 公司后端服务 │ ←───────────────→ │ OpenClaw(工作电脑) │
|
|
10
|
-
└──────────┘ └──────────────┘ (OpenClaw 主动连) └─────────────────────┘
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
- OpenClaw 插件**主动连接**后端的 WebSocket 服务(不需要公网 IP)
|
|
14
|
-
- 后端收到用户消息后转发给 OpenClaw,OpenClaw 回复后发回后端
|
|
15
|
-
|
|
16
|
-
## 快速开始
|
|
17
|
-
|
|
18
|
-
### 1. 安装插件
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
pnpm openclaw plugins install -l /path/to/openclaw-dcgchat
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
### 2. 配置
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
openclaw config set channels.dcgchat.enabled true
|
|
28
|
-
openclaw config set channels.dcgchat.wsUrl "ws://your-backend:8080/openclaw/ws"
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### 3. 启动
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
pnpm openclaw gateway
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## 消息协议(MVP)
|
|
38
|
-
|
|
39
|
-
### 下行:后端 → OpenClaw(用户消息)
|
|
40
|
-
|
|
41
|
-
```json
|
|
42
|
-
{ "type": "message", "userId": "user_001", "text": "你好" }
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### 上行:OpenClaw → 后端(Agent 回复)
|
|
46
|
-
|
|
47
|
-
```json
|
|
48
|
-
{ "type": "reply", "userId": "user_001", "text": "你好!有什么可以帮你的?" }
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## 配置项
|
|
52
|
-
|
|
53
|
-
| 配置键 | 类型 | 说明 |
|
|
54
|
-
|--------|------|------|
|
|
55
|
-
| `channels.dcgchat.enabled` | boolean | 是否启用 |
|
|
56
|
-
| `channels.dcgchat.wsUrl` | string | 后端 WebSocket 地址 |
|
|
57
|
-
|
|
58
|
-
## 开发
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
# 安装依赖
|
|
62
|
-
pnpm install
|
|
63
|
-
|
|
64
|
-
# 类型检查
|
|
65
|
-
pnpm typecheck
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## 文件结构
|
|
69
|
-
|
|
70
|
-
- `index.ts` - 插件入口
|
|
71
|
-
- `src/channel.ts` - ChannelPlugin 定义
|
|
72
|
-
- `src/runtime.ts` - 插件 runtime
|
|
73
|
-
- `src/types.ts` - 类型定义
|
|
74
|
-
- `src/monitor.ts` - WebSocket 连接与断线重连
|
|
75
|
-
- `src/bot.ts` - 消息处理与 Agent 调用
|
|
76
|
-
|
|
77
|
-
## 后续迭代
|
|
78
|
-
|
|
79
|
-
- [ ] Token 认证
|
|
80
|
-
- [ ] 流式输出
|
|
81
|
-
- [ ] Typing 指示
|
|
82
|
-
- [ ] messageId 去重
|
|
83
|
-
- [ ] 错误消息类型
|