@dcrays/dcgchat 0.3.29 → 0.3.30

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcrays/dcgchat",
3
- "version": "0.3.29",
3
+ "version": "0.3.30",
4
4
  "type": "module",
5
5
  "description": "OpenClaw channel plugin for 书灵墨宝 (WebSocket)",
6
6
  "main": "index.ts",
@@ -42,4 +42,4 @@
42
42
  "defaultChoice": "npm"
43
43
  }
44
44
  }
45
- }
45
+ }
package/src/bot.ts CHANGED
@@ -166,7 +166,7 @@ export async function handleDcgchatMessage(msg: InboundMessage, accountId: strin
166
166
  const effectiveAgentId = embeddedAgentId ?? route.agentId
167
167
  const effectiveSessionKey = getSessionKey(msg.content, account.accountId)
168
168
 
169
- setParamsMessage(effectiveSessionKey, {
169
+ const mergedParams = {
170
170
  userId: msg._userId,
171
171
  botToken: msg.content.bot_token,
172
172
  sessionId: conversationId,
@@ -177,7 +177,11 @@ export async function handleDcgchatMessage(msg: InboundMessage, accountId: strin
177
177
  agentId: msg.content.agent_id ?? '',
178
178
  sessionKey: effectiveSessionKey,
179
179
  real_mobook
180
- })
180
+ }
181
+ setParamsMessage(effectiveSessionKey, mergedParams)
182
+ // 与 OpenClaw 会话投递里仍可能出现的 ctx.to=SenderId(userId)对齐,便于 getOutboundMsgParams 命中
183
+ console.log('🚀 ~ handleDcgchatMessage ~ mergedParams:', mergedParams)
184
+ setParamsMessage(userId, mergedParams)
181
185
  const outboundCtx = getEffectiveMsgParams(effectiveSessionKey)
182
186
  const agentEntry =
183
187
  effectiveAgentId && effectiveAgentId !== 'main' ? config.agents?.list?.find((a) => a.id === effectiveAgentId) : undefined
@@ -443,6 +447,13 @@ export async function handleDcgchatMessage(msg: InboundMessage, accountId: strin
443
447
  storePath,
444
448
  sessionKey: effectiveSessionKey,
445
449
  ctx: ctxPayload,
450
+ // 与 Telegram/Discord 等一致:写入 deliveryContext.to,否则投递可能回退为 From(userId),channel sendMedia 里 ctx.to 会变成数字 userId
451
+ updateLastRoute: {
452
+ sessionKey: effectiveSessionKey,
453
+ channel: "dcgchat",
454
+ to: effectiveSessionKey,
455
+ accountId: route.accountId
456
+ },
446
457
  onRecordError: (err) => {
447
458
  dcgLogger(` session record error: ${String(err)}`, 'error')
448
459
  }
package/src/channel.ts CHANGED
@@ -5,7 +5,7 @@ import { ossUpload } from './request/oss.js'
5
5
  import { addSentMediaKey, getCronMessageId, getOpenClawConfig, hasSentMediaKey } from './utils/global.js'
6
6
  import { isWsOpen, mergeDefaultParams, mergeSessionParams, sendFinal, wsSendRaw } from './transport.js'
7
7
  import { dcgLogger, setLogger } from './utils/log.js'
8
- import { getOutboundMsgParams } from './utils/params.js'
8
+ import { getOutboundMsgParams, getParamsMessage } from './utils/params.js'
9
9
  import { startDcgchatGatewaySocket } from './gateway/socket.js'
10
10
 
11
11
  export type DcgchatMediaSendOptions = {
@@ -101,11 +101,17 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
101
101
  enabled: { type: 'boolean' },
102
102
  wsUrl: { type: 'string' },
103
103
  botToken: { type: 'string' },
104
- userId: { type: 'string' },
104
+ userId: { type: 'string', description: 'WebSocket 连接参数 _userId,与 message 工具的 target(effectiveSessionKey)无关' },
105
105
  appId: { type: 'string' },
106
106
  domainId: { type: 'string' },
107
107
  capabilities: { type: 'array', items: { type: 'string' } }
108
108
  }
109
+ },
110
+ uiHints: {
111
+ userId: {
112
+ label: 'WS 连接 _userId',
113
+ help: '仅用于拼接网关 WebSocket URL 的查询参数,不是 Agent 发消息时的 target。发消息请使用 effectiveSessionKey(与入站上下文 SessionKey 相同,格式如 agent:main:mobook:direct:…)。'
114
+ }
109
115
  }
110
116
  },
111
117
  config: {
@@ -138,9 +144,15 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
138
144
  normalizeTarget: (raw) => raw?.trim() || undefined,
139
145
  targetResolver: {
140
146
  looksLikeId: (raw) => Boolean(raw?.trim()),
141
- hint: 'effectiveSessionKey'
147
+ hint: 'effectiveSessionKey(与 SessionKey 一致;勿填配置里的 WS userId)'
142
148
  }
143
149
  },
150
+ agentPrompt: {
151
+ messageToolHints: () => [
152
+ '书灵墨宝:message 工具的 target 必须填 effectiveSessionKey(与当前会话 SessionKey / OriginatingTo 相同),形如 agent:main:mobook:direct:<agent_id>:<session_id>;不要填 channels.dcgchat.userId 或纯数字 userId。',
153
+ 'OpenClaw 自带的 target 字段说明里仍可能出现 “user id”,在本频道请忽略该字样,一律按 effectiveSessionKey 理解。'
154
+ ]
155
+ },
144
156
  outbound: {
145
157
  deliveryMode: 'direct',
146
158
  textChunkLimit: 4000,
@@ -176,17 +188,29 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
176
188
  }
177
189
  },
178
190
  sendMedia: async (ctx) => {
191
+ const isCron = ctx.to.indexOf('dcg-cron:') >= 0
179
192
  const to = ctx.to.replace('dcg-cron:', '')
180
- const msgCtx = getOutboundMsgParams(to)
193
+ const outboundCtx = getOutboundMsgParams(to)
194
+ const msgCtx = getParamsMessage(to) ?? outboundCtx
181
195
  const cronMsgId = getCronMessageId(to)
182
- const isCron = ctx.to.indexOf('dcg-cron:') >= 0
183
- const messageId = !!cronMsgId ? cronMsgId : isCron ? `${Date.now()}` : msgCtx?.messageId
196
+ const fallbackMessageId = `${Date.now()}`
197
+ const messageId = cronMsgId || (isCron ? fallbackMessageId : msgCtx?.messageId || fallbackMessageId)
198
+
199
+ if (!outboundCtx?.sessionId) {
200
+ dcgLogger(`channel sendMedia to ${ctx.to} -> sessionId not found`, 'error')
201
+ return {
202
+ channel: "dcgchat",
203
+ messageId,
204
+ chatId: to || ''
205
+ }
206
+ }
207
+
184
208
  dcgLogger(`channel sendMedia to ${ctx.to}`)
185
- await sendDcgchatMedia({ sessionKey: to ?? '', mediaUrl: ctx.mediaUrl ?? '' })
209
+ await sendDcgchatMedia({ sessionKey: to || '', mediaUrl: ctx.mediaUrl || '' })
186
210
  return {
187
211
  channel: "dcgchat",
188
- messageId: `${messageId}`,
189
- chatId: to
212
+ messageId,
213
+ chatId: to || ''
190
214
  }
191
215
  }
192
216
  },