diff --git a/README.md b/README.md
index aedd0fe5d..410efca01 100644
--- a/README.md
+++ b/README.md
@@ -474,22 +474,23 @@ Core contributors:
Thanks to all clawtributors:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/agents/clawdbot-tools.session-status.test.ts b/src/agents/clawdbot-tools.session-status.test.ts
index 1a173339d..f3a07b7e2 100644
--- a/src/agents/clawdbot-tools.session-status.test.ts
+++ b/src/agents/clawdbot-tools.session-status.test.ts
@@ -1,15 +1,22 @@
import { describe, expect, it, vi } from "vitest";
const loadSessionStoreMock = vi.fn();
-const saveSessionStoreMock = vi.fn();
+const updateSessionStoreMock = vi.fn();
vi.mock("../config/sessions.js", async (importOriginal) => {
const actual = await importOriginal();
return {
...actual,
loadSessionStore: (storePath: string) => loadSessionStoreMock(storePath),
- saveSessionStore: (storePath: string, store: Record) =>
- saveSessionStoreMock(storePath, store),
+ updateSessionStore: async (
+ storePath: string,
+ mutator: (store: Record) => Promise | void,
+ ) => {
+ const store = loadSessionStoreMock(storePath) as Record;
+ await mutator(store);
+ updateSessionStoreMock(storePath, store);
+ return store;
+ },
resolveStorePath: () => "/tmp/sessions.json",
};
});
@@ -73,7 +80,7 @@ import { createClawdbotTools } from "./clawdbot-tools.js";
describe("session_status tool", () => {
it("returns a status card for the current session", async () => {
loadSessionStoreMock.mockReset();
- saveSessionStoreMock.mockReset();
+ updateSessionStoreMock.mockReset();
loadSessionStoreMock.mockReturnValue({
main: {
sessionId: "s1",
@@ -96,7 +103,7 @@ describe("session_status tool", () => {
it("errors for unknown session keys", async () => {
loadSessionStoreMock.mockReset();
- saveSessionStoreMock.mockReset();
+ updateSessionStoreMock.mockReset();
loadSessionStoreMock.mockReturnValue({
main: { sessionId: "s1", updatedAt: 10 },
});
@@ -110,12 +117,12 @@ describe("session_status tool", () => {
await expect(tool.execute("call2", { sessionKey: "nope" })).rejects.toThrow(
"Unknown sessionKey",
);
- expect(saveSessionStoreMock).not.toHaveBeenCalled();
+ expect(updateSessionStoreMock).not.toHaveBeenCalled();
});
it("resets per-session model override via model=default", async () => {
loadSessionStoreMock.mockReset();
- saveSessionStoreMock.mockReset();
+ updateSessionStoreMock.mockReset();
loadSessionStoreMock.mockReturnValue({
main: {
sessionId: "s1",
@@ -133,8 +140,8 @@ describe("session_status tool", () => {
if (!tool) throw new Error("missing session_status tool");
await tool.execute("call3", { model: "default" });
- expect(saveSessionStoreMock).toHaveBeenCalled();
- const [, savedStore] = saveSessionStoreMock.mock.calls.at(-1) as [
+ expect(updateSessionStoreMock).toHaveBeenCalled();
+ const [, savedStore] = updateSessionStoreMock.mock.calls.at(-1) as [
string,
Record,
];
diff --git a/src/auto-reply/reply/agent-runner-execution.ts b/src/auto-reply/reply/agent-runner-execution.ts
index f9129566a..dc46ee7bc 100644
--- a/src/auto-reply/reply/agent-runner-execution.ts
+++ b/src/auto-reply/reply/agent-runner-execution.ts
@@ -400,6 +400,9 @@ export async function runAgentTurnWithFallback(params: {
}
}
+ // Keep the in-memory snapshot consistent with the on-disk store reset.
+ delete params.activeSessionStore[sessionKey];
+
// Remove session entry from store using a fresh, locked snapshot.
await updateSessionStore(params.storePath, (store) => {
delete store[sessionKey];
diff --git a/src/commands/agent.ts b/src/commands/agent.ts
index 1f3ad44c6..e7d3680dc 100644
--- a/src/commands/agent.ts
+++ b/src/commands/agent.ts
@@ -243,6 +243,7 @@ export async function agentCommand(
}
if (sessionEntry && sessionStore && sessionKey && hasStoredOverride) {
+ const entry = sessionEntry;
const overrideProvider = sessionEntry.providerOverride?.trim() || defaultProvider;
const overrideModel = sessionEntry.modelOverride?.trim();
if (overrideModel) {
@@ -252,12 +253,12 @@ export async function agentCommand(
allowedModelKeys.size > 0 &&
!allowedModelKeys.has(key)
) {
- delete sessionEntry.providerOverride;
- delete sessionEntry.modelOverride;
- sessionEntry.updatedAt = Date.now();
- sessionStore[sessionKey] = sessionEntry;
+ delete entry.providerOverride;
+ delete entry.modelOverride;
+ entry.updatedAt = Date.now();
+ sessionStore[sessionKey] = entry;
await updateSessionStore(storePath, (store) => {
- store[sessionKey] = sessionEntry;
+ store[sessionKey] = entry;
});
}
}
@@ -277,17 +278,21 @@ export async function agentCommand(
model = storedModelOverride;
}
}
- if (sessionEntry?.authProfileOverride) {
- const store = ensureAuthProfileStore();
- const profile = store.profiles[sessionEntry.authProfileOverride];
- if (!profile || profile.provider !== provider) {
- delete sessionEntry.authProfileOverride;
- sessionEntry.updatedAt = Date.now();
- if (sessionStore && sessionKey) {
- sessionStore[sessionKey] = sessionEntry;
- await updateSessionStore(storePath, (store) => {
- store[sessionKey] = sessionEntry;
- });
+ if (sessionEntry) {
+ const authProfileId = sessionEntry.authProfileOverride;
+ if (authProfileId) {
+ const entry = sessionEntry;
+ const store = ensureAuthProfileStore();
+ const profile = store.profiles[authProfileId];
+ if (!profile || profile.provider !== provider) {
+ delete entry.authProfileOverride;
+ entry.updatedAt = Date.now();
+ if (sessionStore && sessionKey) {
+ sessionStore[sessionKey] = entry;
+ await updateSessionStore(storePath, (store) => {
+ store[sessionKey] = entry;
+ });
+ }
}
}
}
@@ -312,11 +317,12 @@ export async function agentCommand(
}
resolvedThinkLevel = "high";
if (sessionEntry && sessionStore && sessionKey && sessionEntry.thinkingLevel === "xhigh") {
- sessionEntry.thinkingLevel = "high";
- sessionEntry.updatedAt = Date.now();
- sessionStore[sessionKey] = sessionEntry;
+ const entry = sessionEntry;
+ entry.thinkingLevel = "high";
+ entry.updatedAt = Date.now();
+ sessionStore[sessionKey] = entry;
await updateSessionStore(storePath, (store) => {
- store[sessionKey] = sessionEntry;
+ store[sessionKey] = entry;
});
}
}
diff --git a/src/discord/monitor/provider.ts b/src/discord/monitor/provider.ts
index facfa9595..f2c3e8997 100644
--- a/src/discord/monitor/provider.ts
+++ b/src/discord/monitor/provider.ts
@@ -136,11 +136,6 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
publicKey: "a",
token,
autoDeploy: nativeEnabled,
- eventQueue: {
- // Auto-threading (create thread + generate reply + post) can exceed the default
- // 30s listener timeout in some environments.
- listenerTimeout: 120_000,
- },
},
{
commands,