@dcrays/dcgchat 0.3.28 → 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 +2 -2
- package/src/bot.ts +13 -2
- package/src/channel.ts +35 -11
- package/src/utils/params.ts +2 -2
package/package.json
CHANGED
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
|
-
|
|
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 = {
|
|
@@ -43,14 +43,14 @@ export async function sendDcgchatMedia(opts: DcgchatMediaSendOptions): Promise<v
|
|
|
43
43
|
message_tags: { source: 'file' },
|
|
44
44
|
files: [{ url, name: fileName }]
|
|
45
45
|
})
|
|
46
|
-
dcgLogger(`dcgchat: sendMedia
|
|
46
|
+
dcgLogger(`dcgchat: sendMedia session=${opts.sessionKey}, file=${fileName}`)
|
|
47
47
|
} catch (error) {
|
|
48
48
|
wsSendRaw(msgCtx, {
|
|
49
49
|
response: opts.text ?? '',
|
|
50
50
|
message_tags: { source: 'file' },
|
|
51
51
|
files: [{ url: opts.mediaUrl ?? '', name: fileName }]
|
|
52
52
|
})
|
|
53
|
-
dcgLogger(`dcgchat: error sendMedia
|
|
53
|
+
dcgLogger(`dcgchat: error sendMedia session=${opts.sessionKey}: ${String(error)}`, 'error')
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -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: 'userId'
|
|
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
|
|
193
|
+
const outboundCtx = getOutboundMsgParams(to)
|
|
194
|
+
const msgCtx = getParamsMessage(to) ?? outboundCtx
|
|
181
195
|
const cronMsgId = getCronMessageId(to)
|
|
182
|
-
const
|
|
183
|
-
const 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
|
|
209
|
+
await sendDcgchatMedia({ sessionKey: to || '', mediaUrl: ctx.mediaUrl || '' })
|
|
186
210
|
return {
|
|
187
211
|
channel: "dcgchat",
|
|
188
|
-
messageId
|
|
189
|
-
chatId:
|
|
212
|
+
messageId,
|
|
213
|
+
chatId: to || ''
|
|
190
214
|
}
|
|
191
215
|
}
|
|
192
216
|
},
|
package/src/utils/params.ts
CHANGED
|
@@ -47,8 +47,8 @@ export function getEffectiveMsgParams(sessionKey?: string): IMsgParams {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* Agent `message`
|
|
51
|
-
* `
|
|
50
|
+
* Agent `message` 工具的 `target` 应为 `effectiveSessionKey`(如 `agent:main:mobook:direct:...`)。
|
|
51
|
+
* `setParamsMessage` 使用的 key 与此一致。若按 preferredKey 查不到 map,
|
|
52
52
|
* 则回落到当前会话 `currentSessionKey`,避免拿到空 `messageId` / `sessionId` 导致无文件卡片、WS 上下文错误。
|
|
53
53
|
*/
|
|
54
54
|
export function getOutboundMsgParams(preferredKey: string): IMsgParams {
|