@searchfe/openclaw-baiduapp 0.1.8-beta.1 → 0.1.8-beta.2

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/dist/index.js CHANGED
@@ -4534,15 +4534,18 @@ async function dispatchBaiduAppMessage(params) {
4534
4534
  await channel.reply.dispatchReplyWithBufferedBlockDispatcher({
4535
4535
  ctx: ctxPayload,
4536
4536
  cfg: safeCfg,
4537
+ replyOptions: {
4538
+ disableBlockStreaming: false
4539
+ },
4537
4540
  dispatcherOptions: {
4538
- deliver: async (payload) => {
4541
+ deliver: async (payload, info) => {
4539
4542
  const rawText = payload.text ?? "";
4540
4543
  if (!rawText.trim()) {
4541
4544
  logger3.debug("deliver callback: empty text, skipping");
4542
4545
  return;
4543
4546
  }
4544
4547
  const converted = channel.text?.convertMarkdownTables && tableMode ? channel.text.convertMarkdownTables(rawText, tableMode) : rawText;
4545
- logger3.debug(`deliver callback: textLen=${converted.length}`);
4548
+ logger3.debug(`deliver callback: kind=${info.kind} textLen=${converted.length}`);
4546
4549
  hooks.onChunk(converted);
4547
4550
  },
4548
4551
  onError: (err, info) => {
@@ -5126,11 +5129,6 @@ function tryGetBaiduAppRuntime() {
5126
5129
 
5127
5130
  // src/monitor.ts
5128
5131
  var webhookTargets = /* @__PURE__ */ new Map();
5129
- var streams = /* @__PURE__ */ new Map();
5130
- var msgidToStreamId = /* @__PURE__ */ new Map();
5131
- var STREAM_TTL_MS = 10 * 60 * 1e3;
5132
- var STREAM_MAX_BYTES = 512e3;
5133
- var MAX_MESSAGE_BYTES = 2048;
5134
5132
  var tempPruneInFlight = null;
5135
5133
  function normalizeWebhookPath(raw) {
5136
5134
  const trimmed = raw.trim();
@@ -5143,47 +5141,6 @@ function normalizeWebhookPath(raw) {
5143
5141
  }
5144
5142
  return withSlash;
5145
5143
  }
5146
- function pruneStreams() {
5147
- const cutoff = Date.now() - STREAM_TTL_MS;
5148
- for (const [id, state] of streams.entries()) {
5149
- if (state.updatedAt < cutoff) {
5150
- streams.delete(id);
5151
- }
5152
- }
5153
- for (const [msgid, id] of msgidToStreamId.entries()) {
5154
- if (!streams.has(id)) {
5155
- msgidToStreamId.delete(msgid);
5156
- }
5157
- }
5158
- }
5159
- function truncateUtf8Bytes(text, maxBytes) {
5160
- const buf = Buffer.from(text, "utf8");
5161
- if (buf.length <= maxBytes) {
5162
- return text;
5163
- }
5164
- const slice = buf.subarray(buf.length - maxBytes);
5165
- return slice.toString("utf8");
5166
- }
5167
- function splitMessageByBytes(text, maxBytes = MAX_MESSAGE_BYTES) {
5168
- const result = [];
5169
- let current = "";
5170
- let currentBytes = 0;
5171
- for (const char of text) {
5172
- const charBytes = Buffer.byteLength(char, "utf8");
5173
- if (currentBytes + charBytes > maxBytes && current.length > 0) {
5174
- result.push(current);
5175
- current = char;
5176
- currentBytes = charBytes;
5177
- } else {
5178
- current += char;
5179
- currentBytes += charBytes;
5180
- }
5181
- }
5182
- if (current.length > 0) {
5183
- result.push(current);
5184
- }
5185
- return result;
5186
- }
5187
5144
  function jsonOk(res, body) {
5188
5145
  res.statusCode = 200;
5189
5146
  res.setHeader("Content-Type", "application/json; charset=utf-8");
@@ -5276,93 +5233,6 @@ function resolvePath(req) {
5276
5233
  function resolveSignatureParam(params) {
5277
5234
  return params.get("msg_signature") ?? params.get("msgsignature") ?? params.get("signature") ?? "";
5278
5235
  }
5279
- function buildStreamPlaceholderReply(streamId) {
5280
- return {
5281
- msgtype: "stream",
5282
- stream: {
5283
- id: streamId,
5284
- finish: false,
5285
- content: "\u7A0D\u7B49~"
5286
- }
5287
- };
5288
- }
5289
- function buildStreamReplyFromState(state) {
5290
- const content = truncateUtf8Bytes(state.content, STREAM_MAX_BYTES);
5291
- return {
5292
- msgtype: "stream",
5293
- stream: {
5294
- id: state.streamId,
5295
- finish: state.finished,
5296
- content
5297
- }
5298
- };
5299
- }
5300
- function createStreamId() {
5301
- return crypto3.randomBytes(16).toString("hex");
5302
- }
5303
- function parseBaiduAppPlainMessage(raw) {
5304
- const trimmed = raw.trim();
5305
- if (trimmed.startsWith("<") && trimmed.endsWith(">")) {
5306
- const xmlData = parseXmlBody(trimmed);
5307
- return {
5308
- msgtype: xmlData.MsgType,
5309
- MsgType: xmlData.MsgType,
5310
- msgid: xmlData.MsgId,
5311
- MsgId: xmlData.MsgId,
5312
- content: xmlData.Content,
5313
- Content: xmlData.Content,
5314
- from: xmlData.FromUserName ? { appkey: xmlData.FromUserName } : void 0,
5315
- ToUserName: xmlData.ToUserName,
5316
- CreateTime: xmlData.CreateTime ? Number(xmlData.CreateTime) : void 0,
5317
- BotID: xmlData.BotID ? Number(xmlData.BotID) : void 0,
5318
- Event: xmlData.Event
5319
- };
5320
- }
5321
- try {
5322
- const parsed = JSON.parse(trimmed);
5323
- if (!parsed || typeof parsed !== "object") {
5324
- return {};
5325
- }
5326
- return parsed;
5327
- } catch {
5328
- return {};
5329
- }
5330
- }
5331
- function decryptBaiduAppCandidates(params) {
5332
- const results = [];
5333
- for (const candidate of params.candidates) {
5334
- if (!candidate.account.encodingAESKey) {
5335
- continue;
5336
- }
5337
- try {
5338
- const plaintext = decryptBaiduAppEncrypted({
5339
- encodingAESKey: candidate.account.encodingAESKey,
5340
- encrypt: params.encrypt
5341
- });
5342
- const msg = parseBaiduAppPlainMessage(plaintext);
5343
- results.push({ target: candidate, plaintext, msg });
5344
- } catch {
5345
- }
5346
- }
5347
- return results;
5348
- }
5349
- function selectDecryptedTarget(params) {
5350
- if (params.candidates.length === 1) {
5351
- return params.candidates[0];
5352
- }
5353
- const accountIds = params.candidates.map((candidate) => candidate.target.account.accountId).join(", ");
5354
- params.logger.warn(
5355
- `multiple openclaw-baiduapp accounts matched signature; using first match (accounts: ${accountIds})`
5356
- );
5357
- return params.candidates[0];
5358
- }
5359
- function appendStreamContent(state, nextText) {
5360
- const content = state.content ? `${state.content}
5361
-
5362
- ${nextText}`.trim() : nextText.trim();
5363
- state.content = truncateUtf8Bytes(content, STREAM_MAX_BYTES);
5364
- state.updatedAt = Date.now();
5365
- }
5366
5236
  function buildLogger(target) {
5367
5237
  return createLogger("openclaw-baiduapp", {
5368
5238
  log: target.runtime.log,
@@ -5429,6 +5299,62 @@ async function downloadInboundFiles(params) {
5429
5299
  }
5430
5300
  };
5431
5301
  }
5302
+ function parseBaiduAppPlainMessage(raw) {
5303
+ const trimmed = raw.trim();
5304
+ if (trimmed.startsWith("<") && trimmed.endsWith(">")) {
5305
+ const xmlData = parseXmlBody(trimmed);
5306
+ return {
5307
+ msgtype: xmlData.MsgType,
5308
+ MsgType: xmlData.MsgType,
5309
+ msgid: xmlData.MsgId,
5310
+ MsgId: xmlData.MsgId,
5311
+ content: xmlData.Content,
5312
+ Content: xmlData.Content,
5313
+ from: xmlData.FromUserName ? { appkey: xmlData.FromUserName } : void 0,
5314
+ ToUserName: xmlData.ToUserName,
5315
+ CreateTime: xmlData.CreateTime ? Number(xmlData.CreateTime) : void 0,
5316
+ BotID: xmlData.BotID ? Number(xmlData.BotID) : void 0,
5317
+ Event: xmlData.Event
5318
+ };
5319
+ }
5320
+ try {
5321
+ const parsed = JSON.parse(trimmed);
5322
+ if (!parsed || typeof parsed !== "object") {
5323
+ return {};
5324
+ }
5325
+ return parsed;
5326
+ } catch {
5327
+ return {};
5328
+ }
5329
+ }
5330
+ function decryptBaiduAppCandidates(params) {
5331
+ const results = [];
5332
+ for (const candidate of params.candidates) {
5333
+ if (!candidate.account.encodingAESKey) {
5334
+ continue;
5335
+ }
5336
+ try {
5337
+ const plaintext = decryptBaiduAppEncrypted({
5338
+ encodingAESKey: candidate.account.encodingAESKey,
5339
+ encrypt: params.encrypt
5340
+ });
5341
+ const msg = parseBaiduAppPlainMessage(plaintext);
5342
+ results.push({ target: candidate, plaintext, msg });
5343
+ } catch {
5344
+ }
5345
+ }
5346
+ return results;
5347
+ }
5348
+ function selectDecryptedTarget(params) {
5349
+ if (params.candidates.length === 1) {
5350
+ return params.candidates[0];
5351
+ }
5352
+ const accountIds = params.candidates.map((candidate) => candidate.target.account.accountId).join(", ");
5353
+ params.logger.warn(
5354
+ `multiple openclaw-baiduapp accounts matched signature; using first match (accounts: ${accountIds})`
5355
+ );
5356
+ return params.candidates[0];
5357
+ }
5432
5358
  async function processBaiduAppInboundMessage(params) {
5433
5359
  const { target, msg } = params;
5434
5360
  const logger3 = buildLogger(target);
@@ -5436,70 +5362,43 @@ async function processBaiduAppInboundMessage(params) {
5436
5362
  const msgtype = String(msg.msgtype ?? msg.MsgType ?? "").toLowerCase();
5437
5363
  const msgid = msg.msgid ?? msg.MsgId ? String(msg.msgid ?? msg.MsgId) : void 0;
5438
5364
  logger3.info(`inbound: type=${msgtype || "unknown"} msgid=${msgid ?? "none"} account=${target.account.accountId}`);
5439
- if (msgtype === "stream") {
5440
- const streamId2 = String(msg.stream?.id ?? "").trim();
5441
- const state = streamId2 ? streams.get(streamId2) : void 0;
5442
- logger3.info(
5443
- `[REPLY-MODE:STREAM-POLL] stream poll request: streamId=${streamId2 || "none"} found=${Boolean(state)} finished=${state?.finished ?? "n/a"} contentLen=${state?.content.length ?? 0}`
5444
- );
5445
- return state ? buildStreamReplyFromState(state) : buildStreamReplyFromState({
5446
- streamId: streamId2 || "unknown",
5447
- finished: true,
5448
- content: ""
5449
- });
5450
- }
5451
- if (msgid && msgidToStreamId.has(msgid)) {
5452
- const streamId2 = msgidToStreamId.get(msgid) ?? "";
5453
- logger3.debug(`duplicate msgid detected: msgid=${msgid} streamId=${streamId2}, returning placeholder`);
5454
- return buildStreamPlaceholderReply(streamId2);
5455
- }
5456
5365
  if (!canDispatchBaiduAppInboundMessage(msg)) {
5457
5366
  logger3.warn(`inbound message skipped: type=${msgtype || "unknown"} reason=no-dispatchable-content`);
5458
5367
  return {};
5459
5368
  }
5460
5369
  const inboundFileResult = msgtype === "text" ? await downloadInboundFiles({ msg, logger: logger3, runtime: target.runtime }) : { localFiles: [], diagnostic: {} };
5461
5370
  const inboundMediaFiles = inboundFileResult.localFiles;
5462
- const streamId = createStreamId();
5463
- if (msgid) {
5464
- msgidToStreamId.set(msgid, streamId);
5465
- }
5466
- streams.set(streamId, {
5467
- streamId,
5468
- msgid,
5469
- createdAt: Date.now(),
5470
- updatedAt: Date.now(),
5471
- started: false,
5472
- finished: false,
5473
- content: ""
5474
- });
5475
- logger3.info(`stream created: streamId=${streamId} msgid=${msgid ?? "none"}`);
5476
5371
  const core = tryGetBaiduAppRuntime();
5477
5372
  if (core) {
5478
- const state = streams.get(streamId);
5479
- if (state) {
5480
- state.started = true;
5481
- }
5482
- logger3.info(`agent dispatch started: streamId=${streamId} canSendActive=${target.account.canSendActive}`);
5373
+ logger3.info(`agent dispatch started: canSendActive=${target.account.canSendActive}`);
5374
+ let chunkKey = 0;
5483
5375
  const hooks = {
5484
5376
  onChunk: (text) => {
5485
- const current = streams.get(streamId);
5486
- if (!current) {
5487
- return;
5488
- }
5489
- appendStreamContent(current, text);
5377
+ const currentChunkKey = chunkKey++;
5490
5378
  logger3.debug(
5491
- `chunk received: streamId=${streamId} chunkLen=${text.length} totalLen=${current.content.length}`
5379
+ `chunk received: chunkKey=${currentChunkKey} chunkLen=${text.length}`
5492
5380
  );
5493
5381
  target.statusSink?.({ lastOutboundAt: Date.now() });
5382
+ if (target.account.canSendActive) {
5383
+ sendBaiduAppMessage(target.account, text, {
5384
+ msgid,
5385
+ chunkKey: currentChunkKey
5386
+ }).then((result) => {
5387
+ if (!result.ok) {
5388
+ logger3.error(
5389
+ `chunk send failed: chunkKey=${currentChunkKey} error=${result.errmsg ?? "unknown"}`
5390
+ );
5391
+ } else {
5392
+ logger3.debug(`chunk sent: chunkKey=${currentChunkKey}`);
5393
+ }
5394
+ }).catch((err) => {
5395
+ logger3.error(
5396
+ `chunk send error: chunkKey=${currentChunkKey} error=${String(err)}`
5397
+ );
5398
+ });
5399
+ }
5494
5400
  },
5495
5401
  onError: (err) => {
5496
- const current = streams.get(streamId);
5497
- if (current) {
5498
- current.error = err instanceof Error ? err.message : String(err);
5499
- current.content = current.content || `Error: ${current.error}`;
5500
- current.finished = true;
5501
- current.updatedAt = Date.now();
5502
- }
5503
5402
  logger3.error(`openclaw-baiduapp agent failed: ${String(err)}`);
5504
5403
  }
5505
5404
  };
@@ -5513,65 +5412,15 @@ async function processBaiduAppInboundMessage(params) {
5513
5412
  inboundFileDiagnostic: inboundFileResult.diagnostic,
5514
5413
  log: target.runtime.log,
5515
5414
  error: target.runtime.error
5516
- }).then(async () => {
5517
- const current = streams.get(streamId);
5518
- if (current) {
5519
- current.finished = true;
5520
- current.updatedAt = Date.now();
5521
- const contentLen = current.content.trim().length;
5522
- logger3.info(
5523
- `agent dispatch done: streamId=${streamId} contentLen=${contentLen} canSendActive=${target.account.canSendActive}`
5524
- );
5525
- if (!target.account.canSendActive) {
5526
- logger3.warn(
5527
- `active send skipped: appKey/appSecret not configured for account ${target.account.accountId}`
5528
- );
5529
- } else if (!contentLen) {
5530
- logger3.warn(`active send skipped: agent produced no content`);
5531
- }
5532
- if (target.account.canSendActive && current.content.trim()) {
5533
- try {
5534
- const chunks = splitMessageByBytes(current.content, MAX_MESSAGE_BYTES);
5535
- logger3.info(
5536
- `[REPLY-MODE:ACTIVE-SEND] active send starting: streamId=${streamId} chunks=${chunks.length} contentLen=${contentLen}`
5537
- );
5538
- for (let i = 0; i < chunks.length; i++) {
5539
- await sendBaiduAppMessage(target.account, chunks[i], {
5540
- msgid,
5541
- streamId,
5542
- chunkKey: i
5543
- });
5544
- logger3.debug(`active send chunk ${i + 1}/${chunks.length} sent: streamId=${streamId}`);
5545
- }
5546
- logger3.info(
5547
- `[REPLY-MODE:ACTIVE-SEND] active send complete: streamId=${streamId} chunks=${chunks.length}`
5548
- );
5549
- } catch (err) {
5550
- logger3.error(`active send failed: streamId=${streamId} error=${String(err)}`);
5551
- }
5552
- }
5553
- }
5415
+ }).then(() => {
5416
+ logger3.info(`agent dispatch done: totalChunks=${chunkKey}`);
5554
5417
  }).catch((err) => {
5555
- const current = streams.get(streamId);
5556
- if (current) {
5557
- current.error = err instanceof Error ? err.message : String(err);
5558
- current.content = current.content || `Error: ${current.error}`;
5559
- current.finished = true;
5560
- current.updatedAt = Date.now();
5561
- }
5562
- logger3.error(`agent dispatch failed: streamId=${streamId} error=${String(err)}`);
5418
+ logger3.error(`agent dispatch failed: error=${String(err)}`);
5563
5419
  });
5564
5420
  } else {
5565
- logger3.warn(`runtime not available: streamId=${streamId} \u2014 agent dispatch skipped, no reply will be generated`);
5566
- const state = streams.get(streamId);
5567
- if (state) {
5568
- state.finished = true;
5569
- state.updatedAt = Date.now();
5570
- }
5421
+ logger3.warn(`runtime not available \u2014 agent dispatch skipped, no reply will be generated`);
5571
5422
  }
5572
- const placeholderReply = buildStreamPlaceholderReply(streamId);
5573
- logger3.debug(`stream placeholder reply sent: streamId=${streamId}`);
5574
- return placeholderReply;
5423
+ return {};
5575
5424
  }
5576
5425
  function registerBaiduAppWebhookTarget(target) {
5577
5426
  const key = normalizeWebhookPath(target.path);
@@ -5589,7 +5438,6 @@ function registerBaiduAppWebhookTarget(target) {
5589
5438
  };
5590
5439
  }
5591
5440
  async function handleBaiduAppWebhookRequest(req, res) {
5592
- pruneStreams();
5593
5441
  const path4 = resolvePath(req);
5594
5442
  const targets = webhookTargets.get(path4);
5595
5443
  if (!targets || targets.length === 0) {
@@ -6509,6 +6357,15 @@ var plugin = {
6509
6357
  } else if (api.registerHttpHandler) {
6510
6358
  api.registerHttpHandler(handleBaiduAppWebhookRequest);
6511
6359
  }
6360
+ const typedApi = api;
6361
+ if (typeof typedApi.on === "function") {
6362
+ typedApi.on("before_tool_call", (event) => {
6363
+ console.log(`[openclaw-baiduapp] before_tool_call raw:`, JSON.stringify(event));
6364
+ });
6365
+ typedApi.on("after_tool_call", (event) => {
6366
+ console.log(`[openclaw-baiduapp] after_tool_call raw:`, JSON.stringify(event));
6367
+ });
6368
+ }
6512
6369
  }
6513
6370
  };
6514
6371
  var index_default = plugin;