feat(cron): add --tools flag for per-job tool allow-list (#58504)

Add toolsAllow field to cron agent-turn payloads, enabling users to
restrict which tool schemas are sent to the model for a given cron job.

When --tools is set:
- Only listed tools are included in the provider request
- promptMode is forced to 'minimal' (strips skills catalog, reply tags,
  heartbeat, messaging, docs, memory, model aliases, silent replies)
- Dramatically reduces input tokens for small local models (~16K to ~800)

CLI surface:
- openclaw cron add --tools exec,read,write
- openclaw cron edit <id> --tools exec
- openclaw cron edit <id> --clear-tools (remove allow-list)

Closes #58435

Co-authored-by: andyk-ms <andyk-ms@users.noreply.github.com>
This commit is contained in:
Andy
2026-03-31 18:09:17 -07:00
committed by GitHub
parent 3a52b475ab
commit 4d8c07b97c
7 changed files with 54 additions and 3 deletions

View File

@@ -417,7 +417,8 @@ export async function runEmbeddedAttempt(
const modelHasVision = params.model.input?.includes("image") ?? false;
const toolsRaw = params.disableTools
? []
: createOpenClawCodingTools({
: (() => {
const allTools = createOpenClawCodingTools({
agentId: sessionAgentId,
trigger: params.trigger,
memoryFlushWritePath: params.memoryFlushWritePath,
@@ -476,6 +477,12 @@ export async function runEmbeddedAttempt(
abortSessionForYield?.();
},
});
if (params.toolsAllow && params.toolsAllow.length > 0) {
const allowSet = new Set(params.toolsAllow);
return allTools.filter((tool) => allowSet.has(tool.name));
}
return allTools;
})();
const toolsEnabled = supportsModelTools(params.model);
const tools = sanitizeToolsForGoogle({
tools: toolsEnabled ? toolsRaw : [],
@@ -612,6 +619,10 @@ export async function runEmbeddedAttempt(
});
const isDefaultAgent = sessionAgentId === defaultAgentId;
const promptMode = resolvePromptModeForSession(params.sessionKey);
// When toolsAllow is set, use minimal prompt and strip skills catalog
const effectivePromptMode = params.toolsAllow?.length ? "minimal" as const : promptMode;
const effectiveSkillsPrompt = params.toolsAllow?.length ? undefined : skillsPrompt;
const docsPath = await resolveOpenClawDocsPath({
workspaceDir: effectiveWorkspace,
argv1: process.argv[1],
@@ -637,12 +648,12 @@ export async function runEmbeddedAttempt(
ownerDisplaySecret: ownerDisplay.ownerDisplaySecret,
reasoningTagHint,
heartbeatPrompt,
skillsPrompt,
skillsPrompt: effectiveSkillsPrompt,
docsPath: docsPath ?? undefined,
ttsHint,
workspaceNotes,
reactionGuidance,
promptMode,
promptMode: effectivePromptMode,
acpEnabled: params.config?.acp?.enabled !== false,
runtimeInfo,
messageToolHints,

View File

@@ -97,6 +97,8 @@ export type RunEmbeddedPiAgentParams = {
bootstrapContextMode?: "full" | "lightweight";
/** Run kind hint for context mode behavior. */
bootstrapContextRunKind?: "default" | "heartbeat" | "cron";
/** Optional tool allow-list; when set, only these tools are sent to the model. */
toolsAllow?: string[];
/** Seen bootstrap truncation warning signatures for this session (once mode dedupe). */
bootstrapPromptWarningSignaturesSeen?: string[];
/** Last shown bootstrap truncation warning signature for this session. */