refactor(gateway): use canonical session store keys
This commit is contained in:
@@ -94,7 +94,6 @@ import {
|
|||||||
readSessionMessages,
|
readSessionMessages,
|
||||||
resolveGatewaySessionStoreTarget,
|
resolveGatewaySessionStoreTarget,
|
||||||
resolveSessionModelRef,
|
resolveSessionModelRef,
|
||||||
resolveSessionStoreKey,
|
|
||||||
resolveSessionTranscriptCandidates,
|
resolveSessionTranscriptCandidates,
|
||||||
type SessionsPatchResult,
|
type SessionsPatchResult,
|
||||||
} from "./session-utils.js";
|
} from "./session-utils.js";
|
||||||
@@ -867,9 +866,8 @@ export function createBridgeHandlers(ctx: BridgeHandlersContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { cfg, storePath, store, entry } = loadSessionEntry(
|
const { cfg, storePath, store, entry, canonicalKey } =
|
||||||
p.sessionKey,
|
loadSessionEntry(p.sessionKey);
|
||||||
);
|
|
||||||
const timeoutMs = resolveAgentTimeoutMs({
|
const timeoutMs = resolveAgentTimeoutMs({
|
||||||
cfg,
|
cfg,
|
||||||
overrideMs: p.timeoutMs,
|
overrideMs: p.timeoutMs,
|
||||||
@@ -946,12 +944,8 @@ export function createBridgeHandlers(ctx: BridgeHandlersContext) {
|
|||||||
clientRunId,
|
clientRunId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const storeKey = resolveSessionStoreKey({
|
|
||||||
cfg,
|
|
||||||
sessionKey: p.sessionKey,
|
|
||||||
});
|
|
||||||
if (store) {
|
if (store) {
|
||||||
store[storeKey] = sessionEntry;
|
store[canonicalKey] = sessionEntry;
|
||||||
if (storePath) {
|
if (storePath) {
|
||||||
await saveSessionStore(storePath, store);
|
await saveSessionStore(storePath, store);
|
||||||
}
|
}
|
||||||
@@ -1068,11 +1062,11 @@ export function createBridgeHandlers(ctx: BridgeHandlersContext) {
|
|||||||
const rawMainKey = normalizeMainKey(cfg.session?.mainKey);
|
const rawMainKey = normalizeMainKey(cfg.session?.mainKey);
|
||||||
const sessionKey =
|
const sessionKey =
|
||||||
sessionKeyRaw.length > 0 ? sessionKeyRaw : rawMainKey;
|
sessionKeyRaw.length > 0 ? sessionKeyRaw : rawMainKey;
|
||||||
const { storePath, store, entry } = loadSessionEntry(sessionKey);
|
const { storePath, store, entry, canonicalKey } =
|
||||||
const storeKey = resolveSessionStoreKey({ cfg, sessionKey });
|
loadSessionEntry(sessionKey);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const sessionId = entry?.sessionId ?? randomUUID();
|
const sessionId = entry?.sessionId ?? randomUUID();
|
||||||
store[storeKey] = {
|
store[canonicalKey] = {
|
||||||
sessionId,
|
sessionId,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
thinkingLevel: entry?.thinkingLevel,
|
thinkingLevel: entry?.thinkingLevel,
|
||||||
@@ -1146,15 +1140,11 @@ export function createBridgeHandlers(ctx: BridgeHandlersContext) {
|
|||||||
const sessionKeyRaw = (link?.sessionKey ?? "").trim();
|
const sessionKeyRaw = (link?.sessionKey ?? "").trim();
|
||||||
const sessionKey =
|
const sessionKey =
|
||||||
sessionKeyRaw.length > 0 ? sessionKeyRaw : `node-${nodeId}`;
|
sessionKeyRaw.length > 0 ? sessionKeyRaw : `node-${nodeId}`;
|
||||||
const { storePath, store, entry } = loadSessionEntry(sessionKey);
|
const { storePath, store, entry, canonicalKey } =
|
||||||
const nodeCfg = loadConfig();
|
loadSessionEntry(sessionKey);
|
||||||
const nodeStoreKey = resolveSessionStoreKey({
|
|
||||||
cfg: nodeCfg,
|
|
||||||
sessionKey,
|
|
||||||
});
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const sessionId = entry?.sessionId ?? randomUUID();
|
const sessionId = entry?.sessionId ?? randomUUID();
|
||||||
store[nodeStoreKey] = {
|
store[canonicalKey] = {
|
||||||
sessionId,
|
sessionId,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
thinkingLevel: entry?.thinkingLevel,
|
thinkingLevel: entry?.thinkingLevel,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import {
|
|||||||
validateAgentParams,
|
validateAgentParams,
|
||||||
validateAgentWaitParams,
|
validateAgentWaitParams,
|
||||||
} from "../protocol/index.js";
|
} from "../protocol/index.js";
|
||||||
import { loadSessionEntry, resolveSessionStoreKey } from "../session-utils.js";
|
import { loadSessionEntry } from "../session-utils.js";
|
||||||
import { formatForLog } from "../ws-log.js";
|
import { formatForLog } from "../ws-log.js";
|
||||||
import { waitForAgentJob } from "./agent-job.js";
|
import { waitForAgentJob } from "./agent-job.js";
|
||||||
import type { GatewayRequestHandlers } from "./types.js";
|
import type { GatewayRequestHandlers } from "./types.js";
|
||||||
@@ -146,7 +146,7 @@ export const agentHandlers: GatewayRequestHandlers = {
|
|||||||
let cfgForAgent: ReturnType<typeof loadConfig> | undefined;
|
let cfgForAgent: ReturnType<typeof loadConfig> | undefined;
|
||||||
|
|
||||||
if (requestedSessionKey) {
|
if (requestedSessionKey) {
|
||||||
const { cfg, storePath, store, entry } =
|
const { cfg, storePath, store, entry, canonicalKey } =
|
||||||
loadSessionEntry(requestedSessionKey);
|
loadSessionEntry(requestedSessionKey);
|
||||||
cfgForAgent = cfg;
|
cfgForAgent = cfg;
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
@@ -189,10 +189,7 @@ export const agentHandlers: GatewayRequestHandlers = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resolvedSessionId = sessionId;
|
resolvedSessionId = sessionId;
|
||||||
const canonicalSessionKey = resolveSessionStoreKey({
|
const canonicalSessionKey = canonicalKey;
|
||||||
cfg,
|
|
||||||
sessionKey: requestedSessionKey,
|
|
||||||
});
|
|
||||||
const agentId = resolveAgentIdFromSessionKey(canonicalSessionKey);
|
const agentId = resolveAgentIdFromSessionKey(canonicalSessionKey);
|
||||||
const mainSessionKey = resolveAgentMainSessionKey({ cfg, agentId });
|
const mainSessionKey = resolveAgentMainSessionKey({ cfg, agentId });
|
||||||
if (store) {
|
if (store) {
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import {
|
|||||||
loadSessionEntry,
|
loadSessionEntry,
|
||||||
readSessionMessages,
|
readSessionMessages,
|
||||||
resolveSessionModelRef,
|
resolveSessionModelRef,
|
||||||
resolveSessionStoreKey,
|
|
||||||
} from "../session-utils.js";
|
} from "../session-utils.js";
|
||||||
import { formatForLog } from "../ws-log.js";
|
import { formatForLog } from "../ws-log.js";
|
||||||
import type { GatewayRequestHandlers } from "./types.js";
|
import type { GatewayRequestHandlers } from "./types.js";
|
||||||
@@ -223,7 +222,9 @@ export const chatHandlers: GatewayRequestHandlers = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const { cfg, storePath, store, entry } = loadSessionEntry(p.sessionKey);
|
const { cfg, storePath, store, entry, canonicalKey } = loadSessionEntry(
|
||||||
|
p.sessionKey,
|
||||||
|
);
|
||||||
const timeoutMs = resolveAgentTimeoutMs({
|
const timeoutMs = resolveAgentTimeoutMs({
|
||||||
cfg,
|
cfg,
|
||||||
overrideMs: p.timeoutMs,
|
overrideMs: p.timeoutMs,
|
||||||
@@ -307,12 +308,8 @@ export const chatHandlers: GatewayRequestHandlers = {
|
|||||||
clientRunId,
|
clientRunId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const storeKey = resolveSessionStoreKey({
|
|
||||||
cfg,
|
|
||||||
sessionKey: p.sessionKey,
|
|
||||||
});
|
|
||||||
if (store) {
|
if (store) {
|
||||||
store[storeKey] = sessionEntry;
|
store[canonicalKey] = sessionEntry;
|
||||||
if (storePath) {
|
if (storePath) {
|
||||||
await saveSessionStore(storePath, store);
|
await saveSessionStore(storePath, store);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -464,4 +464,38 @@ describe("gateway server sessions", () => {
|
|||||||
"agent:work:main",
|
"agent:work:main",
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("resolves and patches main alias to default agent main key", async () => {
|
||||||
|
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-sessions-"));
|
||||||
|
const storePath = path.join(dir, "sessions.json");
|
||||||
|
testState.sessionStorePath = storePath;
|
||||||
|
testState.agentsConfig = { list: [{ id: "ops", default: true }] };
|
||||||
|
testState.sessionConfig = { mainKey: "work" };
|
||||||
|
|
||||||
|
await fs.writeFile(storePath, JSON.stringify({}, null, 2), "utf-8");
|
||||||
|
|
||||||
|
const { ws } = await startServerWithClient();
|
||||||
|
const resolved = await rpcReq<{ ok: true; key: string }>(
|
||||||
|
ws,
|
||||||
|
"sessions.resolve",
|
||||||
|
{ key: "main" },
|
||||||
|
);
|
||||||
|
expect(resolved.ok).toBe(true);
|
||||||
|
expect(resolved.payload?.key).toBe("agent:ops:work");
|
||||||
|
|
||||||
|
const patched = await rpcReq<{ ok: true; key: string }>(
|
||||||
|
ws,
|
||||||
|
"sessions.patch",
|
||||||
|
{ key: "main", thinkingLevel: "medium" },
|
||||||
|
);
|
||||||
|
expect(patched.ok).toBe(true);
|
||||||
|
expect(patched.payload?.key).toBe("agent:ops:work");
|
||||||
|
|
||||||
|
const stored = JSON.parse(await fs.readFile(storePath, "utf-8")) as Record<
|
||||||
|
string,
|
||||||
|
{ thinkingLevel?: string }
|
||||||
|
>;
|
||||||
|
expect(stored["agent:ops:work"]?.thinkingLevel).toBe("medium");
|
||||||
|
expect(stored.main).toBeUndefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user