From 3fd29e549de45402a7d0d334cb763cc56cdfe173 Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Fri, 3 Apr 2026 17:06:45 -0500 Subject: [PATCH] fix: honor tools default account --- .../reply/commands-info.tools.test.ts | 59 +++++++++++++++++++ src/auto-reply/reply/commands-info.ts | 10 +++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/auto-reply/reply/commands-info.tools.test.ts b/src/auto-reply/reply/commands-info.tools.test.ts index 492575a8cf3..66f7692bd48 100644 --- a/src/auto-reply/reply/commands-info.tools.test.ts +++ b/src/auto-reply/reply/commands-info.tools.test.ts @@ -1,5 +1,7 @@ import { describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; +import { setActivePluginRegistry } from "../../plugins/runtime.js"; +import { createChannelTestPluginBase, createTestRegistry } from "../../test-utils/channel-plugins.js"; async function loadToolsHarness(options?: { resolveToolsMock?: ReturnType; @@ -219,6 +221,63 @@ describe("handleToolsCommand", () => { expect(result).toEqual({ shouldContinue: false }); }); + it("uses the configured default account when /tools omits AccountId", async () => { + setActivePluginRegistry( + createTestRegistry([ + { + pluginId: "telegram", + source: "test", + plugin: { + ...createChannelTestPluginBase({ + id: "telegram", + label: "Telegram", + config: { + listAccountIds: () => ["default", "work"], + defaultAccountId: () => "work", + resolveAccount: (_cfg, accountId) => ({ accountId: accountId ?? "work" }), + }, + }), + }, + }, + ]), + ); + + const { buildCommandTestParams, handleToolsCommand, resolveToolsMock } = + await loadToolsHarness(); + const params = buildCommandTestParams( + "/tools", + { + commands: { text: true }, + channels: { telegram: { defaultAccount: "work" } }, + } as OpenClawConfig, + undefined, + { workspaceDir: "/tmp" }, + ); + params.agentId = "main"; + params.provider = "openai"; + params.model = "gpt-4.1"; + params.ctx = { + ...params.ctx, + OriginatingChannel: "telegram", + Provider: "telegram", + Surface: "telegram", + ChatType: "group", + AccountId: undefined, + }; + params.command = { + ...params.command, + channel: "telegram", + }; + + await handleToolsCommand(params, true); + + expect(resolveToolsMock).toHaveBeenCalledWith( + expect.objectContaining({ + accountId: "work", + }), + ); + }); + it("returns a concise fallback error on effective inventory failures", async () => { const { buildCommandTestParams, handleToolsCommand } = await loadToolsHarness({ resolveTools: () => { diff --git a/src/auto-reply/reply/commands-info.ts b/src/auto-reply/reply/commands-info.ts index dd71d2ec3b1..121a38d27e3 100644 --- a/src/auto-reply/reply/commands-info.ts +++ b/src/auto-reply/reply/commands-info.ts @@ -14,6 +14,7 @@ import { buildContextReply } from "./commands-context-report.js"; import { buildExportSessionReply } from "./commands-export-session.js"; import { buildStatusReply } from "./commands-status.js"; import type { CommandHandler } from "./commands-types.js"; +import { resolveChannelAccountId } from "./channel-context.js"; import { extractExplicitGroupId } from "./group-id.js"; import { resolveReplyToMode } from "./reply-threading.js"; @@ -105,6 +106,11 @@ export const handleToolsCommand: CommandHandler = async (params, allowTextComman } try { + const effectiveAccountId = resolveChannelAccountId({ + cfg: params.cfg, + ctx: params.ctx, + command: params.command, + }); const agentId = params.agentId ?? resolveSessionAgentId({ sessionKey: params.sessionKey, config: params.cfg }); @@ -127,7 +133,7 @@ export const handleToolsCommand: CommandHandler = async (params, allowTextComman senderName: params.ctx.SenderName, senderUsername: params.ctx.SenderUsername, senderE164: params.ctx.SenderE164, - accountId: params.ctx.AccountId, + accountId: effectiveAccountId, currentChannelId: threadingContext.currentChannelId, currentThreadTs: typeof params.ctx.MessageThreadId === "string" || @@ -142,7 +148,7 @@ export const handleToolsCommand: CommandHandler = async (params, allowTextComman replyToMode: resolveReplyToMode( params.cfg, params.ctx.OriginatingChannel ?? params.ctx.Provider, - params.ctx.AccountId, + effectiveAccountId, params.ctx.ChatType, ), });