perf(runtime): reduce slack prep and qmd cache-key overhead

This commit is contained in:
Peter Steinberger
2026-03-02 19:47:38 +00:00
parent 8e48f7e353
commit d979eeda9f
2 changed files with 21 additions and 25 deletions

View File

@@ -24,8 +24,9 @@ export async function getMemorySearchManager(params: {
const resolved = resolveMemoryBackendConfig(params);
if (resolved.backend === "qmd" && resolved.qmd) {
const statusOnly = params.purpose === "status";
const cacheKey = buildQmdCacheKey(params.agentId, resolved.qmd);
let cacheKey: string | undefined;
if (!statusOnly) {
cacheKey = buildQmdCacheKey(params.agentId, resolved.qmd);
const cached = QMD_MANAGER_CACHE.get(cacheKey);
if (cached) {
return { manager: cached };
@@ -51,9 +52,15 @@ export async function getMemorySearchManager(params: {
return await MemoryIndexManager.get(params);
},
},
() => QMD_MANAGER_CACHE.delete(cacheKey),
() => {
if (cacheKey) {
QMD_MANAGER_CACHE.delete(cacheKey);
}
},
);
QMD_MANAGER_CACHE.set(cacheKey, wrapper);
if (cacheKey) {
QMD_MANAGER_CACHE.set(cacheKey, wrapper);
}
return { manager: wrapper };
}
} catch (err) {
@@ -217,22 +224,7 @@ class FallbackMemoryManager implements MemorySearchManager {
}
function buildQmdCacheKey(agentId: string, config: ResolvedQmdConfig): string {
return `${agentId}:${stableSerialize(config)}`;
}
function stableSerialize(value: unknown): string {
return JSON.stringify(sortValue(value));
}
function sortValue(value: unknown): unknown {
if (Array.isArray(value)) {
return value.map((entry) => sortValue(entry));
}
if (value && typeof value === "object") {
const sortedEntries = Object.keys(value as Record<string, unknown>)
.toSorted((a, b) => a.localeCompare(b))
.map((key) => [key, sortValue((value as Record<string, unknown>)[key])]);
return Object.fromEntries(sortedEntries);
}
return value;
// ResolvedQmdConfig is assembled in a stable field order in resolveMemoryBackendConfig.
// Fast stringify avoids deep key-sorting overhead on this hot path.
return `${agentId}:${JSON.stringify(config)}`;
}

View File

@@ -66,13 +66,17 @@ export async function prepareSlackMessage(params: {
topic?: string;
purpose?: string;
} = {};
let channelType = message.channel_type;
if (!channelType || channelType !== "im") {
let resolvedChannelType = normalizeSlackChannelType(message.channel_type, message.channel);
// D-prefixed channels are always direct messages. Skip channel lookups in
// that common path to avoid an unnecessary API round-trip.
if (resolvedChannelType !== "im" && (!message.channel_type || message.channel_type !== "im")) {
channelInfo = await ctx.resolveChannelName(message.channel);
channelType = channelType ?? channelInfo.type;
resolvedChannelType = normalizeSlackChannelType(
message.channel_type ?? channelInfo.type,
message.channel,
);
}
const channelName = channelInfo?.name;
const resolvedChannelType = normalizeSlackChannelType(channelType, message.channel);
const isDirectMessage = resolvedChannelType === "im";
const isGroupDm = resolvedChannelType === "mpim";
const isRoom = resolvedChannelType === "channel" || resolvedChannelType === "group";