mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-21 06:02:13 +00:00
refactor: dedupe provider channel readers
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
export type BraveConfig = {
|
||||
mode?: string;
|
||||
@@ -174,8 +175,8 @@ export function normalizeBraveLanguageParams(params: { search_lang?: string; ui_
|
||||
ui_lang?: string;
|
||||
invalidField?: "search_lang" | "ui_lang";
|
||||
} {
|
||||
const rawSearchLang = params.search_lang?.trim() || undefined;
|
||||
const rawUiLang = params.ui_lang?.trim() || undefined;
|
||||
const rawSearchLang = normalizeOptionalString(params.search_lang);
|
||||
const rawUiLang = normalizeOptionalString(params.ui_lang);
|
||||
let searchLangCandidate = rawSearchLang;
|
||||
let uiLangCandidate = rawUiLang;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
import { buildOauthProviderAuthResult } from "openclaw/plugin-sdk/provider-auth";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import { loginChutes } from "openclaw/plugin-sdk/provider-auth-login";
|
||||
import { readStringValue } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { normalizeOptionalString, readStringValue } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
CHUTES_DEFAULT_MODEL_REF,
|
||||
applyChutesApiKeyConfig,
|
||||
@@ -31,7 +31,7 @@ async function runChutesOAuth(ctx: ProviderAuthContext): Promise<ProviderAuthRes
|
||||
validate: (value: string) => (value?.trim() ? undefined : "Required"),
|
||||
}),
|
||||
).trim();
|
||||
const clientSecret = process.env.CHUTES_CLIENT_SECRET?.trim() || undefined;
|
||||
const clientSecret = normalizeOptionalString(process.env.CHUTES_CLIENT_SECRET);
|
||||
|
||||
await ctx.prompter.note(
|
||||
isRemote
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { Static, Type } from "@sinclair/typebox";
|
||||
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type { AnyAgentTool, OpenClawPluginApi, OpenClawPluginToolContext } from "../api.js";
|
||||
import { PlaywrightDiffScreenshotter, type DiffScreenshotter } from "./browser.js";
|
||||
import { resolveDiffImageRenderOptions } from "./config.js";
|
||||
@@ -469,9 +470,9 @@ function normalizeDiffInput(params: DiffsToolParams): DiffInput {
|
||||
}
|
||||
assertMaxBytes(before, "before", MAX_BEFORE_AFTER_BYTES);
|
||||
assertMaxBytes(after, "after", MAX_BEFORE_AFTER_BYTES);
|
||||
const path = params.path?.trim() || undefined;
|
||||
const lang = params.lang?.trim() || undefined;
|
||||
const title = params.title?.trim() || undefined;
|
||||
const path = normalizeOptionalString(params.path);
|
||||
const lang = normalizeOptionalString(params.lang);
|
||||
const title = normalizeOptionalString(params.title);
|
||||
if (path) {
|
||||
assertMaxBytes(path, "path", MAX_PATH_BYTES);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
readStringParam,
|
||||
} from "openclaw/plugin-sdk/agent-runtime";
|
||||
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-contract";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { handleDiscordAction } from "../../action-runtime-api.js";
|
||||
import {
|
||||
isDiscordModerationAction,
|
||||
@@ -360,7 +361,7 @@ export async function tryHandleDiscordMessageActionGuildAdmin(params: {
|
||||
integer: true,
|
||||
}),
|
||||
});
|
||||
const senderUserId = ctx.requesterSenderId?.trim() || undefined;
|
||||
const senderUserId = normalizeOptionalString(ctx.requesterSenderId);
|
||||
return await handleDiscordAction(
|
||||
{
|
||||
action: moderation.action,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createRunStateMachine } from "openclaw/plugin-sdk/channel-lifecycle";
|
||||
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/core";
|
||||
import { danger, formatDurationSeconds } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { materializeDiscordInboundJob, type DiscordInboundJob } from "./inbound-job.js";
|
||||
import type { RuntimeEnv } from "./message-handler.preflight.types.js";
|
||||
import { processDiscordMessage } from "./message-handler.process.js";
|
||||
@@ -63,8 +64,8 @@ async function processDiscordInboundJob(params: {
|
||||
finalReplyStarted = true;
|
||||
},
|
||||
onReplyPlanResolved: (resolved) => {
|
||||
createdThreadId = resolved.createdThreadId?.trim() || undefined;
|
||||
sessionKey = resolved.sessionKey?.trim() || undefined;
|
||||
createdThreadId = normalizeOptionalString(resolved.createdThreadId);
|
||||
sessionKey = normalizeOptionalString(resolved.sessionKey);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import * as conversationRuntime from "openclaw/plugin-sdk/conversation-binding-runtime";
|
||||
import type { ResolvedAgentRoute } from "openclaw/plugin-sdk/routing";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
resolveDiscordBoundConversationRoute,
|
||||
resolveDiscordEffectiveRoute,
|
||||
@@ -63,9 +64,9 @@ export async function resolveDiscordNativeInteractionRouteState(params: {
|
||||
})
|
||||
: null;
|
||||
const configuredBinding = configuredRoute?.bindingResolution ?? null;
|
||||
const configuredBoundSessionKey = configuredRoute?.boundSessionKey?.trim() || undefined;
|
||||
const configuredBoundSessionKey = normalizeOptionalString(configuredRoute?.boundSessionKey);
|
||||
const boundSessionKey =
|
||||
params.threadBinding?.targetSessionKey?.trim() || configuredBoundSessionKey;
|
||||
normalizeOptionalString(params.threadBinding?.targetSessionKey) ?? configuredBoundSessionKey;
|
||||
const effectiveRoute = resolveDiscordEffectiveRoute({
|
||||
route,
|
||||
boundSessionKey,
|
||||
|
||||
@@ -12,6 +12,7 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { danger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { createDiscordRequestClient } from "../proxy-request-client.js";
|
||||
import type { DiscordGuildEntryResolved } from "./allow-list.js";
|
||||
import { createDiscordAutoPresenceController } from "./auto-presence.js";
|
||||
@@ -166,7 +167,8 @@ export async function fetchDiscordBotIdentity(params: {
|
||||
try {
|
||||
const botUser = await params.client.fetchUser("@me");
|
||||
const botUserId = botUser?.id;
|
||||
const botUserName = botUser?.username?.trim() || botUser?.globalName?.trim() || undefined;
|
||||
const botUserName =
|
||||
normalizeOptionalString(botUser?.username) ?? normalizeOptionalString(botUser?.globalName);
|
||||
params.logStartupPhase(
|
||||
"fetch-bot-identity:done",
|
||||
`botUserId=${botUserId ?? "<missing>"} botUserName=${botUserName ?? "<missing>"}`,
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
type RetryRunner,
|
||||
} from "openclaw/plugin-sdk/retry-runtime";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { convertMarkdownTables, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { resolveDiscordAccount } from "../accounts.js";
|
||||
import { chunkDiscordTextWithMode } from "../chunk.js";
|
||||
import { isLikelyDiscordVideoMedia } from "../media-detection.js";
|
||||
@@ -228,7 +228,7 @@ function createPayloadReplyToResolver(params: {
|
||||
replyToMode: ReplyToMode;
|
||||
resolveFallbackReplyTo: () => string | undefined;
|
||||
}): () => string | undefined {
|
||||
const payloadReplyTo = params.payload.replyToId?.trim() || undefined;
|
||||
const payloadReplyTo = normalizeOptionalString(params.payload.replyToId);
|
||||
const allowExplicitReplyWhenOff = Boolean(
|
||||
payloadReplyTo && (params.payload.replyToTag || params.payload.replyToCurrent),
|
||||
);
|
||||
@@ -370,7 +370,7 @@ export async function deliverDiscordReply(params: {
|
||||
threadBindings?: DiscordThreadBindingLookup;
|
||||
mediaLocalRoots?: readonly string[];
|
||||
}) {
|
||||
const replyTo = params.replyToId?.trim() || undefined;
|
||||
const replyTo = normalizeOptionalString(params.replyToId);
|
||||
const replyToMode = params.replyToMode ?? "all";
|
||||
const replyOnce = isSingleUseReplyToMode(replyToMode);
|
||||
let replyUsed = false;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { User } from "@buape/carbon";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type { PluralKitMessageInfo } from "../pluralkit.js";
|
||||
import { formatDiscordUserTag } from "./format.js";
|
||||
|
||||
@@ -48,13 +49,13 @@ export function resolveDiscordSenderIdentity(params: {
|
||||
return {
|
||||
id: memberId,
|
||||
name: memberName,
|
||||
tag: pkMember?.name?.trim() || undefined,
|
||||
tag: normalizeOptionalString(pkMember?.name),
|
||||
label,
|
||||
isPluralKit: true,
|
||||
pluralkit: {
|
||||
memberId,
|
||||
memberName,
|
||||
systemId: pkSystem?.id?.trim() || undefined,
|
||||
systemId: normalizeOptionalString(pkSystem?.id),
|
||||
systemName,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/runtime-config-snapshot";
|
||||
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { createDiscordRestClient } from "../client.js";
|
||||
import {
|
||||
createThreadForBinding,
|
||||
@@ -452,11 +453,13 @@ export function createThreadBindingManager(
|
||||
threadId,
|
||||
targetKind,
|
||||
targetSessionKey,
|
||||
agentId: bindParams.agentId?.trim() || resolveAgentIdFromSessionKey(targetSessionKey),
|
||||
label: bindParams.label?.trim() || undefined,
|
||||
agentId:
|
||||
normalizeOptionalString(bindParams.agentId) ??
|
||||
resolveAgentIdFromSessionKey(targetSessionKey),
|
||||
label: normalizeOptionalString(bindParams.label),
|
||||
webhookId: webhookId || undefined,
|
||||
webhookToken: webhookToken || undefined,
|
||||
boundBy: bindParams.boundBy?.trim() || "system",
|
||||
boundBy: normalizeOptionalString(bindParams.boundBy) || "system",
|
||||
boundAt: now,
|
||||
lastActivityAt: now,
|
||||
idleTimeoutMs,
|
||||
@@ -598,16 +601,22 @@ export function createThreadBindingManager(
|
||||
typeof metadata.label === "string" ? metadata.label.trim() || undefined : undefined;
|
||||
const threadName =
|
||||
typeof metadata.threadName === "string"
|
||||
? metadata.threadName.trim() || undefined
|
||||
? normalizeOptionalString(metadata.threadName)
|
||||
: undefined;
|
||||
const introText =
|
||||
typeof metadata.introText === "string" ? metadata.introText.trim() || undefined : undefined;
|
||||
typeof metadata.introText === "string"
|
||||
? normalizeOptionalString(metadata.introText)
|
||||
: undefined;
|
||||
const boundBy =
|
||||
typeof metadata.boundBy === "string" ? metadata.boundBy.trim() || undefined : undefined;
|
||||
typeof metadata.boundBy === "string"
|
||||
? normalizeOptionalString(metadata.boundBy)
|
||||
: undefined;
|
||||
const agentId =
|
||||
typeof metadata.agentId === "string" ? metadata.agentId.trim() || undefined : undefined;
|
||||
typeof metadata.agentId === "string"
|
||||
? normalizeOptionalString(metadata.agentId)
|
||||
: undefined;
|
||||
let threadId: string | undefined;
|
||||
let channelId = input.conversation.parentConversationId?.trim() || undefined;
|
||||
let channelId = normalizeOptionalString(input.conversation.parentConversationId);
|
||||
let createThread = false;
|
||||
|
||||
if (placement === "child") {
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
sendPayloadMediaSequenceOrFallback,
|
||||
sendTextMediaPayload,
|
||||
} from "openclaw/plugin-sdk/reply-payload";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type { DiscordComponentMessageSpec } from "./components.js";
|
||||
import { getThreadBindingManager, type ThreadBindingRecord } from "./monitor/thread-bindings.js";
|
||||
import { normalizeDiscordOutboundTarget } from "./normalize.js";
|
||||
@@ -67,10 +68,10 @@ function resolveDiscordWebhookIdentity(params: {
|
||||
identity?: OutboundIdentity;
|
||||
binding: ThreadBindingRecord;
|
||||
}): { username?: string; avatarUrl?: string } {
|
||||
const usernameRaw = params.identity?.name?.trim();
|
||||
const fallbackUsername = params.binding.label?.trim() || params.binding.agentId;
|
||||
const usernameRaw = normalizeOptionalString(params.identity?.name);
|
||||
const fallbackUsername = normalizeOptionalString(params.binding.label) ?? params.binding.agentId;
|
||||
const username = (usernameRaw || fallbackUsername || "").slice(0, 80) || undefined;
|
||||
const avatarUrl = params.identity?.avatarUrl?.trim() || undefined;
|
||||
const avatarUrl = normalizeOptionalString(params.identity?.avatarUrl);
|
||||
return { username, avatarUrl };
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { fetchDiscord } from "./api.js";
|
||||
import { listGuilds, type DiscordGuildSummary } from "./guilds.js";
|
||||
import {
|
||||
@@ -156,7 +157,9 @@ export async function resolveDiscordUserAllowlist(params: {
|
||||
if (best) {
|
||||
const user = best.member.user;
|
||||
const name =
|
||||
best.member.nick?.trim() || user.global_name?.trim() || user.username?.trim() || undefined;
|
||||
normalizeOptionalString(best.member.nick) ??
|
||||
normalizeOptionalString(user.global_name) ??
|
||||
normalizeOptionalString(user.username);
|
||||
results.push({
|
||||
input,
|
||||
resolved: true,
|
||||
|
||||
@@ -13,7 +13,7 @@ import type { PollInput } from "openclaw/plugin-sdk/media-runtime";
|
||||
import { resolveChunkMode } from "openclaw/plugin-sdk/reply-chunking";
|
||||
import type { RetryConfig } from "openclaw/plugin-sdk/retry-runtime";
|
||||
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
||||
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { convertMarkdownTables, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { loadWebMediaRaw } from "openclaw/plugin-sdk/web-media";
|
||||
import { resolveDiscordAccount } from "./accounts.js";
|
||||
import { resolveDiscordClientAccountContext } from "./client.js";
|
||||
@@ -391,8 +391,8 @@ export async function sendWebhookMessageDiscord(
|
||||
},
|
||||
body: JSON.stringify({
|
||||
content: rewrittenText,
|
||||
username: opts.username?.trim() || undefined,
|
||||
avatar_url: opts.avatarUrl?.trim() || undefined,
|
||||
username: normalizeOptionalString(opts.username),
|
||||
avatar_url: normalizeOptionalString(opts.avatarUrl),
|
||||
...(messageReference ? { message_reference: messageReference } : {}),
|
||||
}),
|
||||
},
|
||||
|
||||
@@ -17,6 +17,7 @@ import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { parseTtsDirectives } from "openclaw/plugin-sdk/speech";
|
||||
import { formatErrorMessage } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { formatMention } from "../mentions.js";
|
||||
import { normalizeDiscordSlug, resolveDiscordOwnerAccess } from "../monitor/allow-list.js";
|
||||
import { formatDiscordUserTag } from "../monitor/format.js";
|
||||
@@ -300,7 +301,7 @@ async function transcribeAudio(params: {
|
||||
agentDir: resolveAgentDir(params.cfg, params.agentId),
|
||||
mime: "audio/wav",
|
||||
});
|
||||
return result.text?.trim() || undefined;
|
||||
return normalizeOptionalString(result.text);
|
||||
}
|
||||
|
||||
export class DiscordVoiceManager {
|
||||
|
||||
@@ -311,9 +311,9 @@ export async function listElevenLabsVoices(params: {
|
||||
? json.voices
|
||||
.map((voice) => ({
|
||||
id: voice.voice_id?.trim() ?? "",
|
||||
name: voice.name?.trim() || undefined,
|
||||
category: voice.category?.trim() || undefined,
|
||||
description: voice.description?.trim() || undefined,
|
||||
name: trimToUndefined(voice.name),
|
||||
category: trimToUndefined(voice.category),
|
||||
description: trimToUndefined(voice.description),
|
||||
}))
|
||||
.filter((voice) => voice.id.length > 0)
|
||||
: [];
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
resolveOpenProviderRuntimeGroupPolicy,
|
||||
warnMissingProviderGroupPolicyFallbackOnce,
|
||||
} from "openclaw/plugin-sdk/runtime-group-policy";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { resolveFeishuRuntimeAccount } from "./accounts.js";
|
||||
import {
|
||||
checkBotMentioned,
|
||||
@@ -344,7 +345,7 @@ export async function handleFeishuMessage(params: {
|
||||
let ctx = parseFeishuMessageEvent(event, botOpenId, botName);
|
||||
const isGroup = ctx.chatType === "group";
|
||||
const isDirect = !isGroup;
|
||||
const senderUserId = event.sender.sender_id.user_id?.trim() || undefined;
|
||||
const senderUserId = normalizeOptionalString(event.sender.sender_id.user_id);
|
||||
|
||||
// Handle merge_forward messages: fetch full message via API then expand sub-messages
|
||||
if (event.message.message_type === "merge_forward") {
|
||||
@@ -1060,7 +1061,7 @@ export async function handleFeishuMessage(params: {
|
||||
CommandAuthorized: commandAuthorized,
|
||||
OriginatingChannel: "feishu" as const,
|
||||
OriginatingTo: feishuTo,
|
||||
GroupSystemPrompt: isGroup ? groupConfig?.systemPrompt?.trim() || undefined : undefined,
|
||||
GroupSystemPrompt: isGroup ? normalizeOptionalString(groupConfig?.systemPrompt) : undefined,
|
||||
...mediaPayload,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import { basename } from "node:path";
|
||||
import type * as Lark from "@larksuiteoapi/node-sdk";
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type { OpenClawPluginApi } from "../runtime-api.js";
|
||||
import { listEnabledFeishuAccounts } from "./accounts.js";
|
||||
import { FeishuDocSchema, type FeishuDocParams } from "./doc-schema.js";
|
||||
@@ -1393,7 +1394,9 @@ export function registerFeishuDocTools(api: OpenClawPluginApi) {
|
||||
(ctx) => {
|
||||
const defaultAccountId = ctx.agentAccountId;
|
||||
const trustedRequesterOpenId =
|
||||
ctx.messageChannel === "feishu" ? ctx.requesterSenderId?.trim() || undefined : undefined;
|
||||
ctx.messageChannel === "feishu"
|
||||
? normalizeOptionalString(ctx.requesterSenderId)
|
||||
: undefined;
|
||||
return {
|
||||
name: "feishu_doc",
|
||||
label: "Feishu Doc",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type { RuntimeEnv } from "../runtime-api.js";
|
||||
import { waitForAbortableDelay } from "./async.js";
|
||||
import { fetchBotIdentityForMonitor, type FeishuMonitorBotIdentity } from "./monitor.startup.js";
|
||||
@@ -12,8 +13,8 @@ export function applyBotIdentityState(
|
||||
accountId: string,
|
||||
identity: FeishuMonitorBotIdentity,
|
||||
): { botOpenId?: string; botName?: string } {
|
||||
const botOpenId = identity.botOpenId?.trim() || undefined;
|
||||
const botName = identity.botName?.trim() || undefined;
|
||||
const botOpenId = normalizeOptionalString(identity.botOpenId);
|
||||
const botName = normalizeOptionalString(identity.botName);
|
||||
|
||||
botOpenIds.set(accountId, botOpenId ?? "");
|
||||
if (botName) {
|
||||
|
||||
@@ -3,7 +3,13 @@ import type { ClawdbotConfig } from "../runtime-api.js";
|
||||
import { resolveFeishuAccount } from "./accounts.js";
|
||||
import { raceWithTimeoutAndAbort } from "./async.js";
|
||||
import { createFeishuClient } from "./client.js";
|
||||
import { encodeQuery, extractReplyText, isRecord, readString } from "./comment-shared.js";
|
||||
import {
|
||||
encodeQuery,
|
||||
extractReplyText,
|
||||
isRecord,
|
||||
normalizeString,
|
||||
readString,
|
||||
} from "./comment-shared.js";
|
||||
import { normalizeCommentFileType, type CommentFileType } from "./comment-target.js";
|
||||
import type { ResolvedFeishuAccount } from "./types.js";
|
||||
|
||||
@@ -415,10 +421,10 @@ async function fetchDriveCommentContext(params: {
|
||||
const meta = metaResponse?.code === 0 ? metaResponse.data?.metas?.[0] : undefined;
|
||||
|
||||
return {
|
||||
documentTitle: meta?.title?.trim() || undefined,
|
||||
documentUrl: meta?.url?.trim() || undefined,
|
||||
documentTitle: normalizeString(meta?.title),
|
||||
documentUrl: normalizeString(meta?.url),
|
||||
isWholeComment: commentCard?.is_whole,
|
||||
quoteText: commentCard?.quote?.trim() || undefined,
|
||||
quoteText: normalizeString(commentCard?.quote),
|
||||
rootCommentText: extractReplyText(rootReply),
|
||||
targetReplyText: extractReplyText(targetReply),
|
||||
};
|
||||
@@ -537,7 +543,7 @@ async function resolveDriveCommentEventCore(params: ResolveDriveCommentEventPara
|
||||
const fileToken = event.notice_meta?.file_token?.trim();
|
||||
const fileType = normalizeCommentFileType(event.notice_meta?.file_type);
|
||||
const senderId = event.notice_meta?.from_user_id?.open_id?.trim();
|
||||
const senderUserId = event.notice_meta?.from_user_id?.user_id?.trim() || undefined;
|
||||
const senderUserId = normalizeString(event.notice_meta?.from_user_id?.user_id);
|
||||
if (!eventId || !commentId || !noticeType || !fileToken || !fileType || !senderId) {
|
||||
logger?.(
|
||||
`feishu[${accountId}]: drive comment notice missing required fields event=${eventId ?? "unknown"} comment=${commentId ?? "unknown"}`,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type { OpenClawPluginApi } from "../runtime-api.js";
|
||||
import { buildFeishuConversationId, parseFeishuConversationId } from "./conversation-id.js";
|
||||
import { normalizeFeishuTarget } from "./targets.js";
|
||||
@@ -221,8 +222,8 @@ function resolveMatchingChildBinding(params: {
|
||||
(entry) =>
|
||||
entry.accountId === requesterConversation.accountId &&
|
||||
entry.conversationId === requesterConversation.conversationId &&
|
||||
(entry.parentConversationId?.trim() || undefined) ===
|
||||
(requesterConversation.parentConversationId?.trim() || undefined),
|
||||
normalizeOptionalString(entry.parentConversationId) ===
|
||||
normalizeOptionalString(requesterConversation.parentConversationId),
|
||||
);
|
||||
if (matched) {
|
||||
return matched;
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
type SessionBindingRecord,
|
||||
} from "openclaw/plugin-sdk/conversation-runtime";
|
||||
import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
type FeishuBindingTargetKind = "subagent" | "acp";
|
||||
|
||||
@@ -165,7 +166,7 @@ export function createFeishuThreadBindingManager(params: {
|
||||
const record: FeishuThreadBindingRecord = {
|
||||
accountId,
|
||||
conversationId: normalizedConversationId,
|
||||
parentConversationId: parentConversationId?.trim() || undefined,
|
||||
parentConversationId: normalizeOptionalString(parentConversationId),
|
||||
deliveryTo:
|
||||
typeof metadata?.deliveryTo === "string" && metadata.deliveryTo.trim()
|
||||
? metadata.deliveryTo.trim()
|
||||
|
||||
@@ -144,11 +144,11 @@ export async function listMicrosoftVoices(): Promise<SpeechVoiceOption[]> {
|
||||
? voices
|
||||
.map((voice) => ({
|
||||
id: voice.ShortName?.trim() ?? "",
|
||||
name: voice.FriendlyName?.trim() || voice.ShortName?.trim() || undefined,
|
||||
name: trimToUndefined(voice.FriendlyName) ?? trimToUndefined(voice.ShortName),
|
||||
category: voice.VoiceTag?.ContentCategories?.find((value) => value.trim().length > 0),
|
||||
description: formatMicrosoftVoiceDescription(voice),
|
||||
locale: voice.Locale?.trim() || undefined,
|
||||
gender: voice.Gender?.trim() || undefined,
|
||||
locale: trimToUndefined(voice.Locale),
|
||||
gender: trimToUndefined(voice.Gender),
|
||||
personalities: voice.VoiceTag?.VoicePersonalities?.filter(
|
||||
(value): value is string => value.trim().length > 0,
|
||||
),
|
||||
|
||||
@@ -991,7 +991,7 @@ export const msteamsPlugin: ChannelPlugin<ResolvedMSTeamsAccount, ProbeMSTeamsRe
|
||||
},
|
||||
threading: {
|
||||
buildToolContext: ({ context, hasRepliedRef }) => ({
|
||||
currentChannelId: context.To?.trim() || undefined,
|
||||
currentChannelId: normalizeOptionalString(context.To),
|
||||
currentThreadTs: context.ReplyToId,
|
||||
hasRepliedRef,
|
||||
}),
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
type ModelProviderConfig,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { readStringValue } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { normalizeOptionalString, readStringValue } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
buildOllamaProvider,
|
||||
configureOllamaNonInteractive,
|
||||
@@ -51,8 +51,8 @@ function resolveOllamaDiscoveryApiKey(params: {
|
||||
resolvedApiKey?: string;
|
||||
}): string {
|
||||
const envApiKey = params.env.OLLAMA_API_KEY?.trim() ? "OLLAMA_API_KEY" : undefined;
|
||||
const explicitApiKey = params.explicitApiKey?.trim() || undefined;
|
||||
const resolvedApiKey = params.resolvedApiKey?.trim() || undefined;
|
||||
const explicitApiKey = normalizeOptionalString(params.explicitApiKey);
|
||||
const resolvedApiKey = normalizeOptionalString(params.resolvedApiKey);
|
||||
return envApiKey ?? explicitApiKey ?? resolvedApiKey ?? DEFAULT_API_KEY;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,12 @@ import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-pay
|
||||
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
|
||||
import { isVerbose, logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/sandbox";
|
||||
import { CONFIG_DIR, resolveUserPath, stripMarkdown } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
CONFIG_DIR,
|
||||
normalizeOptionalString,
|
||||
resolveUserPath,
|
||||
stripMarkdown,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
canonicalizeSpeechProviderId,
|
||||
getSpeechProvider,
|
||||
@@ -324,7 +329,7 @@ export function resolveTtsConfig(cfg: OpenClawConfig): ResolvedTtsConfig {
|
||||
normalizeConfiguredSpeechProviderId(raw.provider) ??
|
||||
(providerSource === "config" ? raw.provider?.trim().toLowerCase() || "" : ""),
|
||||
providerSource,
|
||||
summaryModel: raw.summaryModel?.trim() || undefined,
|
||||
summaryModel: normalizeOptionalString(raw.summaryModel),
|
||||
modelOverrides: resolveModelOverridePolicy(raw.modelOverrides),
|
||||
providerConfigs: collectDirectProviderConfigEntries(raw),
|
||||
prefsPath: raw.prefsPath,
|
||||
|
||||
Reference in New Issue
Block a user