mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
refactor(runtime): split runtime builders and stabilize cron tool seam
This commit is contained in:
@@ -1,11 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { callGatewayMock } = vi.hoisted(() => ({
|
||||
callGatewayMock: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../../gateway/call.js", () => ({
|
||||
callGateway: (opts: unknown) => callGatewayMock(opts),
|
||||
const { callGatewayToolMock } = vi.hoisted(() => ({
|
||||
callGatewayToolMock: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../agent-scope.js", () => ({
|
||||
@@ -16,12 +12,15 @@ import { createCronTool } from "./cron-tool.js";
|
||||
|
||||
describe("cron tool flat-params", () => {
|
||||
beforeEach(() => {
|
||||
callGatewayMock.mockReset();
|
||||
callGatewayMock.mockResolvedValue({ ok: true });
|
||||
callGatewayToolMock.mockReset();
|
||||
callGatewayToolMock.mockResolvedValue({ ok: true });
|
||||
});
|
||||
|
||||
it("preserves explicit top-level sessionKey during flat-params recovery", async () => {
|
||||
const tool = createCronTool({ agentSessionKey: "agent:main:discord:channel:ops" });
|
||||
const tool = createCronTool(
|
||||
{ agentSessionKey: "agent:main:discord:channel:ops" },
|
||||
{ callGatewayTool: callGatewayToolMock },
|
||||
);
|
||||
await tool.execute("call-flat-session-key", {
|
||||
action: "add",
|
||||
sessionKey: "agent:main:telegram:group:-100123:topic:99",
|
||||
@@ -29,11 +28,12 @@ describe("cron tool flat-params", () => {
|
||||
message: "do stuff",
|
||||
});
|
||||
|
||||
const call = callGatewayMock.mock.calls[0]?.[0] as {
|
||||
method?: string;
|
||||
params?: { sessionKey?: string };
|
||||
};
|
||||
expect(call.method).toBe("cron.add");
|
||||
expect(call.params?.sessionKey).toBe("agent:main:telegram:group:-100123:topic:99");
|
||||
const [method, _gatewayOpts, params] = callGatewayToolMock.mock.calls[0] as [
|
||||
string,
|
||||
unknown,
|
||||
{ sessionKey?: string },
|
||||
];
|
||||
expect(method).toBe("cron.add");
|
||||
expect(params.sessionKey).toBe("agent:main:telegram:group:-100123:topic:99");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import type { CronDelivery, CronMessageChannel } from "../../cron/types.js";
|
||||
import { loadConfig } from "../../config/config.js";
|
||||
import { normalizeCronJobCreate, normalizeCronJobPatch } from "../../cron/normalize.js";
|
||||
import type { CronDelivery, CronMessageChannel } from "../../cron/types.js";
|
||||
import { normalizeHttpWebhookUrl } from "../../cron/webhook-url.js";
|
||||
import { parseAgentSessionKey } from "../../sessions/session-key-utils.js";
|
||||
import { extractTextFromChatContent } from "../../shared/chat-content.js";
|
||||
@@ -50,6 +50,12 @@ type CronToolOptions = {
|
||||
agentSessionKey?: string;
|
||||
};
|
||||
|
||||
type GatewayToolCaller = typeof callGatewayTool;
|
||||
|
||||
type CronToolDeps = {
|
||||
callGatewayTool?: GatewayToolCaller;
|
||||
};
|
||||
|
||||
type ChatMessage = {
|
||||
role?: unknown;
|
||||
content?: unknown;
|
||||
@@ -84,6 +90,7 @@ async function buildReminderContextLines(params: {
|
||||
agentSessionKey?: string;
|
||||
gatewayOpts: GatewayCallOptions;
|
||||
contextMessages: number;
|
||||
callGatewayTool: GatewayToolCaller;
|
||||
}) {
|
||||
const maxMessages = Math.min(
|
||||
REMINDER_CONTEXT_MESSAGES_MAX,
|
||||
@@ -100,7 +107,7 @@ async function buildReminderContextLines(params: {
|
||||
const { mainKey, alias } = resolveMainSessionAlias(cfg);
|
||||
const resolvedKey = resolveInternalSessionKey({ key: sessionKey, alias, mainKey });
|
||||
try {
|
||||
const res = await callGatewayTool<{ messages: Array<unknown> }>(
|
||||
const res = await params.callGatewayTool<{ messages: Array<unknown> }>(
|
||||
"chat.history",
|
||||
params.gatewayOpts,
|
||||
{
|
||||
@@ -197,7 +204,8 @@ function inferDeliveryFromSessionKey(agentSessionKey?: string): CronDelivery | n
|
||||
return delivery;
|
||||
}
|
||||
|
||||
export function createCronTool(opts?: CronToolOptions): AnyAgentTool {
|
||||
export function createCronTool(opts?: CronToolOptions, deps?: CronToolDeps): AnyAgentTool {
|
||||
const callGateway = deps?.callGatewayTool ?? callGatewayTool;
|
||||
return {
|
||||
label: "Cron",
|
||||
name: "cron",
|
||||
@@ -272,10 +280,10 @@ Use jobId as the canonical identifier; id is accepted for compatibility. Use con
|
||||
|
||||
switch (action) {
|
||||
case "status":
|
||||
return jsonResult(await callGatewayTool("cron.status", gatewayOpts, {}));
|
||||
return jsonResult(await callGateway("cron.status", gatewayOpts, {}));
|
||||
case "list":
|
||||
return jsonResult(
|
||||
await callGatewayTool("cron.list", gatewayOpts, {
|
||||
await callGateway("cron.list", gatewayOpts, {
|
||||
includeDisabled: Boolean(params.includeDisabled),
|
||||
}),
|
||||
);
|
||||
@@ -412,6 +420,7 @@ Use jobId as the canonical identifier; id is accepted for compatibility. Use con
|
||||
agentSessionKey: opts?.agentSessionKey,
|
||||
gatewayOpts,
|
||||
contextMessages,
|
||||
callGatewayTool: callGateway,
|
||||
});
|
||||
if (contextLines.length > 0) {
|
||||
const baseText = stripExistingContext(payload.text);
|
||||
@@ -419,7 +428,7 @@ Use jobId as the canonical identifier; id is accepted for compatibility. Use con
|
||||
}
|
||||
}
|
||||
}
|
||||
return jsonResult(await callGatewayTool("cron.add", gatewayOpts, job));
|
||||
return jsonResult(await callGateway("cron.add", gatewayOpts, job));
|
||||
}
|
||||
case "update": {
|
||||
const id = readStringParam(params, "jobId") ?? readStringParam(params, "id");
|
||||
@@ -431,7 +440,7 @@ Use jobId as the canonical identifier; id is accepted for compatibility. Use con
|
||||
}
|
||||
const patch = normalizeCronJobPatch(params.patch) ?? params.patch;
|
||||
return jsonResult(
|
||||
await callGatewayTool("cron.update", gatewayOpts, {
|
||||
await callGateway("cron.update", gatewayOpts, {
|
||||
id,
|
||||
patch,
|
||||
}),
|
||||
@@ -442,7 +451,7 @@ Use jobId as the canonical identifier; id is accepted for compatibility. Use con
|
||||
if (!id) {
|
||||
throw new Error("jobId required (id accepted for backward compatibility)");
|
||||
}
|
||||
return jsonResult(await callGatewayTool("cron.remove", gatewayOpts, { id }));
|
||||
return jsonResult(await callGateway("cron.remove", gatewayOpts, { id }));
|
||||
}
|
||||
case "run": {
|
||||
const id = readStringParam(params, "jobId") ?? readStringParam(params, "id");
|
||||
@@ -451,14 +460,14 @@ Use jobId as the canonical identifier; id is accepted for compatibility. Use con
|
||||
}
|
||||
const runMode =
|
||||
params.runMode === "due" || params.runMode === "force" ? params.runMode : "force";
|
||||
return jsonResult(await callGatewayTool("cron.run", gatewayOpts, { id, mode: runMode }));
|
||||
return jsonResult(await callGateway("cron.run", gatewayOpts, { id, mode: runMode }));
|
||||
}
|
||||
case "runs": {
|
||||
const id = readStringParam(params, "jobId") ?? readStringParam(params, "id");
|
||||
if (!id) {
|
||||
throw new Error("jobId required (id accepted for backward compatibility)");
|
||||
}
|
||||
return jsonResult(await callGatewayTool("cron.runs", gatewayOpts, { id }));
|
||||
return jsonResult(await callGateway("cron.runs", gatewayOpts, { id }));
|
||||
}
|
||||
case "wake": {
|
||||
const text = readStringParam(params, "text", { required: true });
|
||||
@@ -467,7 +476,7 @@ Use jobId as the canonical identifier; id is accepted for compatibility. Use con
|
||||
? params.mode
|
||||
: "next-heartbeat";
|
||||
return jsonResult(
|
||||
await callGatewayTool("wake", gatewayOpts, { mode, text }, { expectFinal: false }),
|
||||
await callGateway("wake", gatewayOpts, { mode, text }, { expectFinal: false }),
|
||||
);
|
||||
}
|
||||
default:
|
||||
|
||||
38
src/config/plugins-runtime-boundary.test.ts
Normal file
38
src/config/plugins-runtime-boundary.test.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { FIELD_HELP } from "./schema.help.js";
|
||||
import { FIELD_LABELS } from "./schema.labels.js";
|
||||
import { OpenClawSchema } from "./zod-schema.js";
|
||||
|
||||
function hasLegacyPluginsRuntimeKeys(keys: string[]): boolean {
|
||||
return keys.some((key) => key === "plugins.runtime" || key.startsWith("plugins.runtime."));
|
||||
}
|
||||
|
||||
describe("plugins runtime boundary config", () => {
|
||||
it("omits legacy plugins.runtime keys from schema metadata", () => {
|
||||
expect(hasLegacyPluginsRuntimeKeys(Object.keys(FIELD_HELP))).toBe(false);
|
||||
expect(hasLegacyPluginsRuntimeKeys(Object.keys(FIELD_LABELS))).toBe(false);
|
||||
});
|
||||
|
||||
it("omits plugins.runtime from the generated config schema", () => {
|
||||
const schema = OpenClawSchema.toJSONSchema({
|
||||
target: "draft-7",
|
||||
io: "input",
|
||||
reused: "ref",
|
||||
}) as {
|
||||
properties?: Record<string, { properties?: Record<string, unknown> }>;
|
||||
};
|
||||
const pluginsProperties = schema.properties?.plugins?.properties ?? {};
|
||||
expect("runtime" in pluginsProperties).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects legacy plugins.runtime config entries", () => {
|
||||
const result = OpenClawSchema.safeParse({
|
||||
plugins: {
|
||||
runtime: {
|
||||
allowLegacyExec: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -239,195 +239,215 @@ function loadWhatsAppActions() {
|
||||
export function createPluginRuntime(): PluginRuntime {
|
||||
return {
|
||||
version: resolveVersion(),
|
||||
config: {
|
||||
loadConfig,
|
||||
writeConfigFile,
|
||||
config: createRuntimeConfig(),
|
||||
system: createRuntimeSystem(),
|
||||
media: createRuntimeMedia(),
|
||||
tts: { textToSpeechTelephony },
|
||||
tools: createRuntimeTools(),
|
||||
channel: createRuntimeChannel(),
|
||||
logging: createRuntimeLogging(),
|
||||
state: { resolveStateDir },
|
||||
};
|
||||
}
|
||||
|
||||
function createRuntimeConfig(): PluginRuntime["config"] {
|
||||
return {
|
||||
loadConfig,
|
||||
writeConfigFile,
|
||||
};
|
||||
}
|
||||
|
||||
function createRuntimeSystem(): PluginRuntime["system"] {
|
||||
return {
|
||||
enqueueSystemEvent,
|
||||
runCommandWithTimeout,
|
||||
formatNativeDependencyHint,
|
||||
};
|
||||
}
|
||||
|
||||
function createRuntimeMedia(): PluginRuntime["media"] {
|
||||
return {
|
||||
loadWebMedia,
|
||||
detectMime,
|
||||
mediaKindFromMime,
|
||||
isVoiceCompatibleAudio,
|
||||
getImageMetadata,
|
||||
resizeToJpeg,
|
||||
};
|
||||
}
|
||||
|
||||
function createRuntimeTools(): PluginRuntime["tools"] {
|
||||
return {
|
||||
createMemoryGetTool,
|
||||
createMemorySearchTool,
|
||||
registerMemoryCli,
|
||||
};
|
||||
}
|
||||
|
||||
function createRuntimeChannel(): PluginRuntime["channel"] {
|
||||
return {
|
||||
text: {
|
||||
chunkByNewline,
|
||||
chunkMarkdownText,
|
||||
chunkMarkdownTextWithMode,
|
||||
chunkText,
|
||||
chunkTextWithMode,
|
||||
resolveChunkMode,
|
||||
resolveTextChunkLimit,
|
||||
hasControlCommand,
|
||||
resolveMarkdownTableMode,
|
||||
convertMarkdownTables,
|
||||
},
|
||||
system: {
|
||||
enqueueSystemEvent,
|
||||
runCommandWithTimeout,
|
||||
formatNativeDependencyHint,
|
||||
reply: {
|
||||
dispatchReplyWithBufferedBlockDispatcher,
|
||||
createReplyDispatcherWithTyping,
|
||||
resolveEffectiveMessagesConfig,
|
||||
resolveHumanDelayConfig,
|
||||
dispatchReplyFromConfig,
|
||||
finalizeInboundContext,
|
||||
formatAgentEnvelope,
|
||||
/** @deprecated Prefer `BodyForAgent` + structured user-context blocks (do not build plaintext envelopes for prompts). */
|
||||
formatInboundEnvelope,
|
||||
resolveEnvelopeFormatOptions,
|
||||
},
|
||||
routing: {
|
||||
resolveAgentRoute,
|
||||
},
|
||||
pairing: {
|
||||
buildPairingReply,
|
||||
readAllowFromStore: readChannelAllowFromStore,
|
||||
upsertPairingRequest: upsertChannelPairingRequest,
|
||||
},
|
||||
media: {
|
||||
loadWebMedia,
|
||||
detectMime,
|
||||
mediaKindFromMime,
|
||||
isVoiceCompatibleAudio,
|
||||
getImageMetadata,
|
||||
resizeToJpeg,
|
||||
fetchRemoteMedia,
|
||||
saveMediaBuffer,
|
||||
},
|
||||
tts: {
|
||||
textToSpeechTelephony,
|
||||
activity: {
|
||||
record: recordChannelActivity,
|
||||
get: getChannelActivity,
|
||||
},
|
||||
tools: {
|
||||
createMemoryGetTool,
|
||||
createMemorySearchTool,
|
||||
registerMemoryCli,
|
||||
session: {
|
||||
resolveStorePath,
|
||||
readSessionUpdatedAt,
|
||||
recordSessionMetaFromInbound,
|
||||
recordInboundSession,
|
||||
updateLastRoute,
|
||||
},
|
||||
channel: {
|
||||
text: {
|
||||
chunkByNewline,
|
||||
chunkMarkdownText,
|
||||
chunkMarkdownTextWithMode,
|
||||
chunkText,
|
||||
chunkTextWithMode,
|
||||
resolveChunkMode,
|
||||
resolveTextChunkLimit,
|
||||
hasControlCommand,
|
||||
resolveMarkdownTableMode,
|
||||
convertMarkdownTables,
|
||||
},
|
||||
reply: {
|
||||
dispatchReplyWithBufferedBlockDispatcher,
|
||||
createReplyDispatcherWithTyping,
|
||||
resolveEffectiveMessagesConfig,
|
||||
resolveHumanDelayConfig,
|
||||
dispatchReplyFromConfig,
|
||||
finalizeInboundContext,
|
||||
formatAgentEnvelope,
|
||||
/** @deprecated Prefer `BodyForAgent` + structured user-context blocks (do not build plaintext envelopes for prompts). */
|
||||
formatInboundEnvelope,
|
||||
resolveEnvelopeFormatOptions,
|
||||
},
|
||||
routing: {
|
||||
resolveAgentRoute,
|
||||
},
|
||||
pairing: {
|
||||
buildPairingReply,
|
||||
readAllowFromStore: readChannelAllowFromStore,
|
||||
upsertPairingRequest: upsertChannelPairingRequest,
|
||||
},
|
||||
media: {
|
||||
fetchRemoteMedia,
|
||||
saveMediaBuffer,
|
||||
},
|
||||
activity: {
|
||||
record: recordChannelActivity,
|
||||
get: getChannelActivity,
|
||||
},
|
||||
session: {
|
||||
resolveStorePath,
|
||||
readSessionUpdatedAt,
|
||||
recordSessionMetaFromInbound,
|
||||
recordInboundSession,
|
||||
updateLastRoute,
|
||||
},
|
||||
mentions: {
|
||||
buildMentionRegexes,
|
||||
matchesMentionPatterns,
|
||||
matchesMentionWithExplicit,
|
||||
},
|
||||
reactions: {
|
||||
shouldAckReaction,
|
||||
removeAckReactionAfterReply,
|
||||
},
|
||||
groups: {
|
||||
resolveGroupPolicy: resolveChannelGroupPolicy,
|
||||
resolveRequireMention: resolveChannelGroupRequireMention,
|
||||
},
|
||||
debounce: {
|
||||
createInboundDebouncer,
|
||||
resolveInboundDebounceMs,
|
||||
},
|
||||
commands: {
|
||||
resolveCommandAuthorizedFromAuthorizers,
|
||||
isControlCommandMessage,
|
||||
shouldComputeCommandAuthorized,
|
||||
shouldHandleTextCommands,
|
||||
},
|
||||
discord: {
|
||||
messageActions: discordMessageActions,
|
||||
auditChannelPermissions: auditDiscordChannelPermissions,
|
||||
listDirectoryGroupsLive: listDiscordDirectoryGroupsLive,
|
||||
listDirectoryPeersLive: listDiscordDirectoryPeersLive,
|
||||
probeDiscord,
|
||||
resolveChannelAllowlist: resolveDiscordChannelAllowlist,
|
||||
resolveUserAllowlist: resolveDiscordUserAllowlist,
|
||||
sendMessageDiscord,
|
||||
sendPollDiscord,
|
||||
monitorDiscordProvider,
|
||||
},
|
||||
slack: {
|
||||
listDirectoryGroupsLive: listSlackDirectoryGroupsLive,
|
||||
listDirectoryPeersLive: listSlackDirectoryPeersLive,
|
||||
probeSlack,
|
||||
resolveChannelAllowlist: resolveSlackChannelAllowlist,
|
||||
resolveUserAllowlist: resolveSlackUserAllowlist,
|
||||
sendMessageSlack,
|
||||
monitorSlackProvider,
|
||||
handleSlackAction,
|
||||
},
|
||||
telegram: {
|
||||
auditGroupMembership: auditTelegramGroupMembership,
|
||||
collectUnmentionedGroupIds: collectTelegramUnmentionedGroupIds,
|
||||
probeTelegram,
|
||||
resolveTelegramToken,
|
||||
sendMessageTelegram,
|
||||
sendPollTelegram,
|
||||
monitorTelegramProvider,
|
||||
messageActions: telegramMessageActions,
|
||||
},
|
||||
signal: {
|
||||
probeSignal,
|
||||
sendMessageSignal,
|
||||
monitorSignalProvider,
|
||||
messageActions: signalMessageActions,
|
||||
},
|
||||
imessage: {
|
||||
monitorIMessageProvider,
|
||||
probeIMessage,
|
||||
sendMessageIMessage,
|
||||
},
|
||||
whatsapp: {
|
||||
getActiveWebListener,
|
||||
getWebAuthAgeMs,
|
||||
logoutWeb,
|
||||
logWebSelfId,
|
||||
readWebSelfId,
|
||||
webAuthExists,
|
||||
sendMessageWhatsApp: sendMessageWhatsAppLazy,
|
||||
sendPollWhatsApp: sendPollWhatsAppLazy,
|
||||
loginWeb: loginWebLazy,
|
||||
startWebLoginWithQr: startWebLoginWithQrLazy,
|
||||
waitForWebLogin: waitForWebLoginLazy,
|
||||
monitorWebChannel: monitorWebChannelLazy,
|
||||
handleWhatsAppAction: handleWhatsAppActionLazy,
|
||||
createLoginTool: createWhatsAppLoginTool,
|
||||
},
|
||||
line: {
|
||||
listLineAccountIds,
|
||||
resolveDefaultLineAccountId,
|
||||
resolveLineAccount,
|
||||
normalizeAccountId: normalizeLineAccountId,
|
||||
probeLineBot,
|
||||
sendMessageLine,
|
||||
pushMessageLine,
|
||||
pushMessagesLine,
|
||||
pushFlexMessage,
|
||||
pushTemplateMessage,
|
||||
pushLocationMessage,
|
||||
pushTextMessageWithQuickReplies,
|
||||
createQuickReplyItems,
|
||||
buildTemplateMessageFromPayload,
|
||||
monitorLineProvider,
|
||||
},
|
||||
mentions: {
|
||||
buildMentionRegexes,
|
||||
matchesMentionPatterns,
|
||||
matchesMentionWithExplicit,
|
||||
},
|
||||
logging: {
|
||||
shouldLogVerbose,
|
||||
getChildLogger: (bindings, opts) => {
|
||||
const logger = getChildLogger(bindings, {
|
||||
level: opts?.level ? normalizeLogLevel(opts.level) : undefined,
|
||||
});
|
||||
return {
|
||||
debug: (message) => logger.debug?.(message),
|
||||
info: (message) => logger.info(message),
|
||||
warn: (message) => logger.warn(message),
|
||||
error: (message) => logger.error(message),
|
||||
};
|
||||
},
|
||||
reactions: {
|
||||
shouldAckReaction,
|
||||
removeAckReactionAfterReply,
|
||||
},
|
||||
state: {
|
||||
resolveStateDir,
|
||||
groups: {
|
||||
resolveGroupPolicy: resolveChannelGroupPolicy,
|
||||
resolveRequireMention: resolveChannelGroupRequireMention,
|
||||
},
|
||||
debounce: {
|
||||
createInboundDebouncer,
|
||||
resolveInboundDebounceMs,
|
||||
},
|
||||
commands: {
|
||||
resolveCommandAuthorizedFromAuthorizers,
|
||||
isControlCommandMessage,
|
||||
shouldComputeCommandAuthorized,
|
||||
shouldHandleTextCommands,
|
||||
},
|
||||
discord: {
|
||||
messageActions: discordMessageActions,
|
||||
auditChannelPermissions: auditDiscordChannelPermissions,
|
||||
listDirectoryGroupsLive: listDiscordDirectoryGroupsLive,
|
||||
listDirectoryPeersLive: listDiscordDirectoryPeersLive,
|
||||
probeDiscord,
|
||||
resolveChannelAllowlist: resolveDiscordChannelAllowlist,
|
||||
resolveUserAllowlist: resolveDiscordUserAllowlist,
|
||||
sendMessageDiscord,
|
||||
sendPollDiscord,
|
||||
monitorDiscordProvider,
|
||||
},
|
||||
slack: {
|
||||
listDirectoryGroupsLive: listSlackDirectoryGroupsLive,
|
||||
listDirectoryPeersLive: listSlackDirectoryPeersLive,
|
||||
probeSlack,
|
||||
resolveChannelAllowlist: resolveSlackChannelAllowlist,
|
||||
resolveUserAllowlist: resolveSlackUserAllowlist,
|
||||
sendMessageSlack,
|
||||
monitorSlackProvider,
|
||||
handleSlackAction,
|
||||
},
|
||||
telegram: {
|
||||
auditGroupMembership: auditTelegramGroupMembership,
|
||||
collectUnmentionedGroupIds: collectTelegramUnmentionedGroupIds,
|
||||
probeTelegram,
|
||||
resolveTelegramToken,
|
||||
sendMessageTelegram,
|
||||
sendPollTelegram,
|
||||
monitorTelegramProvider,
|
||||
messageActions: telegramMessageActions,
|
||||
},
|
||||
signal: {
|
||||
probeSignal,
|
||||
sendMessageSignal,
|
||||
monitorSignalProvider,
|
||||
messageActions: signalMessageActions,
|
||||
},
|
||||
imessage: {
|
||||
monitorIMessageProvider,
|
||||
probeIMessage,
|
||||
sendMessageIMessage,
|
||||
},
|
||||
whatsapp: {
|
||||
getActiveWebListener,
|
||||
getWebAuthAgeMs,
|
||||
logoutWeb,
|
||||
logWebSelfId,
|
||||
readWebSelfId,
|
||||
webAuthExists,
|
||||
sendMessageWhatsApp: sendMessageWhatsAppLazy,
|
||||
sendPollWhatsApp: sendPollWhatsAppLazy,
|
||||
loginWeb: loginWebLazy,
|
||||
startWebLoginWithQr: startWebLoginWithQrLazy,
|
||||
waitForWebLogin: waitForWebLoginLazy,
|
||||
monitorWebChannel: monitorWebChannelLazy,
|
||||
handleWhatsAppAction: handleWhatsAppActionLazy,
|
||||
createLoginTool: createWhatsAppLoginTool,
|
||||
},
|
||||
line: {
|
||||
listLineAccountIds,
|
||||
resolveDefaultLineAccountId,
|
||||
resolveLineAccount,
|
||||
normalizeAccountId: normalizeLineAccountId,
|
||||
probeLineBot,
|
||||
sendMessageLine,
|
||||
pushMessageLine,
|
||||
pushMessagesLine,
|
||||
pushFlexMessage,
|
||||
pushTemplateMessage,
|
||||
pushLocationMessage,
|
||||
pushTextMessageWithQuickReplies,
|
||||
createQuickReplyItems,
|
||||
buildTemplateMessageFromPayload,
|
||||
monitorLineProvider,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function createRuntimeLogging(): PluginRuntime["logging"] {
|
||||
return {
|
||||
shouldLogVerbose,
|
||||
getChildLogger: (bindings, opts) => {
|
||||
const logger = getChildLogger(bindings, {
|
||||
level: opts?.level ? normalizeLogLevel(opts.level) : undefined,
|
||||
});
|
||||
return {
|
||||
debug: (message) => logger.debug?.(message),
|
||||
info: (message) => logger.info(message),
|
||||
warn: (message) => logger.warn(message),
|
||||
error: (message) => logger.error(message),
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user