fix: refresh web tool and audit typing

This commit is contained in:
Ayaan Zaidi
2026-04-06 14:02:38 +05:30
parent 0bfe6710a2
commit 03523c65d5
5 changed files with 20 additions and 22 deletions

View File

@@ -1,6 +1,7 @@
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import type {
ChannelDirectoryEntryKind,
ChannelMessageActionName,
ChannelMessagingAdapter,
ChannelOutboundAdapter,
ChannelPlugin,
@@ -32,7 +33,7 @@ const whatsappConfig = {
const runDryAction = (params: {
cfg: OpenClawConfig;
action: "send" | "thread-reply" | "broadcast" | "upload-file";
action: ChannelMessageActionName;
actionParams: Record<string, unknown>;
toolContext?: Record<string, unknown>;
abortSignal?: AbortSignal;

View File

@@ -386,8 +386,12 @@ export async function resolveRuntimeWebTools(params: {
? params.resolvedConfig.tools
: undefined;
const resolvedWeb = isRecord(resolvedTools?.web) ? resolvedTools.web : undefined;
const legacyXSearchSource = isRecord(sourceWeb?.x_search) ? sourceWeb.x_search : undefined;
const legacyXSearchResolved = isRecord(resolvedWeb?.x_search) ? resolvedWeb.x_search : undefined;
const legacyXSearchSourceRaw: unknown = sourceWeb?.x_search;
const legacyXSearchResolvedRaw: unknown = resolvedWeb?.x_search;
const legacyXSearchSource = isRecord(legacyXSearchSourceRaw) ? legacyXSearchSourceRaw : undefined;
const legacyXSearchResolved = isRecord(legacyXSearchResolvedRaw)
? legacyXSearchResolvedRaw
: undefined;
if (!sourceWeb && !hasPluginWebToolConfig(params.sourceConfig)) {
return {
search: {
@@ -406,16 +410,17 @@ export async function resolveRuntimeWebTools(params: {
legacyXSearchResolved &&
Object.prototype.hasOwnProperty.call(legacyXSearchSource, "apiKey")
) {
const apiKey = legacyXSearchSource["apiKey"];
const resolution = await resolveSecretInputWithEnvFallback({
sourceConfig: params.sourceConfig,
context: params.context,
defaults,
value: legacyXSearchSource.apiKey,
value: apiKey,
path: "tools.web.x_search.apiKey",
envVars: ["XAI_API_KEY"],
});
if (resolution.value) {
legacyXSearchResolved.apiKey = resolution.value;
legacyXSearchResolved["apiKey"] = resolution.value;
}
}
const search = isRecord(sourceWeb?.search) ? sourceWeb.search : undefined;

View File

@@ -1,6 +1,7 @@
import { describe, expect, it, vi } from "vitest";
import { collectDiscordSecurityAuditFindings } from "../../extensions/discord/contract-api.js";
import type { ResolvedDiscordAccount } from "../../extensions/discord/src/accounts.js";
import type { DiscordAccountConfig } from "../../extensions/discord/src/runtime-api.js";
import type { OpenClawConfig } from "../config/config.js";
import { withChannelSecurityStateDir } from "./audit-channel-security.test-helpers.js";
@@ -12,9 +13,7 @@ vi.mock("openclaw/plugin-sdk/conversation-runtime", () => ({
readChannelAllowFromStore: readChannelAllowFromStoreMock,
}));
function createDiscordAccount(
config: NonNullable<OpenClawConfig["channels"]>["discord"],
): ResolvedDiscordAccount {
function createDiscordAccount(config: DiscordAccountConfig): ResolvedDiscordAccount {
return {
accountId: "default",
enabled: true,
@@ -49,10 +48,10 @@ describe("security audit discord command findings", () => {
const findings = await collectDiscordSecurityAuditFindings({
cfg: cfg as OpenClawConfig & {
channels: {
discord: NonNullable<OpenClawConfig["channels"]>["discord"];
discord: DiscordAccountConfig;
};
},
account: createDiscordAccount(cfg.channels!.discord),
account: createDiscordAccount(cfg.channels!.discord!),
accountId: "default",
orderedAccountIds: ["default"],
hasExplicitAccountPath: false,

View File

@@ -1,6 +1,7 @@
import { describe, expect, it, vi } from "vitest";
import { collectDiscordSecurityAuditFindings } from "../../extensions/discord/contract-api.js";
import type { ResolvedDiscordAccount } from "../../extensions/discord/src/accounts.js";
import type { DiscordAccountConfig } from "../../extensions/discord/src/runtime-api.js";
import type { OpenClawConfig } from "../config/config.js";
const { readChannelAllowFromStoreMock } = vi.hoisted(() => ({
@@ -11,9 +12,7 @@ vi.mock("openclaw/plugin-sdk/conversation-runtime", () => ({
readChannelAllowFromStore: readChannelAllowFromStoreMock,
}));
function createAccount(
config: NonNullable<OpenClawConfig["channels"]>["discord"],
): ResolvedDiscordAccount {
function createAccount(config: DiscordAccountConfig): ResolvedDiscordAccount {
return {
accountId: "default",
enabled: true,
@@ -78,7 +77,7 @@ describe("security audit discord native command findings", () => {
throw new Error("discord config required");
}
const findings = await collectDiscordSecurityAuditFindings({
cfg: testCase.cfg as OpenClawConfig & { channels: { discord: typeof discord } },
cfg: testCase.cfg as OpenClawConfig & { channels: { discord: DiscordAccountConfig } },
account: createAccount(discord),
accountId: "default",
orderedAccountIds: ["default"],

View File

@@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest";
import { collectSynologyChatSecurityAuditFindings } from "../../extensions/synology-chat/contract-api.js";
import { resolveAccount as resolveSynologyChatAccount } from "../../extensions/synology-chat/src/accounts.js";
import { collectZalouserSecurityAuditFindings } from "../../extensions/zalouser/contract-api.js";
import type { ResolvedZalouserAccount } from "../../extensions/zalouser/src/accounts.js";
import type { ChannelPlugin } from "../channels/plugins/types.js";
@@ -99,14 +100,7 @@ describe("security audit synology and zalo channel routing", () => {
? "beta"
: "default";
const findings = collectSynologyChatSecurityAuditFindings({
account: {
accountId,
enabled: true,
dangerouslyAllowNameMatching:
accountId === "beta"
? synologyChat.accounts?.beta?.dangerouslyAllowNameMatching === true
: synologyChat.dangerouslyAllowNameMatching === true,
},
account: resolveSynologyChatAccount(testCase.cfg, accountId),
accountId,
orderedAccountIds: Object.keys(synologyChat.accounts ?? {}),
hasExplicitAccountPath: accountId !== "default",