feat: lightweight bootstrap context mode for heartbeat/cron runs (openclaw#26064) thanks @jose-velez

Verified:
- pnpm build
- pnpm check (fails on pre-existing unrelated repo issues in extensions/diffs and src/agents/tools/nodes-tool.test.ts)
- pnpm vitest run src/agents/bootstrap-files.test.ts src/infra/heartbeat-runner.model-override.test.ts src/cli/cron-cli.test.ts
- pnpm test:macmini (fails on pre-existing extensions/diffs import errors; touched suites pass)

Co-authored-by: jose-velez <10926182+jose-velez@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
Jose E Velez
2026-03-01 21:13:24 -05:00
committed by GitHub
parent 0a182bb4d1
commit 0c8fa63b93
17 changed files with 168 additions and 23 deletions

View File

@@ -64,6 +64,7 @@ describe("runHeartbeatOnce heartbeat model override", () => {
async function runDefaultsHeartbeat(params: {
model?: string;
suppressToolErrorWarnings?: boolean;
lightContext?: boolean;
}) {
return withHeartbeatFixture(async ({ tmpDir, storePath, seedSession }) => {
const cfg: OpenClawConfig = {
@@ -75,6 +76,7 @@ describe("runHeartbeatOnce heartbeat model override", () => {
target: "whatsapp",
model: params.model,
suppressToolErrorWarnings: params.suppressToolErrorWarnings,
lightContext: params.lightContext,
},
},
},
@@ -121,6 +123,16 @@ describe("runHeartbeatOnce heartbeat model override", () => {
);
});
it("passes bootstrapContextMode when heartbeat lightContext is enabled", async () => {
const replyOpts = await runDefaultsHeartbeat({ lightContext: true });
expect(replyOpts).toEqual(
expect.objectContaining({
isHeartbeat: true,
bootstrapContextMode: "lightweight",
}),
);
});
it("passes per-agent heartbeat model override (merged with defaults)", async () => {
await withHeartbeatFixture(async ({ tmpDir, storePath, seedSession }) => {
const cfg: OpenClawConfig = {

View File

@@ -743,9 +743,16 @@ export async function runHeartbeatOnce(opts: {
const heartbeatModelOverride = heartbeat?.model?.trim() || undefined;
const suppressToolErrorWarnings = heartbeat?.suppressToolErrorWarnings === true;
const bootstrapContextMode: "lightweight" | undefined =
heartbeat?.lightContext === true ? "lightweight" : undefined;
const replyOpts = heartbeatModelOverride
? { isHeartbeat: true, heartbeatModelOverride, suppressToolErrorWarnings }
: { isHeartbeat: true, suppressToolErrorWarnings };
? {
isHeartbeat: true,
heartbeatModelOverride,
suppressToolErrorWarnings,
bootstrapContextMode,
}
: { isHeartbeat: true, suppressToolErrorWarnings, bootstrapContextMode };
const replyResult = await getReplyFromConfig(ctx, replyOpts, cfg);
const replyPayload = resolveHeartbeatReplyPayload(replyResult);
const includeReasoning = heartbeat?.includeReasoning === true;