diff --git a/CHANGELOG.md b/CHANGELOG.md index df4f4639f19..9609adceca2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Docs: https://docs.openclaw.ai - Video generation/live tests: bound provider polling for live video smoke, default to the fast non-FAL text-to-video path, and use a one-second lobster prompt so release validation no longer waits indefinitely on slow provider queues. - Memory-core/QMD `memory_get`: reject reads of arbitrary workspace markdown paths and only allow canonical memory files (`MEMORY.md`, `memory.md`, `DREAMS.md`, `dreams.md`, `memory/**`) plus exact paths of active indexed QMD workspace documents, so the QMD memory backend can no longer be used as a generic workspace-file read shim that bypasses `read` tool-policy denials. (#66026) Thanks @eleqtrizit. +- Cron/agents: forward embedded-run tool policy and internal event params into the attempt layer so `--tools` allowlists, cron-owned message-tool suppression, explicit message targeting, and command-path internal events all take effect at runtime again. (#62675) Thanks @hexsprite. ## 2026.4.14 diff --git a/src/agents/pi-embedded-runner/run.attempt-param-forwarding.test.ts b/src/agents/pi-embedded-runner/run.attempt-param-forwarding.test.ts new file mode 100644 index 00000000000..45f3029024c --- /dev/null +++ b/src/agents/pi-embedded-runner/run.attempt-param-forwarding.test.ts @@ -0,0 +1,80 @@ +import { beforeAll, beforeEach, describe, expect, it } from "vitest"; +import type { AgentInternalEvent } from "../internal-events.js"; +import { makeAttemptResult } from "./run.overflow-compaction.fixture.js"; +import { + loadRunOverflowCompactionHarness, + mockedRunEmbeddedAttempt, + overflowBaseRunParams, + resetRunOverflowCompactionHarnessMocks, +} from "./run.overflow-compaction.harness.js"; +import type { RunEmbeddedPiAgentParams } from "./run/params.js"; + +type ForwardingCase = { + name: string; + runId: string; + params: Partial; + expected: Record; +}; + +let runEmbeddedPiAgent: typeof import("./run.js").runEmbeddedPiAgent; +const internalEvents: AgentInternalEvent[] = []; +const forwardingCases = [ + { + name: "forwards toolsAllow so the per-job tool allowlist can be honored", + runId: "forward-toolsAllow", + params: { toolsAllow: ["exec", "read"] }, + expected: { toolsAllow: ["exec", "read"] }, + }, + { + name: "forwards bootstrapContextMode so lightContext cron jobs strip workspace bootstrap files", + runId: "forward-bootstrapContextMode", + params: { bootstrapContextMode: "lightweight" }, + expected: { bootstrapContextMode: "lightweight" }, + }, + { + name: "forwards bootstrapContextRunKind so the bootstrap filter knows the caller context", + runId: "forward-bootstrapContextRunKind", + params: { bootstrapContextRunKind: "cron" }, + expected: { bootstrapContextRunKind: "cron" }, + }, + { + name: "forwards disableMessageTool so cron-owned delivery suppresses the messaging tool", + runId: "forward-disableMessageTool", + params: { disableMessageTool: true }, + expected: { disableMessageTool: true }, + }, + { + name: "forwards requireExplicitMessageTarget so non-subagent callers can opt in explicitly", + runId: "forward-requireExplicitMessageTarget", + params: { requireExplicitMessageTarget: true }, + expected: { requireExplicitMessageTarget: true }, + }, + { + name: "forwards internalEvents so the agent command attempt path can deliver internal events", + runId: "forward-internalEvents", + params: { internalEvents }, + expected: { internalEvents }, + }, +] satisfies ForwardingCase[]; + +describe("runEmbeddedPiAgent forwards optional params to runEmbeddedAttempt", () => { + beforeAll(async () => { + ({ runEmbeddedPiAgent } = await loadRunOverflowCompactionHarness()); + }); + + beforeEach(() => { + resetRunOverflowCompactionHarnessMocks(); + }); + + it.each(forwardingCases)("$name", async ({ runId, params, expected }) => { + mockedRunEmbeddedAttempt.mockResolvedValueOnce(makeAttemptResult({ promptError: null })); + + await runEmbeddedPiAgent({ + ...overflowBaseRunParams, + ...params, + runId, + }); + + expect(mockedRunEmbeddedAttempt).toHaveBeenCalledWith(expect.objectContaining(expected)); + }); +}); diff --git a/src/agents/pi-embedded-runner/run.ts b/src/agents/pi-embedded-runner/run.ts index 8f0398ed388..92522104099 100644 --- a/src/agents/pi-embedded-runner/run.ts +++ b/src/agents/pi-embedded-runner/run.ts @@ -754,6 +754,10 @@ export async function runEmbeddedPiAgent( silentExpected: params.silentExpected, bootstrapContextMode: params.bootstrapContextMode, bootstrapContextRunKind: params.bootstrapContextRunKind, + toolsAllow: params.toolsAllow, + disableMessageTool: params.disableMessageTool, + requireExplicitMessageTarget: params.requireExplicitMessageTarget, + internalEvents: params.internalEvents, bootstrapPromptWarningSignaturesSeen, bootstrapPromptWarningSignature: bootstrapPromptWarningSignaturesSeen[bootstrapPromptWarningSignaturesSeen.length - 1],