@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 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: channelInfo[ENV],
10
+ id: "dcgchat-test",
12
11
  name: '书灵墨宝',
13
12
  description: '连接 OpenClaw 与 书灵墨宝 产品(WebSocket)',
14
13
  configSchema: emptyPluginConfigSchema(),
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "id": "dcgchat-test",
3
- "channels": ["dcgchat-test"],
3
+ "channels": [
4
+ "dcgchat-test"
5
+ ],
4
6
  "configSchema": {
5
7
  "type": "object",
6
8
  "additionalProperties": false,
7
9
  "properties": {}
8
10
  }
9
- }
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcrays/dcgchat-test",
3
- "version": "0.4.26",
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: channelInfo[ENV],
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?.[channelInfo[ENV]]?.appId || 100,
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: channelInfo[ENV],
273
- Surface: channelInfo[ENV],
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: channelInfo[ENV],
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: channelInfo[ENV],
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: channelInfo[ENV],
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?.[channelInfo[ENV]] as DcgchatConfig | undefined) ?? {}
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?.[channelInfo[ENV]]?.botToken ?? ''
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?.[channelInfo[ENV]] as DcgchatConfig | undefined) ?? {}
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: channelInfo[ENV],
263
+ id: "dcgchat-test",
265
264
  meta: {
266
- id: channelInfo[ENV],
265
+ id: "dcgchat-test",
267
266
  label: '书灵墨宝',
268
267
  selectionLabel: '书灵墨宝',
269
268
  docsPath: '/channels/dcgchat',
270
- docsLabel: channelInfo[ENV],
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.${channelInfo[ENV]}`, 'channels.dcgchat'] },
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 = channelInfo[ENV]
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: channelInfo[ENV],
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: channelInfo[ENV],
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: channelInfo[ENV],
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: channelInfo[ENV],
446
+ channel: "dcgchat-test",
448
447
  messageId,
449
448
  chatId: outboundChatId(ctx.to, to || '')
450
449
  }
@@ -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 = 'dcgchat-test'
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 ${'dcgchat-test'} --to dcg-cron:${sk} --json`
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
@@ -1,9 +1,5 @@
1
1
  export const ENV: 'production' | 'test' | 'develop' = 'test'
2
2
 
3
- export const channelInfo: Record<string, string> = {
4
- production: 'dcgchat',
5
- test: 'dcgchat-test'
6
- }
7
3
 
8
4
  export const systemCommand = ['/new', '/status']
9
5
  export const stopCommand = ['/stop']
@@ -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?.[channelInfo[ENV]]?.appId == 110 ? '.mobook' : '.openclaw',
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
- `${channelInfo[ENV]} runtime not initialized`
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: channelInfo[ENV],
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()} [${channelInfo[ENV]}]: ${message}`)
13
+ console[type](`书灵墨宝🚀 ~ ${new Date().toISOString()} [${"dcgchat-test"}]: ${message}`)
15
14
  }
16
15
  }
@@ -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?.[channelInfo[ENV]] as DcgchatConfig | undefined) ?? {}
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
- - [ ] 错误消息类型