From 9c0ff87c863147c2947a867171f0c862cb27d877 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 18 Jan 2026 05:24:20 +0000 Subject: [PATCH] fix: align plugin runtime and exec wiring --- src/agents/pi-tools.ts | 28 +++++------ src/memory/manager.ts | 5 +- src/plugins/runtime/index.ts | 95 ++++-------------------------------- 3 files changed, 25 insertions(+), 103 deletions(-) diff --git a/src/agents/pi-tools.ts b/src/agents/pi-tools.ts index 07c158a69..33c4c27ad 100644 --- a/src/agents/pi-tools.ts +++ b/src/agents/pi-tools.ts @@ -74,19 +74,18 @@ function isApplyPatchAllowedForModel(params: { }); } -function resolveExecConfig(cfg: ClawdbotConfig | undefined, agentId?: string | null) { +function resolveExecConfig(cfg: ClawdbotConfig | undefined) { const globalExec = cfg?.tools?.exec; - const agentExec = cfg?.agents?.list?.find((entry) => entry.id === agentId)?.tools?.exec; return { - host: agentExec?.host ?? globalExec?.host, - security: agentExec?.security ?? globalExec?.security, - ask: agentExec?.ask ?? globalExec?.ask, - node: agentExec?.node ?? globalExec?.node, - backgroundMs: agentExec?.backgroundMs ?? globalExec?.backgroundMs, - timeoutSec: agentExec?.timeoutSec ?? globalExec?.timeoutSec, - cleanupMs: agentExec?.cleanupMs ?? globalExec?.cleanupMs, - notifyOnExit: agentExec?.notifyOnExit ?? globalExec?.notifyOnExit, - applyPatch: agentExec?.applyPatch ?? globalExec?.applyPatch, + host: globalExec?.host, + security: globalExec?.security, + ask: globalExec?.ask, + node: globalExec?.node, + backgroundMs: globalExec?.backgroundMs, + timeoutSec: globalExec?.timeoutSec, + cleanupMs: globalExec?.cleanupMs, + notifyOnExit: globalExec?.notifyOnExit, + applyPatch: globalExec?.applyPatch, }; } @@ -162,7 +161,7 @@ export function createClawdbotCodingTools(options?: { sandbox?.tools, subagentPolicy, ]); - const execConfig = resolveExecConfig(options?.config, agentId); + const execConfig = resolveExecConfig(options?.config); const sandboxRoot = sandbox?.workspaceDir; const allowWorkspaceWrites = sandbox?.workspaceAccess !== "ro"; const workspaceRoot = options?.workspaceDir ?? process.cwd(); @@ -199,8 +198,9 @@ export function createClawdbotCodingTools(options?: { } return [tool as AnyAgentTool]; }); + const { cleanupMs: cleanupMsOverride, ...execDefaults } = options?.exec ?? {}; const execTool = createExecTool({ - ...options?.exec, + ...execDefaults, host: options?.exec?.host ?? execConfig.host, security: options?.exec?.security ?? execConfig.security, ask: options?.exec?.ask ?? execConfig.ask, @@ -229,7 +229,7 @@ export function createClawdbotCodingTools(options?: { label: "bash", } satisfies AnyAgentTool; const processTool = createProcessTool({ - cleanupMs: options?.exec?.cleanupMs, + cleanupMs: cleanupMsOverride ?? execConfig.cleanupMs, scopeKey, }); const applyPatchTool = diff --git a/src/memory/manager.ts b/src/memory/manager.ts index db11bdeb6..d73b73972 100644 --- a/src/memory/manager.ts +++ b/src/memory/manager.ts @@ -11,10 +11,7 @@ import type { ClawdbotConfig } from "../config/config.js"; import { resolveSessionTranscriptsDirForAgent } from "../config/sessions/paths.js"; import { createSubsystemLogger } from "../logging.js"; import { onSessionTranscriptUpdate } from "../sessions/transcript-events.js"; -import { resolveUserPath, truncateUtf16Safe } from "../utils.js"; -import { colorize, isRich, theme } from "../terminal/theme.js"; -import { resolveUserPath, truncateUtf16Safe } from "../utils.js"; -import { colorize, isRich, theme } from "../terminal/theme.js"; +import { resolveUserPath } from "../utils.js"; import { createEmbeddingProvider, type EmbeddingProvider, diff --git a/src/plugins/runtime/index.ts b/src/plugins/runtime/index.ts index 8b26ad8a7..d3dbde550 100644 --- a/src/plugins/runtime/index.ts +++ b/src/plugins/runtime/index.ts @@ -7,14 +7,10 @@ import { resolveInboundDebounceMs, } from "../../auto-reply/inbound-debounce.js"; import { buildMentionRegexes, matchesMentionPatterns } from "../../auto-reply/reply/mentions.js"; -import type { ReplyPayload } from "../../auto-reply/types.js"; -import type { ReplyDispatchKind, ReplyDispatcherWithTypingOptions } from "../../auto-reply/reply/reply-dispatcher.js"; -import { dispatchReplyWithBufferedBlockDispatcher as dispatchReplyWithBufferedBlockDispatcherImpl } from "../../auto-reply/reply/provider-dispatcher.js"; +import { dispatchReplyWithBufferedBlockDispatcher } from "../../auto-reply/reply/provider-dispatcher.js"; import { createReplyDispatcherWithTyping } from "../../auto-reply/reply/reply-dispatcher.js"; import { resolveEffectiveMessagesConfig, resolveHumanDelayConfig } from "../../agents/identity.js"; import { resolveCommandAuthorizedFromAuthorizers } from "../../channels/command-gating.js"; -import type { ClawdbotConfig } from "../../config/config.js"; -import type { GroupPolicyChannel } from "../../config/group-policy.js"; import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention } from "../../config/group-policy.js"; import { resolveStateDir } from "../../config/paths.js"; import { shouldLogVerbose } from "../../globals.js"; @@ -28,7 +24,6 @@ import { upsertChannelPairingRequest, } from "../../pairing/pairing-store.js"; import { resolveAgentRoute } from "../../routing/resolve-route.js"; -import type { FinalizedMsgContext } from "../../auto-reply/templating.js"; import type { PluginRuntime } from "./types.js"; @@ -57,41 +52,13 @@ export function createPluginRuntime(): PluginRuntime { hasControlCommand, }, reply: { - dispatchReplyWithBufferedBlockDispatcher: async (params) => { - const dispatcherOptions = params.dispatcherOptions; - const deliver = async (payload: ReplyPayload, _info: { kind: ReplyDispatchKind }) => { - await dispatcherOptions.deliver(payload); - }; - const onError = dispatcherOptions.onError - ? (err: unknown, info: { kind: ReplyDispatchKind }) => { - dispatcherOptions.onError?.(err, { kind: info.kind }); - } - : undefined; - - await dispatchReplyWithBufferedBlockDispatcherImpl({ - ctx: params.ctx as FinalizedMsgContext, - cfg: params.cfg as ClawdbotConfig, - dispatcherOptions: { - deliver, - onError, - } satisfies ReplyDispatcherWithTypingOptions, - }); - }, - createReplyDispatcherWithTyping: (...args) => - createReplyDispatcherWithTyping(args[0] as ReplyDispatcherWithTypingOptions), + dispatchReplyWithBufferedBlockDispatcher, + createReplyDispatcherWithTyping, resolveEffectiveMessagesConfig, resolveHumanDelayConfig, }, routing: { - resolveAgentRoute: (params) => { - const resolved = resolveAgentRoute({ - cfg: params.cfg as ClawdbotConfig, - channel: params.channel, - accountId: params.accountId, - peer: params.peer, - }); - return { sessionKey: resolved.sessionKey, accountId: resolved.accountId }; - }, + resolveAgentRoute, }, pairing: { buildPairingReply, @@ -100,61 +67,19 @@ export function createPluginRuntime(): PluginRuntime { }, media: { fetchRemoteMedia, - saveMediaBuffer: async (buffer, contentType, direction, maxBytes) => { - const saved = await saveMediaBuffer( - Buffer.isBuffer(buffer) ? buffer : Buffer.from(buffer), - contentType, - direction, - maxBytes, - ); - return { path: saved.path, contentType: saved.contentType }; - }, + saveMediaBuffer, }, mentions: { buildMentionRegexes, matchesMentionPatterns, }, groups: { - resolveGroupPolicy: (cfg, channel, accountId, groupId) => - resolveChannelGroupPolicy({ - cfg, - channel: channel as GroupPolicyChannel, - accountId, - groupId, - }), - resolveRequireMention: (cfg, channel, accountId, groupId, override) => - resolveChannelGroupRequireMention({ - cfg, - channel: channel as GroupPolicyChannel, - accountId, - groupId, - requireMentionOverride: override, - }), + resolveGroupPolicy: resolveChannelGroupPolicy, + resolveRequireMention: resolveChannelGroupRequireMention, }, debounce: { - createInboundDebouncer: (opts) => { - const keys = new Set(); - const debouncer = createInboundDebouncer({ - debounceMs: opts.debounceMs, - buildKey: opts.buildKey, - shouldDebounce: opts.shouldDebounce ?? (() => true), - onFlush: opts.onFlush, - onError: opts.onError ? (err: unknown) => opts.onError?.(err) : undefined, - }); - return { - push: (value) => { - const key = opts.buildKey(value); - if (key) keys.add(key); - void debouncer.enqueue(value); - }, - flush: async () => { - const flushKeys = Array.from(keys); - keys.clear(); - for (const key of flushKeys) await debouncer.flushKey(key); - }, - }; - }, - resolveInboundDebounceMs: (cfg, channel) => resolveInboundDebounceMs({ cfg, channel }), + createInboundDebouncer, + resolveInboundDebounceMs, }, commands: { resolveCommandAuthorizedFromAuthorizers, @@ -175,7 +100,7 @@ export function createPluginRuntime(): PluginRuntime { }, }, state: { - resolveStateDir: () => resolveStateDir(), + resolveStateDir, }, }; }