openclaw-lark-multi-agent 1.4.5 → 1.4.6

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.
@@ -88,6 +88,9 @@ export declare class OpenClawClient {
88
88
  private extractVisibleAssistantText;
89
89
  private isVerboseTranscriptEnabled;
90
90
  private clearVerboseAssistantState;
91
+ /** Render protocol-4 structured tool args/results without `[object Object]`.
92
+ * Prefer useful, non-secret fields and keep the fallback bounded. */
93
+ private formatToolValue;
91
94
  private claimToolEvent;
92
95
  private pruneVerboseCaches;
93
96
  private flushVerboseAssistantState;
@@ -312,11 +312,13 @@ export class OpenClawClient {
312
312
  if (this.claimToolEvent(rawKey, eventId, phase)) {
313
313
  const meta = data.meta || data.input || data.args || "";
314
314
  const output = data.output || data.result || data.error || "";
315
+ const inputText = this.formatToolValue(meta, String(data.name), "start");
316
+ const outputText = this.formatToolValue(output, String(data.name), phase);
315
317
  if (toolCb)
316
- toolCb(`${data.name} ${phase}`.trim(), String(meta || ""), String(output || ""));
318
+ toolCb(`${data.name} ${phase}`.trim(), inputText, outputText);
317
319
  const progressCb = this.progressCallbacks.get(rawKey) || this.progressCallbacks.get(shortKey);
318
320
  if (progressCb) {
319
- const detail = phase === "start" ? String(meta || "") : String(output || meta || "");
321
+ const detail = phase === "start" ? inputText : (outputText || inputText);
320
322
  void progressCb({ kind: "tool", phase, name: String(data.name), text: `${data.name} ${phase}${detail ? `: ${detail}` : ""}` });
321
323
  }
322
324
  }
@@ -343,12 +345,14 @@ export class OpenClawClient {
343
345
  }
344
346
  const input = data.input || data.args || data.meta || "";
345
347
  const output = data.output || data.result || data.error || "";
348
+ const inputText = this.formatToolValue(input, name, "start");
349
+ const outputText = this.formatToolValue(output, name, phase);
346
350
  const toolCb = this.toolEventCallbacks.get(rawKey) || this.toolEventCallbacks.get(shortKey);
347
351
  if (toolCb)
348
- toolCb(`${name} ${phase}`, String(input || ""), String(output || ""));
352
+ toolCb(`${name} ${phase}`, inputText, outputText);
349
353
  const progressCb = this.progressCallbacks.get(rawKey) || this.progressCallbacks.get(shortKey);
350
354
  if (progressCb) {
351
- const detail = phase === "start" ? String(input || "") : String(output || input || "");
355
+ const detail = phase === "start" ? inputText : (outputText || inputText);
352
356
  void progressCb({ kind: "tool", phase, name, text: `${name} ${phase}${detail ? `: ${detail}` : ""}` });
353
357
  }
354
358
  }
@@ -451,6 +455,75 @@ export class OpenClawClient {
451
455
  this.verboseAssistantLastTouched.delete(key);
452
456
  }
453
457
  }
458
+ /** Render protocol-4 structured tool args/results without `[object Object]`.
459
+ * Prefer useful, non-secret fields and keep the fallback bounded. */
460
+ formatToolValue(value, toolName, phase) {
461
+ if (value === null || value === undefined || value === "")
462
+ return "";
463
+ if (typeof value === "string")
464
+ return value.trim();
465
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint")
466
+ return String(value);
467
+ if (Array.isArray(value)) {
468
+ const items = value.slice(0, 4).map((item) => this.formatToolValue(item, toolName, phase)).filter(Boolean);
469
+ return items.join("; ");
470
+ }
471
+ if (typeof value !== "object")
472
+ return String(value);
473
+ const record = value;
474
+ const read = (key) => this.formatToolValue(record[key], toolName, phase);
475
+ const first = (...keys) => {
476
+ for (const key of keys) {
477
+ if (!(key in record))
478
+ continue;
479
+ const text = read(key);
480
+ if (text)
481
+ return text;
482
+ }
483
+ return "";
484
+ };
485
+ // Tool-specific start summaries put the primary operation first.
486
+ if (phase === "start") {
487
+ if (toolName === "exec") {
488
+ const command = first("command", "cmd", "script");
489
+ const cwd = first("workdir", "cwd");
490
+ if (command)
491
+ return cwd ? `${command} (cwd: ${cwd})` : command;
492
+ }
493
+ if (toolName === "read" || toolName === "write" || toolName === "edit" || toolName === "apply_patch") {
494
+ const path = first("path", "file", "filename");
495
+ if (path)
496
+ return path;
497
+ }
498
+ if (toolName === "web_fetch") {
499
+ const url = first("url");
500
+ if (url)
501
+ return url;
502
+ }
503
+ if (toolName === "web_search") {
504
+ const query = first("query");
505
+ if (query)
506
+ return query;
507
+ }
508
+ }
509
+ const primary = phase === "start"
510
+ ? first("command", "path", "url", "query", "action", "target", "sessionKey", "key", "name", "description", "text")
511
+ : first("error", "message", "status", "exitCode", "output", "stdout", "stderr", "text", "result");
512
+ if (primary)
513
+ return primary;
514
+ // Safe generic fallback: omit fields that commonly carry credentials or
515
+ // large payloads, then serialize a few scalar fields only.
516
+ const blocked = /token|secret|password|auth|credential|cookie|buffer|content|data|env/i;
517
+ const parts = [];
518
+ for (const [key, raw] of Object.entries(record)) {
519
+ if (blocked.test(key) || raw === null || raw === undefined || typeof raw === "object")
520
+ continue;
521
+ parts.push(`${key}=${String(raw)}`);
522
+ if (parts.length >= 4)
523
+ break;
524
+ }
525
+ return parts.join(", ");
526
+ }
454
527
  claimToolEvent(sessionKey, eventId, phase, now = Date.now()) {
455
528
  const normalizedPhase = phase === "error" ? "end" : phase;
456
529
  const normalizedId = eventId.replace(/^(?:tool|command):/, "");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-lark-multi-agent",
3
- "version": "1.4.5",
3
+ "version": "1.4.6",
4
4
  "description": "Multi-bot Lark/Feishu bridge for OpenClaw, with per-bot model routing and isolated sessions",
5
5
  "type": "module",
6
6
  "scripts": {