mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 01:31:08 +00:00
chore: enable consistent-return
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
"oxc/no-accumulating-spread": "off",
|
||||
"oxc/no-async-endpoint-handlers": "off",
|
||||
"oxc/no-map-spread": "off",
|
||||
"typescript/consistent-return": "off",
|
||||
"typescript/consistent-return": "error",
|
||||
"typescript/no-explicit-any": "error",
|
||||
"typescript/no-extraneous-class": "off",
|
||||
"typescript/no-unnecessary-type-conversion": "off",
|
||||
|
||||
@@ -134,6 +134,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Hooks/security: mark agent hook system events as untrusted and sanitize hook display names before cron metadata reuse. (#64372) Thanks @eleqtrizit.
|
||||
- Media/security: honor sender-scoped `toolsBySender` policy for outbound host-media reads so denied senders cannot trigger host file disclosure via attachment hydration. (#64459) Thanks @eleqtrizit.
|
||||
- Browser/security: reject strict-policy hostname navigation unless the hostname is an explicit allowlist exception or IP literal, and route CDP HTTP discovery through the pinned SSRF fetch path. (#64367) Thanks @eleqtrizit.
|
||||
|
||||
## 2026.4.9
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -1496,7 +1496,7 @@ export default definePluginEntry({
|
||||
agentId: effectiveAgentId,
|
||||
sessionKey: resolvedSessionKey,
|
||||
});
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (!isEnabledForAgent(config, effectiveAgentId)) {
|
||||
await persistPluginStatusLines({
|
||||
@@ -1504,7 +1504,7 @@ export default definePluginEntry({
|
||||
agentId: effectiveAgentId,
|
||||
sessionKey: resolvedSessionKey,
|
||||
});
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (!isEligibleInteractiveSession(ctx)) {
|
||||
await persistPluginStatusLines({
|
||||
@@ -1512,7 +1512,7 @@ export default definePluginEntry({
|
||||
agentId: effectiveAgentId,
|
||||
sessionKey: resolvedSessionKey,
|
||||
});
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (
|
||||
!isAllowedChatType(config, {
|
||||
@@ -1526,7 +1526,7 @@ export default definePluginEntry({
|
||||
agentId: effectiveAgentId,
|
||||
sessionKey: resolvedSessionKey,
|
||||
});
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const query = buildQuery({
|
||||
latestUserMessage: event.prompt,
|
||||
@@ -1544,11 +1544,11 @@ export default definePluginEntry({
|
||||
currentModelId: ctx.modelId,
|
||||
});
|
||||
if (!result.summary) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const metadata = buildMetadata(result.summary);
|
||||
if (!metadata) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
prependSystemContext: ACTIVE_MEMORY_PLUGIN_GUIDANCE,
|
||||
|
||||
@@ -318,4 +318,5 @@ export function normalizeActRequest(
|
||||
};
|
||||
}
|
||||
}
|
||||
throw new Error("Unsupported browser act kind");
|
||||
}
|
||||
|
||||
@@ -307,6 +307,7 @@ function getExistingSessionUnsupportedMessage(action: BrowserActRequest): string
|
||||
case "close":
|
||||
return null;
|
||||
}
|
||||
throw new Error("Unsupported browser act kind");
|
||||
}
|
||||
|
||||
export function registerBrowserAgentActRoutes(
|
||||
|
||||
@@ -21,7 +21,7 @@ export function createBrowserProgram(params?: { withGatewayUrl?: boolean }): {
|
||||
if (params?.withGatewayUrl) {
|
||||
browser.option("--url <url>", "Gateway WebSocket URL");
|
||||
}
|
||||
const parentOpts = (cmd: Command) => cmd.parent?.opts?.() as BrowserParentOpts;
|
||||
const parentOpts = (cmd: Command): BrowserParentOpts => cmd.parent?.opts?.() as BrowserParentOpts;
|
||||
return { program, browser, parentOpts };
|
||||
}
|
||||
|
||||
|
||||
@@ -128,4 +128,5 @@ export async function handleDiscordModerationAction(
|
||||
return jsonResult({ ok: true });
|
||||
}
|
||||
}
|
||||
throw new Error("Unsupported Discord moderation action");
|
||||
}
|
||||
|
||||
@@ -52,6 +52,22 @@ type DiscordSubagentDeliveryTargetEvent = {
|
||||
};
|
||||
};
|
||||
|
||||
type DiscordSubagentSpawningResult =
|
||||
| { status: "ok"; threadBindingReady?: boolean }
|
||||
| { status: "error"; error: string }
|
||||
| undefined;
|
||||
|
||||
type DiscordSubagentDeliveryTargetResult =
|
||||
| {
|
||||
origin: {
|
||||
channel: "discord";
|
||||
accountId?: string;
|
||||
to: string;
|
||||
threadId?: string | number;
|
||||
};
|
||||
}
|
||||
| undefined;
|
||||
|
||||
function normalizeThreadBindingTargetKind(raw?: string): ThreadBindingTargetKind | undefined {
|
||||
const normalized = normalizeOptionalLowercaseString(raw);
|
||||
if (normalized === "subagent" || normalized === "acp") {
|
||||
@@ -84,13 +100,13 @@ function resolveThreadBindingFlags(api: OpenClawPluginApi, accountId?: string) {
|
||||
export async function handleDiscordSubagentSpawning(
|
||||
api: OpenClawPluginApi,
|
||||
event: DiscordSubagentSpawningEvent,
|
||||
) {
|
||||
): Promise<DiscordSubagentSpawningResult> {
|
||||
if (!event.threadRequested) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const channel = normalizeOptionalLowercaseString(event.requester?.channel);
|
||||
if (channel !== "discord") {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const threadBindingFlags = resolveThreadBindingFlags(api, event.requester?.accountId);
|
||||
if (!threadBindingFlags.enabled) {
|
||||
@@ -145,13 +161,15 @@ export function handleDiscordSubagentEnded(event: DiscordSubagentEndedEvent) {
|
||||
});
|
||||
}
|
||||
|
||||
export function handleDiscordSubagentDeliveryTarget(event: DiscordSubagentDeliveryTargetEvent) {
|
||||
export function handleDiscordSubagentDeliveryTarget(
|
||||
event: DiscordSubagentDeliveryTargetEvent,
|
||||
): DiscordSubagentDeliveryTargetResult {
|
||||
if (!event.expectsCompletionMessage) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const requesterChannel = normalizeOptionalLowercaseString(event.requesterOrigin?.channel);
|
||||
if (requesterChannel !== "discord") {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const requesterAccountId = event.requesterOrigin?.accountId?.trim();
|
||||
const requesterThreadId =
|
||||
@@ -164,7 +182,7 @@ export function handleDiscordSubagentDeliveryTarget(event: DiscordSubagentDelive
|
||||
targetKind: "subagent",
|
||||
});
|
||||
if (bindings.length === 0) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let binding: (typeof bindings)[number] | undefined;
|
||||
@@ -183,7 +201,7 @@ export function handleDiscordSubagentDeliveryTarget(event: DiscordSubagentDelive
|
||||
binding = bindings[0];
|
||||
}
|
||||
if (!binding) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
origin: {
|
||||
|
||||
@@ -270,16 +270,32 @@ type FeishuSubagentEndedEvent = {
|
||||
targetSessionKey: string;
|
||||
};
|
||||
|
||||
type FeishuSubagentSpawningResult =
|
||||
| { status: "ok"; threadBindingReady?: boolean }
|
||||
| { status: "error"; error: string }
|
||||
| undefined;
|
||||
|
||||
type FeishuSubagentDeliveryTargetResult =
|
||||
| {
|
||||
origin: {
|
||||
channel: "feishu";
|
||||
accountId?: string;
|
||||
to?: string;
|
||||
threadId?: string | number;
|
||||
};
|
||||
}
|
||||
| undefined;
|
||||
|
||||
export async function handleFeishuSubagentSpawning(
|
||||
event: FeishuSubagentSpawningEvent,
|
||||
ctx: FeishuSubagentContext,
|
||||
) {
|
||||
): Promise<FeishuSubagentSpawningResult> {
|
||||
if (!event.threadRequested) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const requesterChannel = normalizeOptionalLowercaseString(event.requester?.channel);
|
||||
if (requesterChannel !== "feishu") {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const manager = getFeishuThreadBindingManager(event.requester?.accountId);
|
||||
@@ -341,13 +357,15 @@ export async function handleFeishuSubagentSpawning(
|
||||
}
|
||||
}
|
||||
|
||||
export function handleFeishuSubagentDeliveryTarget(event: FeishuSubagentDeliveryTargetEvent) {
|
||||
export function handleFeishuSubagentDeliveryTarget(
|
||||
event: FeishuSubagentDeliveryTargetEvent,
|
||||
): FeishuSubagentDeliveryTargetResult {
|
||||
if (!event.expectsCompletionMessage) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const requesterChannel = normalizeOptionalLowercaseString(event.requesterOrigin?.channel);
|
||||
if (requesterChannel !== "feishu") {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const binding = resolveMatchingChildBinding({
|
||||
@@ -360,7 +378,7 @@ export function handleFeishuSubagentDeliveryTarget(event: FeishuSubagentDelivery
|
||||
},
|
||||
});
|
||||
if (!binding) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -456,18 +456,18 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
const readIngressPrefix = async () => {
|
||||
const selfUserId = await client.getUserId();
|
||||
if (senderId === selfUserId) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (dropPreStartupMessages) {
|
||||
if (typeof eventTs === "number" && eventTs < startupMs - startupGraceMs) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (
|
||||
typeof eventTs !== "number" &&
|
||||
typeof eventAge === "number" &&
|
||||
eventAge > startupGraceMs
|
||||
) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
})
|
||||
) {
|
||||
logVerboseMessage(`matrix: skip verification/system room message room=${roomId}`);
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const locationPayload: MatrixLocationPayload | null = resolveMatrixLocation({
|
||||
@@ -491,13 +491,13 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
|
||||
const relates = content["m.relates_to"];
|
||||
if (relates && "rel_type" in relates && relates.rel_type === RelationType.Replace) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (eventId && inboundDeduper) {
|
||||
claimedInboundEvent = inboundDeduper.claimEvent({ roomId, eventId });
|
||||
if (!claimedInboundEvent) {
|
||||
logVerboseMessage(`matrix: skip duplicate inbound event room=${roomId} id=${eventId}`);
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
const { locationPayload, selfUserId } = params;
|
||||
if (isRoom && groupPolicy === "disabled") {
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const roomInfoForConfig =
|
||||
@@ -553,24 +553,24 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
`matrix: drop configured bot sender=${senderId} (allowBots=false${isDirectMessage ? "" : `, ${roomMatchMeta}`})`,
|
||||
);
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (isRoom && roomConfig && !roomConfigInfo?.allowed) {
|
||||
logVerboseMessage(`matrix: room disabled room=${roomId} (${roomMatchMeta})`);
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (isRoom && groupPolicy === "allowlist") {
|
||||
if (!roomConfigInfo?.allowlistConfigured) {
|
||||
logVerboseMessage(`matrix: drop room message (no allowlist, ${roomMatchMeta})`);
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (!roomConfig) {
|
||||
logVerboseMessage(`matrix: drop room message (not in allowlist, ${roomMatchMeta})`);
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,7 +602,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
if (isDirectMessage) {
|
||||
if (!dmEnabled || dmPolicy === "disabled") {
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (dmPolicy !== "open") {
|
||||
const allowMatchMeta = formatAllowlistMatchMeta(directAllowMatch);
|
||||
@@ -643,7 +643,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
logVerboseMessage(
|
||||
`matrix pairing reply failed for ${senderId}: ${String(err)}`,
|
||||
);
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
} else {
|
||||
logVerboseMessage(
|
||||
@@ -658,7 +658,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
);
|
||||
await commitInboundEventIfClaimed();
|
||||
}
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -670,7 +670,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
)})`,
|
||||
);
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (
|
||||
isRoom &&
|
||||
@@ -686,7 +686,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
)})`,
|
||||
);
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (isRoom) {
|
||||
logVerboseMessage(`matrix: allow room ${roomId} (${roomMatchMeta})`);
|
||||
@@ -708,7 +708,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
logVerboseMessage,
|
||||
});
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let pollSnapshotPromise: Promise<MatrixPollSnapshot | null> | null = null;
|
||||
@@ -748,7 +748,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
: "";
|
||||
if (!mentionPrecheckText && !mediaUrl && !isPollEvent) {
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const _messageId = event.event_id ?? "";
|
||||
@@ -797,7 +797,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
`matrix: drop configured bot sender=${senderId} (allowBots=mentions, missing mention, ${roomMatchMeta})`,
|
||||
);
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const allowTextCommands = core.channel.commands.shouldHandleTextCommands({
|
||||
cfg,
|
||||
@@ -823,7 +823,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
target: senderId,
|
||||
});
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const shouldRequireMention = isRoom
|
||||
? roomConfig?.autoReply === true
|
||||
@@ -856,13 +856,13 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
}
|
||||
logger.info("skipping room message", { roomId, reason: "no-mention" });
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (isPollEvent) {
|
||||
const pollSnapshot = await getPollSnapshot();
|
||||
if (!pollSnapshot) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
content = {
|
||||
msgtype: "m.text",
|
||||
@@ -935,7 +935,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
});
|
||||
if (!bodyText) {
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const senderName = await getSenderName();
|
||||
if (_configuredBinding) {
|
||||
@@ -950,7 +950,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
reason: "configured ACP binding unavailable",
|
||||
target: _configuredBinding.spec.conversationId,
|
||||
});
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (_runtimeBindingId) {
|
||||
@@ -997,7 +997,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
? await runRoomIngress(roomId, async () => {
|
||||
const prefix = await readIngressPrefix();
|
||||
if (!prefix) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (prefix.isDirectMessage) {
|
||||
return { deferredPrefix: prefix } as const;
|
||||
@@ -1013,7 +1013,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
: await (async () => {
|
||||
const prefix = await readIngressPrefix();
|
||||
if (!prefix) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
return await continueIngress(prefix);
|
||||
})();
|
||||
|
||||
@@ -40,6 +40,8 @@ type MemorySearchResult = {
|
||||
score: number;
|
||||
};
|
||||
|
||||
type LegacyBeforeAgentStartContext = { prependContext: string } | undefined;
|
||||
|
||||
// ============================================================================
|
||||
// LanceDB Provider
|
||||
// ============================================================================
|
||||
@@ -536,9 +538,9 @@ export default definePluginEntry({
|
||||
|
||||
// Auto-recall: inject relevant memories before agent starts
|
||||
if (cfg.autoRecall) {
|
||||
api.on("before_agent_start", async (event) => {
|
||||
api.on("before_agent_start", async (event): Promise<LegacyBeforeAgentStartContext> => {
|
||||
if (!event.prompt || event.prompt.length < 5) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -546,7 +548,7 @@ export default definePluginEntry({
|
||||
const results = await db.search(vector, 3, 0.3);
|
||||
|
||||
if (results.length === 0) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
api.logger.info?.(`memory-lancedb: injecting ${results.length} memories into context`);
|
||||
@@ -559,6 +561,7 @@ export default definePluginEntry({
|
||||
} catch (err) {
|
||||
api.logger.warn(`memory-lancedb: recall failed: ${String(err)}`);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ function formatFreshnessLabel(freshness: WikiFreshness): string {
|
||||
case "unknown":
|
||||
return freshness.reason;
|
||||
}
|
||||
throw new Error("Unsupported wiki freshness level");
|
||||
}
|
||||
|
||||
function formatClaimIdentity(claim: WikiClaimHealth): string {
|
||||
@@ -761,6 +762,7 @@ function rankFreshnessLevel(level: WikiFreshnessLevel): number {
|
||||
case "unknown":
|
||||
return 0;
|
||||
}
|
||||
throw new Error("Unsupported wiki freshness level");
|
||||
}
|
||||
|
||||
function sortClaims(page: WikiPageSummary): WikiClaim[] {
|
||||
|
||||
@@ -64,7 +64,7 @@ export const nextcloudTalkSetupWizard: ChannelSetupWizard = {
|
||||
initialValue: hasApiCredentials,
|
||||
});
|
||||
if (!configureApiCredentials) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
credentialValues: {
|
||||
|
||||
@@ -73,6 +73,7 @@ export function cloneEvent(event: QaBusEvent): QaBusEvent {
|
||||
case "thread-created":
|
||||
return { ...event, thread: { ...event.thread } };
|
||||
}
|
||||
throw new Error("Unsupported QA bus event kind");
|
||||
}
|
||||
|
||||
export function buildQaBusSnapshot(params: {
|
||||
|
||||
@@ -501,6 +501,7 @@ async function sendQQBotTextChunk(params: {
|
||||
if (event.channelId) {
|
||||
return await sendChannelMessage(token, event.channelId, text, event.messageId);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async function sendTextChunks(
|
||||
|
||||
@@ -42,7 +42,7 @@ export const signalSetupWizard: ChannelSetupWizard = {
|
||||
}),
|
||||
prepare: async ({ cfg, accountId, credentialValues, runtime, prompter, options }) => {
|
||||
if (!options?.allowSignalInstall) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const currentCliPath =
|
||||
(typeof credentialValues.cliPath === "string" ? credentialValues.cliPath : undefined) ??
|
||||
@@ -56,7 +56,7 @@ export const signalSetupWizard: ChannelSetupWizard = {
|
||||
initialValue: !cliDetected,
|
||||
});
|
||||
if (!wantsInstall) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
const result = await installSignalCli(runtime);
|
||||
@@ -74,6 +74,7 @@ export const signalSetupWizard: ChannelSetupWizard = {
|
||||
} catch (error) {
|
||||
await prompter.note(`signal-cli install failed: ${String(error)}`, "Signal");
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
credentials: [],
|
||||
textInputs: [
|
||||
|
||||
@@ -257,7 +257,7 @@ export function createSlackSetupWizardBase(handlers: {
|
||||
}),
|
||||
finalize: async ({ cfg, accountId, options, prompter }) => {
|
||||
if (hasSlackInteractiveRepliesConfig(cfg, accountId)) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (options?.quickstartDefaults) {
|
||||
return {
|
||||
|
||||
@@ -13,6 +13,7 @@ type ThreadOwnershipConfig = {
|
||||
};
|
||||
|
||||
type AgentEntry = NonNullable<NonNullable<OpenClawConfig["agents"]>["list"]>[number];
|
||||
type ThreadOwnershipMessageSendingResult = { cancel: true } | undefined;
|
||||
|
||||
// In-memory set of {channel}:{thread} keys where this agent was @-mentioned.
|
||||
// Entries expire after 5 minutes.
|
||||
@@ -86,23 +87,23 @@ export default definePluginEntry({
|
||||
}
|
||||
});
|
||||
|
||||
api.on("message_sending", async (event, ctx) => {
|
||||
api.on("message_sending", async (event, ctx): Promise<ThreadOwnershipMessageSendingResult> => {
|
||||
if (ctx.channelId !== "slack") {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const threadTs = (event.metadata?.threadTs as string) ?? "";
|
||||
const channelId = (event.metadata?.channelId as string) ?? event.to;
|
||||
if (!threadTs) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (abTestChannels.size > 0 && !abTestChannels.has(channelId)) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
cleanExpiredMentions();
|
||||
if (mentionedThreads.has(`${channelId}:${threadTs}`)) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -122,7 +123,7 @@ export default definePluginEntry({
|
||||
|
||||
try {
|
||||
if (resp.ok) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (resp.status === 409) {
|
||||
const body = (await resp.json()) as { owner?: string };
|
||||
@@ -140,6 +141,7 @@ export default definePluginEntry({
|
||||
`thread-ownership: ownership check failed (${String(err)}), allowing send`,
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -352,6 +352,7 @@ export function createTlonApprovalRuntime(params: {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
throw new Error("Unsupported Tlon admin command");
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -92,6 +92,7 @@ export function formatApprovalRequest(approval: PendingApproval): string {
|
||||
`(ID: ${approval.id})`
|
||||
);
|
||||
}
|
||||
throw new Error("Unsupported approval type");
|
||||
}
|
||||
|
||||
export type ApprovalResponse = {
|
||||
@@ -211,6 +212,7 @@ export function formatApprovalConfirmation(
|
||||
}
|
||||
return `${actionText} group invite from ${approval.requestingShip} to ${approval.groupFlag}.`;
|
||||
}
|
||||
throw new Error("Unsupported approval type");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -658,6 +658,7 @@ async function executeWebhookAction(params: {
|
||||
};
|
||||
}
|
||||
}
|
||||
throw new Error("Unsupported webhook action");
|
||||
}
|
||||
|
||||
export function createTaskFlowWebhookRequestHandler(params: {
|
||||
|
||||
@@ -173,9 +173,9 @@ function startPollingLoop(params: ZaloPollingLoopParams) {
|
||||
|
||||
runtime.log?.(`[${account.accountId}] Zalo polling loop started timeout=${String(pollTimeout)}s`);
|
||||
|
||||
const poll = async () => {
|
||||
const poll = async (): Promise<void> => {
|
||||
if (isStopped() || abortSignal.aborted) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -209,7 +209,7 @@ async function processUpdate(params: ZaloUpdateProcessingParams): Promise<void>
|
||||
const { event_name, message } = update;
|
||||
const sharedContext = { token, account, config, runtime, core, statusSink, fetcher };
|
||||
if (!message) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
switch (event_name) {
|
||||
@@ -245,7 +245,7 @@ async function handleTextMessage(
|
||||
const { message } = params;
|
||||
const { text } = message;
|
||||
if (!text?.trim()) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await processMessageWithPipeline({
|
||||
@@ -350,7 +350,7 @@ async function authorizeZaloMessage(
|
||||
} else if (groupAccess.reason === "sender_not_allowlisted") {
|
||||
logVerbose(core, runtime, `zalo: drop group sender ${senderId} (groupPolicy=allowlist)`);
|
||||
}
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,7 +376,7 @@ async function authorizeZaloMessage(
|
||||
});
|
||||
if (directDmOutcome === "disabled") {
|
||||
logVerbose(core, runtime, `Blocked zalo DM from ${senderId} (dmPolicy=disabled)`);
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
if (directDmOutcome === "unauthorized") {
|
||||
if (dmPolicy === "pairing") {
|
||||
@@ -409,7 +409,7 @@ async function authorizeZaloMessage(
|
||||
`Blocked unauthorized zalo sender ${senderId} (dmPolicy=${dmPolicy})`,
|
||||
);
|
||||
}
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -193,6 +193,7 @@ async function resolveInstallation(
|
||||
fail(
|
||||
`missing repo context; pass -R owner/repo, set GH_REPO, or set ${INSTALLATION_ID_ENV} for a direct installation lookup`,
|
||||
);
|
||||
throw new Error("unreachable");
|
||||
}
|
||||
|
||||
async function createInstallationToken(
|
||||
|
||||
@@ -413,4 +413,5 @@ export function filterRecordsForReport(
|
||||
case "public-surface-usage":
|
||||
return records;
|
||||
}
|
||||
throw new Error("Unsupported topology report");
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ function extractOwner(relPath: string): string | null {
|
||||
case "test":
|
||||
return null;
|
||||
}
|
||||
throw new Error("Unsupported topology scope");
|
||||
}
|
||||
|
||||
function extractExtensionId(relPath: string): string | null {
|
||||
|
||||
@@ -25,7 +25,8 @@ export function installProcessWarningFilter() {
|
||||
return;
|
||||
}
|
||||
|
||||
return Reflect.apply(originalEmitWarning, process, args);
|
||||
Reflect.apply(originalEmitWarning, process, args);
|
||||
return;
|
||||
};
|
||||
|
||||
globalThis[warningFilterKey] = { installed: true };
|
||||
|
||||
@@ -465,6 +465,7 @@ export function formatExecFailureReason(params: {
|
||||
case "aborted":
|
||||
return "Command aborted before exit code was captured";
|
||||
}
|
||||
throw new Error("Unsupported exec failure kind");
|
||||
}
|
||||
|
||||
export function buildExecExitOutcome(params: {
|
||||
|
||||
@@ -285,6 +285,7 @@ describe("exec approvals", () => {
|
||||
invokeParams = params;
|
||||
return { payload: { success: true, stdout: "ok" } };
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ function encodeAuthProfileCredential(credential: AuthProfileCredential): string
|
||||
credential.managedBy ?? null,
|
||||
]);
|
||||
}
|
||||
throw new Error("Unsupported auth profile credential type");
|
||||
}
|
||||
|
||||
function getLocalCliCredentialFingerprint(provider: string): string | undefined {
|
||||
|
||||
@@ -209,6 +209,7 @@ function resolveThinkingLevel(level: ThinkingLevel, modelId: string): GoogleThin
|
||||
case "xhigh":
|
||||
return "HIGH";
|
||||
}
|
||||
throw new Error("Unsupported thinking level");
|
||||
}
|
||||
|
||||
function getDisabledThinkingConfig(modelId: string): Record<string, unknown> {
|
||||
|
||||
@@ -883,7 +883,7 @@ export async function runWithModelFallback<T>(params: {
|
||||
}
|
||||
}
|
||||
|
||||
throwFallbackFailureSummary({
|
||||
return throwFallbackFailureSummary({
|
||||
attempts,
|
||||
candidates,
|
||||
lastError,
|
||||
@@ -945,7 +945,7 @@ export async function runWithImageModelFallback<T>(params: {
|
||||
}
|
||||
}
|
||||
|
||||
throwFallbackFailureSummary({
|
||||
return throwFallbackFailureSummary({
|
||||
attempts,
|
||||
candidates,
|
||||
lastError,
|
||||
|
||||
@@ -35,7 +35,7 @@ export function handleAgentStart(ctx: EmbeddedPiSubscribeContext) {
|
||||
});
|
||||
}
|
||||
|
||||
export function handleAgentEnd(ctx: EmbeddedPiSubscribeContext) {
|
||||
export function handleAgentEnd(ctx: EmbeddedPiSubscribeContext): void | Promise<void> {
|
||||
const lastAssistant = ctx.state.lastAssistant;
|
||||
const isError = isAssistantMessage(lastAssistant) && lastAssistant.stopReason === "error";
|
||||
let lifecycleErrorText: string | undefined;
|
||||
@@ -136,6 +136,7 @@ export function handleAgentEnd(ctx: EmbeddedPiSubscribeContext) {
|
||||
if (isPromiseLike<void>(onBlockReplyFlushResult)) {
|
||||
return onBlockReplyFlushResult;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -143,6 +144,7 @@ export function handleAgentEnd(ctx: EmbeddedPiSubscribeContext) {
|
||||
if (isPromiseLike<void>(onBlockReplyFlushResult)) {
|
||||
return onBlockReplyFlushResult;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
let lifecycleTerminalEmitted = false;
|
||||
@@ -172,4 +174,5 @@ export function handleAgentEnd(ctx: EmbeddedPiSubscribeContext) {
|
||||
}
|
||||
|
||||
emitLifecycleTerminalOnce();
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ export function handleMessageUpdate(
|
||||
export function handleMessageEnd(
|
||||
ctx: EmbeddedPiSubscribeContext,
|
||||
evt: AgentEvent & { message: AgentMessage },
|
||||
) {
|
||||
): void | Promise<void> {
|
||||
const msg = evt.message;
|
||||
if (msg?.role !== "assistant" || isTranscriptOnlyOpenClawAssistantMessage(msg)) {
|
||||
return;
|
||||
@@ -659,6 +659,7 @@ export function handleMessageEnd(
|
||||
if (isPromiseLike<void>(onBlockReplyFlushResult)) {
|
||||
return onBlockReplyFlushResult;
|
||||
}
|
||||
return undefined;
|
||||
})
|
||||
.finally(() => {
|
||||
finalizeMessageEnd();
|
||||
@@ -673,4 +674,5 @@ export function handleMessageEnd(
|
||||
}
|
||||
|
||||
finalizeMessageEnd();
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -523,8 +523,8 @@ async function emitToolResultOutput(params: {
|
||||
export function handleToolExecutionStart(
|
||||
ctx: ToolHandlerContext,
|
||||
evt: AgentEvent & { toolName: string; toolCallId: string; args: unknown },
|
||||
) {
|
||||
const continueAfterBlockReplyFlush = () => {
|
||||
): void | Promise<void> {
|
||||
const continueAfterBlockReplyFlush = (): void | Promise<void> => {
|
||||
const onBlockReplyFlushResult = ctx.params.onBlockReplyFlush?.();
|
||||
if (isPromiseLike<void>(onBlockReplyFlushResult)) {
|
||||
return onBlockReplyFlushResult.then(() => {
|
||||
@@ -532,6 +532,7 @@ export function handleToolExecutionStart(
|
||||
});
|
||||
}
|
||||
continueToolExecutionStart();
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const continueToolExecutionStart = () => {
|
||||
|
||||
@@ -338,6 +338,7 @@ export function stripShellPreamble(command: string): PreambleResult {
|
||||
first = { index: idx, length: 1 };
|
||||
return false;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
const head = (first ? rest.slice(0, first.index) : rest).trim();
|
||||
const isChdir = (first ? !first.isOr : i > 0) && isChdirCommand(head);
|
||||
|
||||
@@ -154,6 +154,7 @@ export async function executeNodeCommandAction(params: {
|
||||
return jsonResult(raw ?? {});
|
||||
}
|
||||
}
|
||||
throw new Error("Unsupported node command action");
|
||||
}
|
||||
|
||||
export async function invokeNodeCommandPayload(params: {
|
||||
|
||||
@@ -52,6 +52,7 @@ export async function executeNodeMediaAction(
|
||||
case "screen_record":
|
||||
return await executeScreenRecord(input);
|
||||
}
|
||||
throw new Error("Unsupported node media action");
|
||||
}
|
||||
|
||||
async function executeCameraSnap({
|
||||
|
||||
@@ -315,6 +315,7 @@ function describeUnsupportedSearchFilter(name: UnsupportedWebSearchFilterName):
|
||||
case "date_before":
|
||||
return "date_after/date_before filtering";
|
||||
}
|
||||
throw new Error("Unsupported web search filter");
|
||||
}
|
||||
|
||||
export function buildUnsupportedSearchFilterResponse(
|
||||
|
||||
@@ -172,6 +172,7 @@ function setFallbackSelectionStateField(
|
||||
}
|
||||
return false;
|
||||
}
|
||||
throw new Error("Unsupported fallback selection state key");
|
||||
}
|
||||
|
||||
function snapshotFallbackSelectionState(entry: SessionEntry): FallbackSelectionState {
|
||||
@@ -628,19 +629,22 @@ export async function runAgentTurnWithFallback(params: {
|
||||
let bootstrapPromptWarningSignaturesSeen = resolveBootstrapWarningSignaturesSeen(
|
||||
params.getActiveSessionEntry()?.systemPromptReport,
|
||||
);
|
||||
const persistFallbackCandidateSelection = async (provider: string, model: string) => {
|
||||
const persistFallbackCandidateSelection = async (
|
||||
provider: string,
|
||||
model: string,
|
||||
): Promise<(() => Promise<void>) | undefined> => {
|
||||
if (
|
||||
!params.sessionKey ||
|
||||
!params.activeSessionStore ||
|
||||
(provider === params.followupRun.run.provider && model === params.followupRun.run.model)
|
||||
) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const activeSessionEntry =
|
||||
params.getActiveSessionEntry() ?? params.activeSessionStore[params.sessionKey];
|
||||
if (!activeSessionEntry) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const previousState = snapshotFallbackSelectionState(activeSessionEntry);
|
||||
@@ -652,7 +656,7 @@ export async function runAgentTurnWithFallback(params: {
|
||||
});
|
||||
const nextState = applied.nextState;
|
||||
if (!applied.updated || !nextState) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
params.activeSessionStore[params.sessionKey] = activeSessionEntry;
|
||||
|
||||
|
||||
@@ -727,7 +727,7 @@ export async function dispatchReplyFromConfig(params: {
|
||||
}
|
||||
return parts.join("\n\n").trim() || "Planning next steps.";
|
||||
};
|
||||
const maybeSendWorkingStatus = (label: string) => {
|
||||
const maybeSendWorkingStatus = async (label: string): Promise<void> => {
|
||||
const normalizedLabel = normalizeWorkingLabel(label);
|
||||
if (
|
||||
!shouldEmitVerboseProgress() ||
|
||||
@@ -744,11 +744,15 @@ export async function dispatchReplyFromConfig(params: {
|
||||
text: `Working: ${normalizedLabel}`,
|
||||
};
|
||||
if (shouldRouteToOriginating) {
|
||||
return sendPayloadAsync(payload, undefined, false);
|
||||
await sendPayloadAsync(payload, undefined, false);
|
||||
return;
|
||||
}
|
||||
dispatcher.sendToolResult(payload);
|
||||
};
|
||||
const sendPlanUpdate = (payload: { explanation?: string; steps?: string[] }) => {
|
||||
const sendPlanUpdate = async (payload: {
|
||||
explanation?: string;
|
||||
steps?: string[];
|
||||
}): Promise<void> => {
|
||||
if (!shouldEmitVerboseProgress()) {
|
||||
return;
|
||||
}
|
||||
@@ -756,7 +760,8 @@ export async function dispatchReplyFromConfig(params: {
|
||||
text: formatPlanUpdateText(payload),
|
||||
};
|
||||
if (shouldRouteToOriginating) {
|
||||
return sendPayloadAsync(replyPayload, undefined, false);
|
||||
await sendPayloadAsync(replyPayload, undefined, false);
|
||||
return;
|
||||
}
|
||||
dispatcher.sendToolResult(replyPayload);
|
||||
};
|
||||
@@ -866,13 +871,13 @@ export async function dispatchReplyFromConfig(params: {
|
||||
};
|
||||
return run();
|
||||
},
|
||||
onPlanUpdate: ({ phase, explanation, steps }) => {
|
||||
onPlanUpdate: async ({ phase, explanation, steps }) => {
|
||||
if (phase !== "update") {
|
||||
return;
|
||||
}
|
||||
return sendPlanUpdate({ explanation, steps });
|
||||
await sendPlanUpdate({ explanation, steps });
|
||||
},
|
||||
onApprovalEvent: ({ phase, status, command, message }) => {
|
||||
onApprovalEvent: async ({ phase, status, command, message }) => {
|
||||
if (phase !== "requested") {
|
||||
return;
|
||||
}
|
||||
@@ -880,9 +885,9 @@ export async function dispatchReplyFromConfig(params: {
|
||||
if (!label) {
|
||||
return;
|
||||
}
|
||||
return maybeSendWorkingStatus(label);
|
||||
await maybeSendWorkingStatus(label);
|
||||
},
|
||||
onPatchSummary: ({ phase, summary, title }) => {
|
||||
onPatchSummary: async ({ phase, summary, title }) => {
|
||||
if (phase !== "end") {
|
||||
return;
|
||||
}
|
||||
@@ -890,7 +895,7 @@ export async function dispatchReplyFromConfig(params: {
|
||||
if (!label) {
|
||||
return;
|
||||
}
|
||||
return maybeSendWorkingStatus(label);
|
||||
await maybeSendWorkingStatus(label);
|
||||
},
|
||||
onBlockReply: (payload: ReplyPayload, context?: BlockReplyContext) => {
|
||||
const run = async () => {
|
||||
|
||||
@@ -205,7 +205,7 @@ export async function runDaemonRestart(opts: DaemonLifecycleOptions = {}): Promi
|
||||
delayMs: POST_RESTART_HEALTH_DELAY_MS,
|
||||
});
|
||||
if (health.healthy) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const diagnostics = renderGatewayPortHealthDiagnostics(health);
|
||||
@@ -224,6 +224,7 @@ export async function runDaemonRestart(opts: DaemonLifecycleOptions = {}): Promi
|
||||
formatCliCommand("openclaw gateway status --deep"),
|
||||
formatCliCommand("openclaw doctor"),
|
||||
]);
|
||||
throw new Error("unreachable after gateway restart health failure");
|
||||
}
|
||||
|
||||
let health = await waitForGatewayHealthyRestart({
|
||||
@@ -257,7 +258,7 @@ export async function runDaemonRestart(opts: DaemonLifecycleOptions = {}): Promi
|
||||
}
|
||||
|
||||
if (health.healthy) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const diagnostics = renderRestartDiagnostics(health);
|
||||
@@ -290,6 +291,7 @@ export async function runDaemonRestart(opts: DaemonLifecycleOptions = {}): Promi
|
||||
formatCliCommand("openclaw gateway status --deep"),
|
||||
formatCliCommand("openclaw doctor"),
|
||||
]);
|
||||
throw new Error("unreachable after gateway restart failure");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ function backupAssetPriority(kind: BackupAssetKind): number {
|
||||
case "workspace":
|
||||
return 3;
|
||||
}
|
||||
throw new Error("Unsupported backup asset kind");
|
||||
}
|
||||
|
||||
export function buildBackupArchiveRoot(nowMs = Date.now()): string {
|
||||
|
||||
@@ -60,6 +60,7 @@ function execSecurityRank(value: ExecSecurity): number {
|
||||
case "full":
|
||||
return 2;
|
||||
}
|
||||
throw new Error("Unsupported exec security value");
|
||||
}
|
||||
|
||||
function execAskRank(value: ExecAsk): number {
|
||||
@@ -71,6 +72,7 @@ function execAskRank(value: ExecAsk): number {
|
||||
case "always":
|
||||
return 2;
|
||||
}
|
||||
throw new Error("Unsupported exec ask value");
|
||||
}
|
||||
|
||||
function collectExecPolicyConflictWarnings(cfg: OpenClawConfig): string[] {
|
||||
|
||||
@@ -339,6 +339,7 @@ export function resolvePluginAutoEnableCandidateReason(
|
||||
case "setup-auto-enable":
|
||||
return candidate.reason;
|
||||
}
|
||||
throw new Error("Unsupported plugin auto-enable candidate");
|
||||
}
|
||||
|
||||
export function resolveConfiguredPluginAutoEnableCandidates(params: {
|
||||
|
||||
@@ -78,6 +78,7 @@ vi.mock("node:fs", async () => {
|
||||
return await actual.promises.mkdir(p, { recursive: true });
|
||||
}
|
||||
ensureDir(p);
|
||||
return undefined;
|
||||
},
|
||||
readFile: async (p: string) => {
|
||||
if (!isFixtureInMock(p)) {
|
||||
@@ -164,6 +165,7 @@ vi.mock("node:fs/promises", async () => {
|
||||
return await actual.mkdir(p, { recursive: true });
|
||||
}
|
||||
ensureDir(p);
|
||||
return undefined;
|
||||
},
|
||||
writeFile: async (p: string, data: string, _enc?: unknown) => {
|
||||
if (!isFixturePath(p)) {
|
||||
|
||||
@@ -144,7 +144,7 @@ export async function generateImage(
|
||||
}
|
||||
}
|
||||
|
||||
throwCapabilityGenerationFailure({
|
||||
return throwCapabilityGenerationFailure({
|
||||
capabilityLabel: "image generation",
|
||||
attempts,
|
||||
lastError,
|
||||
|
||||
@@ -108,6 +108,7 @@ export function matchBoundaryFileOpenFailure<T>(
|
||||
case "io":
|
||||
return handlers.io ? handlers.io(failure) : handlers.fallback(failure);
|
||||
}
|
||||
return handlers.fallback(failure);
|
||||
}
|
||||
|
||||
function openBoundaryFileResolved(params: {
|
||||
|
||||
@@ -137,6 +137,7 @@ export function formatDevicePairingForbiddenMessage(result: DevicePairingForbidd
|
||||
case "bootstrap-scope-not-allowed":
|
||||
return `bootstrap profile does not allow scope: ${result.scope ?? "unknown"}`;
|
||||
}
|
||||
throw new Error("Unsupported device pairing forbidden reason");
|
||||
}
|
||||
|
||||
async function loadState(baseDir?: string): Promise<DevicePairingStateFile> {
|
||||
|
||||
@@ -34,6 +34,7 @@ export function resolveIndicatorType(
|
||||
case "skipped":
|
||||
return undefined;
|
||||
}
|
||||
throw new Error("Unsupported heartbeat status");
|
||||
}
|
||||
|
||||
type HeartbeatEventState = {
|
||||
|
||||
@@ -195,6 +195,7 @@ function extractShellWrapperPayload(argv: string[], spec: ShellWrapperSpec): str
|
||||
case "powershell":
|
||||
return extractPowerShellInlineCommand(argv);
|
||||
}
|
||||
throw new Error("Unsupported shell wrapper kind");
|
||||
}
|
||||
|
||||
function hasEnvManipulationBeforeShellWrapperInternal(
|
||||
|
||||
@@ -91,7 +91,8 @@ export function installProcessWarningFilter(): void {
|
||||
process.emit("warning", emitted);
|
||||
return;
|
||||
}
|
||||
return Reflect.apply(originalEmitWarning, process, args);
|
||||
Reflect.apply(originalEmitWarning, process, args);
|
||||
return;
|
||||
}) as typeof process.emitWarning;
|
||||
|
||||
process.emitWarning = wrappedEmitWarning;
|
||||
|
||||
@@ -64,6 +64,7 @@ export function formatTimestamp(date: Date, options?: FormatTimestampOptions): s
|
||||
case "long":
|
||||
return `${parts.year}-${parts.month}-${parts.day}T${parts.hour}:${parts.minute}:${parts.second}.${parts.fractionalSecond}${parts.offset}`;
|
||||
}
|
||||
throw new Error("Unsupported timestamp style");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -146,7 +146,7 @@ export async function generateMusic(
|
||||
}
|
||||
}
|
||||
|
||||
throwCapabilityGenerationFailure({
|
||||
return throwCapabilityGenerationFailure({
|
||||
capabilityLabel: "music generation",
|
||||
attempts,
|
||||
lastError,
|
||||
|
||||
@@ -151,4 +151,5 @@ export function buildProviderReplayFamilyHooks(
|
||||
}),
|
||||
};
|
||||
}
|
||||
throw new Error("Unsupported provider replay family");
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@ export function buildProviderStreamFamilyHooks(
|
||||
createToolStreamWrapper(ctx.streamFn, ctx.extraParams?.tool_stream !== false),
|
||||
};
|
||||
}
|
||||
throw new Error("Unsupported provider stream family");
|
||||
}
|
||||
|
||||
// Public stream-wrapper helpers for provider plugins.
|
||||
|
||||
@@ -172,4 +172,5 @@ export function buildProviderToolCompatFamilyHooks(family: ProviderToolCompatFam
|
||||
inspectToolSchemas: inspectGeminiToolSchemas,
|
||||
};
|
||||
}
|
||||
throw new Error("Unsupported provider tool compatibility family");
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ function createSearchCredentialFields(
|
||||
setCredentialValue: () => {},
|
||||
};
|
||||
}
|
||||
throw new Error("Unsupported web search credential type");
|
||||
}
|
||||
|
||||
function createConfiguredCredentialFields(
|
||||
|
||||
@@ -192,6 +192,7 @@ function resolveBundledManifestPluginIdsForContract(contract: ManifestContractKe
|
||||
case "tools":
|
||||
return entry.toolNames.length > 0;
|
||||
}
|
||||
throw new Error("Unsupported manifest contract key");
|
||||
})
|
||||
.map((entry) => entry.pluginId),
|
||||
).toSorted((left, right) => left.localeCompare(right));
|
||||
|
||||
@@ -665,6 +665,7 @@ describe("discoverOpenClawPlugins", () => {
|
||||
packageName: "@openclaw/missing-entry-pack",
|
||||
extensions: ["./missing.ts"],
|
||||
});
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -688,6 +689,7 @@ describe("discoverOpenClawPlugins", () => {
|
||||
packageName: "@openclaw/pack",
|
||||
extensions: ["./linked/escape.ts"],
|
||||
});
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -718,6 +720,7 @@ describe("discoverOpenClawPlugins", () => {
|
||||
packageName: "@openclaw/pack",
|
||||
extensions: ["./escape.ts"],
|
||||
});
|
||||
return true;
|
||||
},
|
||||
},
|
||||
] as const)("$name", async ({ setup, expectedDiagnostic, expectedId }) => {
|
||||
|
||||
@@ -250,6 +250,7 @@ function marketplaceEntrySourceToInput(source: MarketplaceEntrySource): string {
|
||||
case "url":
|
||||
return source.url;
|
||||
}
|
||||
throw new Error("Unsupported marketplace entry source");
|
||||
}
|
||||
|
||||
function parseMarketplaceManifest(
|
||||
|
||||
@@ -22,6 +22,7 @@ function scopeRank(scope: typeof pluginRegistryLoaded): number {
|
||||
case "all":
|
||||
return 3;
|
||||
}
|
||||
throw new Error("Unsupported plugin registry scope");
|
||||
}
|
||||
|
||||
function activeRegistrySatisfiesScope(
|
||||
@@ -50,6 +51,7 @@ function activeRegistrySatisfiesScope(
|
||||
case "all":
|
||||
return false;
|
||||
}
|
||||
throw new Error("Unsupported plugin registry scope");
|
||||
}
|
||||
|
||||
export function ensurePluginRegistryLoaded(options?: {
|
||||
|
||||
@@ -817,7 +817,7 @@ async function resolveProviderRefs(params: {
|
||||
message: `Unsupported secret provider source "${String((params.providerConfig as { source?: unknown }).source)}".`,
|
||||
});
|
||||
} catch (err) {
|
||||
throwUnknownProviderResolutionError({
|
||||
return throwUnknownProviderResolutionError({
|
||||
source: params.source,
|
||||
provider: params.providerName,
|
||||
err,
|
||||
|
||||
@@ -156,7 +156,7 @@ export async function generateVideo(
|
||||
}
|
||||
}
|
||||
|
||||
throwCapabilityGenerationFailure({
|
||||
return throwCapabilityGenerationFailure({
|
||||
capabilityLabel: "video generation",
|
||||
attempts,
|
||||
lastError,
|
||||
|
||||
@@ -729,17 +729,21 @@ export function renderApp(state: AppViewState) {
|
||||
}
|
||||
switch (state.agentsPanel) {
|
||||
case "files":
|
||||
return void loadAgentFiles(state, agentId);
|
||||
void loadAgentFiles(state, agentId);
|
||||
return;
|
||||
case "skills":
|
||||
return void loadAgentSkills(state, agentId);
|
||||
void loadAgentSkills(state, agentId);
|
||||
return;
|
||||
case "tools":
|
||||
void loadToolsCatalog(state, agentId);
|
||||
return void refreshVisibleToolsEffectiveForCurrentSession(state);
|
||||
void refreshVisibleToolsEffectiveForCurrentSession(state);
|
||||
return;
|
||||
}
|
||||
};
|
||||
const refreshAgentsPanelSupplementalData = (panel: AppViewState["agentsPanel"]) => {
|
||||
if (panel === "channels") {
|
||||
return void loadChannels(state, false);
|
||||
void loadChannels(state, false);
|
||||
return;
|
||||
}
|
||||
if (panel === "cron") {
|
||||
void state.loadCron();
|
||||
|
||||
@@ -272,13 +272,17 @@ async function refreshAgentsTab(host: SettingsHost, app: SettingsAppHost) {
|
||||
void loadAgentIdentity(app, agentId);
|
||||
switch (host.agentsPanel) {
|
||||
case "files":
|
||||
return void loadAgentFiles(app, agentId);
|
||||
void loadAgentFiles(app, agentId);
|
||||
return;
|
||||
case "skills":
|
||||
return void loadAgentSkills(app, agentId);
|
||||
void loadAgentSkills(app, agentId);
|
||||
return;
|
||||
case "channels":
|
||||
return void loadChannels(app, false);
|
||||
void loadChannels(app, false);
|
||||
return;
|
||||
case "cron":
|
||||
return void loadCron(host);
|
||||
void loadCron(host);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -196,11 +196,11 @@ export function refreshVisibleToolsEffectiveForCurrentSession(
|
||||
): Promise<void> | undefined {
|
||||
const resolvedSessionKey = state.sessionKey?.trim();
|
||||
if (!resolvedSessionKey || state.agentsPanel !== "tools" || !state.agentsSelectedId) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
const sessionAgentId = resolveAgentIdFromSessionKey(resolvedSessionKey);
|
||||
if (!sessionAgentId || state.agentsSelectedId !== sessionAgentId) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
return loadToolsEffective(state, {
|
||||
agentId: sessionAgentId,
|
||||
|
||||
@@ -160,6 +160,7 @@ const cjkAutoLinkExtension = {
|
||||
],
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ function skillMatchesStatus(skill: SkillStatusEntry, status: SkillsStatusFilter)
|
||||
case "disabled":
|
||||
return skill.disabled;
|
||||
}
|
||||
throw new Error("Unsupported skills status filter");
|
||||
}
|
||||
|
||||
function skillStatusClass(skill: SkillStatusEntry): string {
|
||||
|
||||
Reference in New Issue
Block a user