fix: start fresh cron sessions each run
This commit is contained in:
@@ -48,6 +48,12 @@ async function writeSessionStore(home: string) {
|
||||
return storePath;
|
||||
}
|
||||
|
||||
async function readSessionEntry(storePath: string, key: string) {
|
||||
const raw = await fs.readFile(storePath, "utf-8");
|
||||
const store = JSON.parse(raw) as Record<string, { sessionId?: string }>;
|
||||
return store[key];
|
||||
}
|
||||
|
||||
function makeCfg(
|
||||
home: string,
|
||||
storePath: string,
|
||||
@@ -466,4 +472,51 @@ describe("runCronIsolatedAgentTurn", () => {
|
||||
expect(deps.sendMessageWhatsApp).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it("starts a fresh session id for each cron run", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const storePath = await writeSessionStore(home);
|
||||
const deps: CliDeps = {
|
||||
sendMessageWhatsApp: vi.fn(),
|
||||
sendMessageTelegram: vi.fn(),
|
||||
sendMessageDiscord: vi.fn(),
|
||||
sendMessageSignal: vi.fn(),
|
||||
sendMessageIMessage: vi.fn(),
|
||||
};
|
||||
vi.mocked(runEmbeddedPiAgent).mockResolvedValue({
|
||||
payloads: [{ text: "ok" }],
|
||||
meta: {
|
||||
durationMs: 5,
|
||||
agentMeta: { sessionId: "s", provider: "p", model: "m" },
|
||||
},
|
||||
});
|
||||
|
||||
const cfg = makeCfg(home, storePath);
|
||||
const job = makeJob({ kind: "agentTurn", message: "ping", deliver: false });
|
||||
|
||||
await runCronIsolatedAgentTurn({
|
||||
cfg,
|
||||
deps,
|
||||
job,
|
||||
message: "ping",
|
||||
sessionKey: "cron:job-1",
|
||||
lane: "cron",
|
||||
});
|
||||
const first = await readSessionEntry(storePath, "agent:main:cron:job-1");
|
||||
|
||||
await runCronIsolatedAgentTurn({
|
||||
cfg,
|
||||
deps,
|
||||
job,
|
||||
message: "ping",
|
||||
sessionKey: "cron:job-1",
|
||||
lane: "cron",
|
||||
});
|
||||
const second = await readSessionEntry(storePath, "agent:main:cron:job-1");
|
||||
|
||||
expect(first?.sessionId).toBeDefined();
|
||||
expect(second?.sessionId).toBeDefined();
|
||||
expect(second?.sessionId).not.toBe(first?.sessionId);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -206,8 +206,10 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
const base = `[cron:${params.job.id} ${params.job.name}] ${params.message}`.trim();
|
||||
const commandBody = base;
|
||||
|
||||
const needsSkillsSnapshot = cronSession.isNewSession || !cronSession.sessionEntry.skillsSnapshot;
|
||||
const existingSnapshot = cronSession.sessionEntry.skillsSnapshot;
|
||||
const skillsSnapshotVersion = getSkillsSnapshotVersion(workspaceDir);
|
||||
const needsSkillsSnapshot =
|
||||
!existingSnapshot || existingSnapshot.version !== skillsSnapshotVersion;
|
||||
const skillsSnapshot = needsSkillsSnapshot
|
||||
? buildWorkspaceSkillSnapshot(workspaceDir, {
|
||||
config: cfgWithAgentDefaults,
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import crypto from "node:crypto";
|
||||
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import {
|
||||
DEFAULT_IDLE_MINUTES,
|
||||
loadSessionStore,
|
||||
resolveStorePath,
|
||||
type SessionEntry,
|
||||
} from "../../config/sessions.js";
|
||||
import { loadSessionStore, resolveStorePath, type SessionEntry } from "../../config/sessions.js";
|
||||
|
||||
export function resolveCronSession(params: {
|
||||
cfg: ClawdbotConfig;
|
||||
@@ -15,16 +10,13 @@ export function resolveCronSession(params: {
|
||||
agentId: string;
|
||||
}) {
|
||||
const sessionCfg = params.cfg.session;
|
||||
const idleMinutes = Math.max(sessionCfg?.idleMinutes ?? DEFAULT_IDLE_MINUTES, 1);
|
||||
const idleMs = idleMinutes * 60_000;
|
||||
const storePath = resolveStorePath(sessionCfg?.store, {
|
||||
agentId: params.agentId,
|
||||
});
|
||||
const store = loadSessionStore(storePath);
|
||||
const entry = store[params.sessionKey];
|
||||
const fresh = entry && params.nowMs - entry.updatedAt <= idleMs;
|
||||
const sessionId = fresh ? entry.sessionId : crypto.randomUUID();
|
||||
const systemSent = fresh ? Boolean(entry.systemSent) : false;
|
||||
const sessionId = crypto.randomUUID();
|
||||
const systemSent = false;
|
||||
const sessionEntry: SessionEntry = {
|
||||
sessionId,
|
||||
updatedAt: params.nowMs,
|
||||
@@ -36,6 +28,8 @@ export function resolveCronSession(params: {
|
||||
sendPolicy: entry?.sendPolicy,
|
||||
lastChannel: entry?.lastChannel,
|
||||
lastTo: entry?.lastTo,
|
||||
lastAccountId: entry?.lastAccountId,
|
||||
skillsSnapshot: entry?.skillsSnapshot,
|
||||
};
|
||||
return { storePath, store, sessionEntry, systemSent, isNewSession: !fresh };
|
||||
return { storePath, store, sessionEntry, systemSent, isNewSession: true };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user